You need to enable JavaScript to run this app. Android Kotlin如何从Activity Result API获取requestCode实现SAF文件操作
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin如何从Activity Result API获取requestCode实现SAF文件操作

核心实现思路

Activity Result API 设计上取消了手动维护requestCode的逻辑,你只需要为每个业务场景单独注册对应的ActivityResultLauncher,每个启动器的回调仅处理自身场景的逻辑,完全避免了requestCode的判断逻辑。

完整实现代码

步骤1:声明对应场景的启动器

你可以选择通用的StartActivityForResult协议,也可以使用系统预置的SAF专属协议简化代码,以下为两种实现方式:

方式1:使用通用StartActivityForResult协议

// 读文件启动器
private val readFileLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        val uri = result.data?.data ?: return@registerForActivityResult
        val readContent = openFileContent(uri)
        etContent.setText(readContent)
    }
}

// 创建文件(写)启动器
private val createFileLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        val uri = result.data?.data ?: return@registerForActivityResult
        val writeResult = writeText(uri)
        etContent.setText(writeResult)
    }
}

// 选择待删除文件启动器
private val selectDeleteFileLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        val uri = result.data?.data ?: return@registerForActivityResult
        deleteFile(uri)
    }
}

方式2:使用系统预置SAF专属协议(更简洁)

// 读文件启动器,直接返回选中的Uri
private val readFileLauncher = registerForActivityResult(ActivityResultContracts.OpenDocument()) { uri ->
    uri ?: return@registerForActivityResult
    val readContent = openFileContent(uri)
    etContent.setText(readContent)
}

// 创建文件启动器,直接返回创建的Uri
private val createFileLauncher = registerForActivityResult(ActivityResultContracts.CreateDocument("text/*")) { uri ->
    uri ?: return@registerForActivityResult
    val writeResult = writeText(uri)
    etContent.setText(writeResult)
}

// 选择待删除文件启动器
private val selectDeleteFileLauncher = registerForActivityResult(ActivityResultContracts.OpenDocument()) { uri ->
    uri ?: return@registerForActivityResult
    deleteFile(uri)
}

步骤2:修改触发逻辑

对应不同的启动器类型,修改触发方法:

对应方式1的触发逻辑

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)
    }
    createFileLauncher.launch(intent)
}

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

fun triggerDeleteFile() {
    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
        addCategory(Intent.CATEGORY_OPENABLE)
        type = "text/*"
    }
    selectDeleteFileLauncher.launch(intent)
}

对应方式2的触发逻辑

fun createFile() {
    val filename: String = etFileName.text.toString()
    createFileLauncher.launch(filename)
}

fun readFile(){
    etFileName.setText("")
    readFileLauncher.launch(arrayOf("text/*"))
}

fun triggerDeleteFile() {
    selectDeleteFileLauncher.launch(arrayOf("text/*"))
}

步骤3:保留原有业务工具方法

原有代码中的deleteFile、writeText、openFileContent、queryName方法无需任何修改,直接复用即可,同时可以删除原来废弃的onActivityResult方法。


内容的提问来源于stack exchange,提问作者sujan_014

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 07:54:01