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

Android 11不使用SAF访问/sdcard/Download下文件的问题求助

问题根因

Android 11(API 30)及以上版本的分区存储规则对普通存储权限做了限制:你申请的READ_EXTERNAL_STORAGE仅能授权访问公共目录下的三类媒体文件(图片、音频、视频),json、js等非媒体文件,以及其他应用生成的非媒体文件,即便放在Download等公共目录下,普通存储权限也没有读取权限,这就是你只能枚举到文件夹、看不到普通文件的原因。

符合谷歌规范的解决方案

你需要申请官方提供的所有文件访问权限(MANAGE_EXTERNAL_STORAGE),该权限是API 30以上专门面向需要全量文件访问能力的应用推出的合规方案,不需要用到legacy storage:

实现步骤

  1. 在AndroidManifest.xml中添加权限声明:
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
  1. 动态触发权限申请:
    首先判断当前是否已经拿到权限,未拿到的情况下跳转到系统授权页引导用户开启:
// 自定义请求码常量
val REQUEST_MANAGE_STORAGE = 1001

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    if (!Environment.isExternalStorageManager()) {
        // 跳转到对应应用的所有文件访问权限设置页
        val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
        intent.data = Uri.parse("package:${packageName}")
        startActivityForResult(intent, REQUEST_MANAGE_STORAGE)
    } else {
        // 已拿到权限,直接执行你的拷贝逻辑即可
        executeFileCopy()
    }
} else {
    // API 30以下版本,申请READ_EXTERNAL_STORAGE权限后即可正常使用File API
    requestReadStoragePermission()
}
  1. 用户完成授权回到应用后,你原先的File读写、枚举逻辑不需要做任何修改,即可正常读取Download等公共目录下的所有文件和文件夹。

注意事项

  • 该权限的申请需要符合Google Play的上架政策:只有应用的核心功能必须依赖全量文件访问(如文件管理器、数据备份工具等)才能申请,不符合场景的申请会被Google Play驳回上架。如果你的应用核心功能不需要全量文件访问,建议优先调整逻辑使用MediaStore或者SAF方案实现。
  • 如果你只需要访问本应用自身写入到公共目录的非媒体文件,可以通过MediaStore.Downloads集合查询对应文件,不需要申请该权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:18:03