You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 11使用ResultLauncher复制文件及获取带读权限Uri的问题咨询

问题根因

  • 你对系统返回的授权Uri做了Uri.parse(it.toString().replace("%3A", ":"))篡改操作,Android系统授予的临时读取权限仅和原始返回的Uri绑定,修改后的Uri不持有任何访问权限,直接触发权限拒绝错误。
  • 你当前使用的FileProvider配置和当前问题无关,该配置仅用于你的应用向其他应用分享自身目录下的文件,读取系统返回的外部文件Uri不需要该配置。

修复方案

方案1:直接修复现有逻辑

删除对Uri的修改操作,直接使用registerForActivityResult返回的原始Uri即可,修改后代码如下:

singleTypeResultLauncher =
            fragment.registerForActivityResult(ActivityResultContracts.GetContent()){
                    result ->
                result?.let{ originalUri ->
                    // 移除Uri替换逻辑,直接使用原始返回的Uri
                    val path = createCopyAndReturnRealPath(fragment.requireContext(), originalUri)
                }
            }

启动逻辑保持不变即可,createCopyAndReturnRealPath方法本身逻辑无问题,传入正确的授权Uri后不会出现权限报错。

方案2:高版本系统更稳定适配(推荐Android 11+使用)

将ActivityResultContracts.GetContent替换为专门用于访问公共文档的ActivityResultContracts.OpenDocument,可以获得更稳定的权限,还支持持久化权限让应用重启后仍可访问选中的文件,代码如下:

singleTypeResultLauncher =
            fragment.registerForActivityResult(ActivityResultContracts.OpenDocument()){
                    result ->
                result?.let{ originalUri ->
                    // 可选:持久化Uri读取权限,应用重启后仍可访问该文件
                    fragment.requireContext().contentResolver.takePersistableUriPermission(
                        originalUri,
                        Intent.FLAG_GRANT_READ_URI_PERMISSION
                    )
                    val path = createCopyAndReturnRealPath(fragment.requireContext(), originalUri)
                }
            }

// 启动方式调整为传入MIME类型数组
singleTypeResultLauncher.launch(arrayOf("application/pdf"))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 20:48:04