如何从 Activity Result API 获取 requestCode

问题描述

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

我的实现如下。我如何使用 Activity Result API 实现以下内容

如何从 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)!!
    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 启动器来实现它,但在任何地方都没有对 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) {
            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. 在从其他活动返回的 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 -> run {
            Log.d("Uri Read","$uri")
            val readfile: String = openFileContent(uri)
            etContent.setText(readfile)
        }
        WRITE_REQUEST_CODE -> run {
            Log.i("Uri Write","Uri: $uri")   // 1
            val write = writeText(uri)   // 2
            etContent.setText(write)
        }
        DELETE_REQUEST_CODE -> run {
            Log.d("Uri Delete","$uri")
            deleteFile(uri)
        }
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...