如何从 Activity 结果 API 中获取请求代码

How to get requestCode from Activity Result API

我对 Android Kotlin 编程还很陌生。我正在制作一个应用程序来使用存储访问框架创建、读取和删除文件。我通过实现已弃用的 startActivityForResult 意图来执行文件读取、创建、删除任务来做到这一点。我尝试使用 Activity Result API 来实现它,但我陷入了无法找到它的请求代码中。 在新实现中,有 resultCode 但没有 requestCode。

我的实现如下。如何使用 Activity 结果 API ?

实现以下内容

如何从 Activity 结果 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)
        }
    }
}

由于不推荐使用上述方法,我尝试使用 Intent launcher 来实现它,但是在任何地方都没有对 requestCode 的引用,所以我被困在这里。如下图:

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)
        }
    }
}

任何人都可以告诉我如何正确完成吗?

ActivityResultContracts.StartActivityForResult有两种方式。

  1. 通过注册多个侦听器发出多个请求:
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. 在您从另一个 activity 返回的 Intent 中添加额外内容。将其解压为您的请求代码。
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)
        }
    }
}