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

Android11移除MANAGE_ALL_FILES权限后MediaProvider读文件报错求助

解决方案

报错根因

收到权限报错的核心原因是:通过SAF(存储访问框架)拿到的DocumentFile Uri本身自带授予的访问权限,但调用MediaStore.getMediaUri()将其转换为MediaStore专属Uri后,系统并未给应用授予对应MediaStore文件的访问权限,因此触发了权限拒绝。
另外当前的SAF请求逻辑缺少持久化权限的配置,重启应用后之前拿到的目录访问权限会失效。

修复步骤

  • 调整SAF发起请求时的Flag,增加持久化权限授权标记
  • 拿到目录Uri后主动申请持久化权限,避免权限丢失
  • 直接使用SAF返回的DocumentFile Uri操作文件,无需转换为MediaStore Uri,SAF本身的Uri完全支持读取内容、加载到ImageView、传递给其他组件等操作
  • 额外添加数组越界判断,避免目录下文件不足10个时崩溃

修复后代码

fun opendd(){
    val i = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
        // 同时添加读权限和持久化权限标记
        flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or 
                Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
    }
    startActivityIfNeeded(i, 33)
}

// onActivityResult 逻辑
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    when (requestCode) {
        33 -> {
            if (resultCode == RESULT_OK) {
                data?.data?.also { uri ->
                    // 申请持久化权限,确保重启应用后仍能访问该目录
                    contentResolver.takePersistableUriPermission(
                        uri,
                        Intent.FLAG_GRANT_READ_URI_PERMISSION
                    )
                    
                    val dfile = DocumentFile.fromTreeUri(applicationContext, uri)
                    val fileList = dfile?.listFiles() ?: emptyArray()
                    Log.d("usr", fileList.contentToString())
                    
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && fileList.size >= 10) {
                        // 直接使用SAF返回的Uri,无需转换为MediaStore Uri
                        val i = Intent(this, AnimatedImageView::class.java)
                        i.data = fileList[9].uri
                        startActivity(i)
                    }
                }
            }
        }
    }
}

额外说明

如果需要遍历的目录下文件数量较多,DocumentFile.listFiles()性能较差,可直接通过ContentResolver查询DocumentsContract的相关列获取文件列表,效率会提升数倍。
你无需申请MANAGE_ALL_FILES权限,也不需要申请READ_EXTERNAL_STORAGE/READ_MEDIA_*等权限,仅靠SAF授予的目录权限即可完成所有文件操作,完全符合Google Play政策要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 10:09:02