ActivityResultContracts.CreateDocument的onResult回调未触发问题求助
问题解决办法
1. 修复ActivityResultContracts.CreateDocument构造问题
你无法使用带MIME参数的构造,本质是activity-ktx/activity-compose依赖版本过低。在targetSdk32环境下,需升级相关依赖到支持带参数构造的版本(如1.4.0及以上),修改Module的build.gradle:
dependencies { implementation 'androidx.activity:activity-ktx:1.4.0' implementation 'androidx.activity:activity-compose:1.4.0' // 1.2.0-beta02版本的Compose可兼容上述activity依赖 }
升级后即可使用CreateDocument("text/plain")明确指定文本类型,避免系统识别异常。
2. 排查回调不执行的核心问题
若暂时无法升级依赖,先检查以下几点:
- 确保Launcher稳定初始化:将
rememberLauncherForActivityResult放在Composable顶层作用域,避免重组导致Launcher被重复创建:
@Composable fun WriteScreen(viewModel: WriteViewModel = viewModel()) { val TAG = "WriteScreen" // 放在顶层,仅初始化一次 val saveFile = rememberLauncherForActivityResult(ActivityResultContracts.CreateDocument()) { uri -> Log.d(TAG, "WriteScreen: Enter callback onResult of saveFile launcher") uri?.let { viewModel.saveFileAs(it) } } Button(onClick = { saveFile.launch("my_note.txt") }) { Text("保存文件") } }
- 检查启动参数:启动Launcher时必须传入非空文件名(如
"my_note.txt"),部分系统版本会因空文件名导致流程异常、回调不触发。 - 添加异常捕获与流自动管理:原代码未处理写入异常,且手动关闭流易出错,修改
saveFileAs方法:
fun saveFileAs(uri: Uri) { Log.d(TAG, "saveFileAs: enter method saveFileAs") viewModelScope.launch(Dispatchers.IO) { try { Application.context.contentResolver.openOutputStream(uri)?.use { outputStream -> outputStream.writer().use { writer -> writer.write(_uiState.value.content) Log.d(TAG, "saveFileAs: saved content: ${_uiState.value.content}") } } ?: Log.e(TAG, "saveFileAs: Failed to open output stream") } catch (e: Exception) { Log.e(TAG, "saveFileAs: Error writing file", e) } } }
用use函数自动管理流的关闭,同时捕获所有异常并打印日志,便于定位问题。
3. 验证系统权限
targetSdk32下使用CreateDocument无需申请WRITE_EXTERNAL_STORAGE权限,但需确保App在系统设置中的存储权限为“允许”状态。
内容的提问来源于stack exchange,提问作者Eynnzerr
相关产品推荐
相关产品推荐

