Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get requestCode from Activity Result API

I am very new to Android Kotlin programming. I am making an app to create, read and delete file using Storage Access Framework. I did it by implementing deprecated startActivityForResult intent to perform file read, create, delete tasks. I tried to implement it using Activity Result API but I got stuck in request code which I could not find it. In new implementation, there is resultCode but no requestCode.

My implemetation is below. How I can I implement the following using Activity Result API ?

How can I get request code from Activity Result API ?

fun createFile()
{
    val filename: String = etFileName.text.toString()
    val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
        type = "text/*"
        addCategory(Intent.CATEGORY_OPENABLE)
        putExtra(Intent.EXTRA_TITLE, filename)
    }
    startActivityForResult(intent, WRITE_REQUEST_CODE)
}


fun readFile(){
    etFileName.setText("")
    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
        addCategory(Intent.CATEGORY_OPENABLE)
        type = "text/*"
    }
    startActivityForResult(intent, READ_REQUEST_CODE)
}

fun deleteFile(uri: Uri){
    val filename = queryName(contentResolver, uri)
    DocumentsContract.deleteDocument(contentResolver, uri)
    Toast.makeText(applicationContext, "Done deleting $filename", Toast.LENGTH_SHORT).show()
}

fun writeText(uri: Uri) : String{
    //var writetext: String = "typing high speed"
    var writeStream = contentResolver.openFileDescriptor(uri, "w")
    val filename: String = queryName(contentResolver, uri)
    etFileName.setText(filename)
    var fileOutputStream = FileOutputStream(writeStream?.fileDescriptor)
    fileOutputStream.write(filename.toByteArray())
    fileOutputStream.close()
    return filename.toString()
}

fun openFileContent(uri: Uri): String{
    val inputStream = contentResolver.openInputStream(uri)
    val reader = BufferedReader(InputStreamReader(inputStream))
    val stringBuilder = StringBuilder()

    val filename = queryName(contentResolver, uri)
    etFileName.setText(filename)
    var currentline = reader.readLine()

    while (currentline != null) {
        stringBuilder.append(currentline + "\n")
        currentline = reader.readLine()
    }
    inputStream?.close()
    val str =  stringBuilder.toString()
    Log.d("Uri Read", ": $str")
    return str
}

private fun queryName(resolver: ContentResolver, uri: Uri): String {
    val returnCursor: Cursor = resolver.query(uri, null, null, null, null)!!
    val nameIndex: Int = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
    returnCursor.moveToFirst()
    val name: String = returnCursor.getString(nameIndex)
    returnCursor.close()
    return name
}

override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
    super.onActivityResult(requestCode, resultCode, resultData)

    if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
        val uri =resultData?.data
        Log.d("Uri Read", "$uri")
        if (uri != null) {
            val readfile: String = openFileContent(uri)
            etContent.setText(readfile)
        }
    } else if (requestCode == WRITE_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
        resultData?.data?.also { uri ->
            Log.i("Uri Write", "Uri: $uri")   // 1
            val write = writeText(uri)   // 2
            etContent.setText(write)
        }
    } else if (requestCode == DELETE_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
        val uri =resultData?.data
        Log.d("Uri Delete", "$uri")
        if (uri != null) {
            deleteFile(uri)
        }
    }
}

Since the above method is deprecated, I tried to implement it using Intent launcher, but there is no reference to requestCode anywhere so I am stuck here. It is as shown below :

val startforFile: ActivityResultLauncher<Intent> = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
    result: ActivityResult ->

    // could not find reference to requestCode here

    if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
        val uri =resultData?.data
        Log.d("Uri Read", "$uri")
        if (uri != null) {
            val readfile: String = openFileContent(uri)
            etContent.setText(readfile)
        }
    } else if (requestCode == WRITE_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
        resultData?.data?.also { uri ->
            Log.i("Uri Write", "Uri: $uri")   // 1
            val write = writeText(uri)   // 2
            etContent.setText(write)
        }
    } else if (requestCode == DELETE_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
        val uri =resultData?.data
        Log.d("Uri Delete", "$uri")
        if (uri != null) {
            deleteFile(uri)
        }
    }
}

Can anyone show me how it is done correctly ?

like image 559
sujan_014 Avatar asked Jun 08 '21 12:06

sujan_014


1 Answers

There are two ways with ActivityResultContracts.StartActivityForResult.

  1. Make multiple requests by registering multiple listeners:
val startForFileRead: ActivityResultLauncher<Intent> = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
    result: ActivityResult ->
    if (resultCode == Activity.RESULT_OK) {
        val uri =resultData?.data
        Log.d("Uri Read", "$uri")
        if (uri != null) {
            val readfile: String = openFileContent(uri)
            etContent.setText(readfile)
        }
    } 
}

val startForFileWrite: ActivityResultLauncher<Intent> = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
    result: ActivityResult ->
    if (resultCode == Activity.RESULT_OK) {
        resultData?.data?.also { uri ->
            Log.i("Uri Write", "Uri: $uri")   // 1
            val write = writeText(uri)   // 2
            etContent.setText(write)
        }
    } 
}

val startForFileDelete: ActivityResultLauncher<Intent> = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
    result: ActivityResult ->
    if (resultCode == Activity.RESULT_OK) {
        val uri =resultData?.data
        Log.d("Uri Delete", "$uri")
        if (uri != null) {
            deleteFile(uri)
        }
    } 
}
  1. Put an extra in your Intent returned from the other activity. Unpack it as your request code.
const val REQUEST_CODE = "REQUEST_CODE"
//...

val startForFile: ActivityResultLauncher<Intent> =
    registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    val requestCode = result.data?.extras?.getInt(REQUEST_CODE)
    if (requestCode == null) {
        Log.e("FileResultLauncher", "No REQUEST_CODE was returned in data intent.")
        return@registerForActivityResult
    }
    val uri = result.data?.data
    if (uri == null || result.resultCode != RESULT_OK) {
        Log.i("FileResultLauncher", "No Uri returned or result wasn't OK.")
        return@registerForActivityResult
    }
    when (requestCode) {
        READ_REQUEST_CODE -> {
            Log.d("Uri Read", "$uri")
            val readfile: String = openFileContent(uri)
            etContent.setText(readfile)
        }
        WRITE_REQUEST_CODE -> {
            Log.i("Uri Write", "Uri: $uri")   // 1
            val write = writeText(uri)   // 2
            etContent.setText(write)
        }
        DELETE_REQUEST_CODE -> {
            Log.d("Uri Delete", "$uri")
            deleteFile(uri)
        }
    }
}
like image 144
Tenfour04 Avatar answered Nov 30 '22 17:11

Tenfour04