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
相关产品推荐
相关产品推荐

