Как получить requestCode из Activity Result API

Я новичок в программировании Android Kotlin. Я делаю приложение для создания, чтения и удаления файлов с помощью Storage Access Framework. Я сделал это, реализовав устаревшее намерение startActivityForResult для выполнения задач чтения, создания и удаления файлов. Я попытался реализовать это с помощью 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, 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) {
            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)
        }
    }
}

Кто-нибудь может показать мне, как это правильно делается?

1 ответ

Есть два пути с 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. Добавьте дополнительный элемент в намерение, возвращенное другим действием. Распакуйте его как код вашего запроса.
      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)
        }
    }
}
Другие вопросы по тегам