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

targetSDK30适配Android11用SAF申请WhatsApp媒体权限后加载文件被拒

问题解决方案

根因说明

Android 11 起分区存储规则强制执行,你通过 Storage Access Framework 拿到的授权仅针对SAF返回的content://类型URI生效。你当前使用的本地File对象、Uri.fromFile()生成的file://格式URI不属于SAF授权范围,系统会直接拒绝访问,因此抛出EACCES权限错误。

加载图片修复步骤

  • 废弃所有构造本地File对象、生成file://URI加载图片的逻辑
  • 直接使用SAF查询文件时获取到的content://URI加载资源:
    // Glide加载直接传入content URI
    Glide.with(context)
      .load(contentUri)
      .into(imageView)
    
    // 直接调用setImageURI同样适用
    imageView.setImageURI(contentUri)
    
  • 如果你通过DocumentFile操作文件,直接调用DocumentFile#getUri()即可获取有效授权的content URI

后续写入、复制逻辑实现方案

文件写入

如果是修改SAF授权目录下的已有文件,直接通过ContentResolver打开输出流写入即可:

contentResolver.openOutputStream(targetContentUri, "w")?.use { outputStream ->
    // 写入对应数据即可
}

如果需要新建文件,通过DocumentFile#createFile()创建文件后拿到生成的content URI,再按上述逻辑写入即可。

文件复制

源文件和目标文件均在SAF授权范围内的话,分别打开对应输入流、输出流对接即可,无需申请额外文件路径权限:

contentResolver.openInputStream(sourceContentUri)?.use { inputStream ->
    contentResolver.openOutputStream(targetContentUri)?.use { outputStream ->
        inputStream.copyTo(outputStream)
    }
}

权限持久化校验

确认你在用户完成目录授权后已经调用权限持久化方法,避免应用重启后权限失效:

// 用户授权完成的回调中执行
val uri = resultData.data ?: return
val authFlags = resultData.flags and (Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
contentResolver.takePersistableUriPermission(uri, authFlags)

额外说明

  • targetSDKVersion >= 30时requestLegacyExternalStorage配置已失效,无需再调整该配置
  • 不要尝试使用私有API绕过分区存储直接访问/sdcard/Android/media路径的本地File对象,不符合Google Play应用上架规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 20:54:04