详解Android所有文件访问权限

从 Android 11 (API 30) 开始,Google 推行了严格的 分区存储(Scoped Storage) 策略。这段代码引入 ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION 是为了向用户申请 "所有文件访问权限"(MANAGE_EXTERNAL_STORAGE) 。

一、 为什么要申请这个权限?

在 Android 10 及更早版本,只要用户授予了 WRITE_EXTERNAL_STORAGE 权限,App 就可以在 SD 卡/公有目录的任意位置创建、修改和删除文件。

但到了 Android 11+:

  1. 直接文件 API 受限 :原有的标准 File API(如 new File("/sdcard/Download/test.mp3"))不再被允许随意读写公共存储的非特定目录。
  2. 普通存储权限失效 :WRITE_EXTERNAL_STORAGE 在 API 30+ 上已被废弃或限制,对系统级文件的自由访问需要更高维度的授权。
  3. 极高的系统权限 :ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION 是最高级别的存储权限,允许应用忽略 Scoped Storage 限制,像旧版本 Android 那样对设备存储进行全面读写。

二、 应用场景与功能是什么?

典型应用场景

Google 对该权限的审查非常严格,通常只允许以下核心功能是"管理文件"的应用申请:

  • 文件管理器(如 ES 文件浏览器、Total Commander)
  • 备份/恢复类应用(如系统数据备份工具)
  • 防病毒/安全软件(需要全盘扫描文件)
  • 文档/代码编辑器(需要直接修改外部任意位置的项目文件)

这段代码在你的 App 中的功能

代码的含义是:在录音/录屏(startRecord())前,先检查是否有全盘文件访问权限。若没有,则跳转到系统设置页让用户开启"允许管理所有文件"开关。

潜在风险 :如果你的应用只是普通的"录音/录像/文件下载"工具,将应用上架到 Google Play Store 时申请此权限,99% 会被系统审核拒绝甚至下架,因为 Google 不认为录音属于该权限的合法合规场景。

三、 不申请有无替代方案?

有,且强烈建议替换!

如果你的应用只是为了保存录音/音视频文件,完全不需要申请这种全局危险权限。以下提供 2 种标准的官方推荐替代方案:

方案 1:存入应用专属目录(最简单、无需任何权限)

如果录音文件只需要在你的应用内部播放,或者由你的 App 自行管理,直接存入应用的专属目录即可。不需要在 Manifest 中申请任何读写存储权限!

Java

ini 复制代码
// 获取应用专属的 Audio/Music 目录:Android/data/<package_name>/files/Music/
File storageDir = getExternalFilesDir(Environment.DIRECTORY_MUSIC);
File audioFile = new File(storageDir, "recording_" + System.currentTimeMillis() + ".mp3");

// 直接传入 MediaRecorder 使用
mediaRecorder.setOutputFile(audioFile.getAbsolutePath());
startRecord();

方案 2:保存到系统公共媒体库(MediaStore API)

如果你希望录音保存到系统公共文件夹 (如 Music/ 或 Recordings/),以便用户能在系统的"音乐"或"文件"App 中看到,应当使用 MediaStore API。

  • Android 10+ (API 29+) :写入自己创建的媒体文件完全不需要任何存储权限!
  • Android 9 及以下 :仅需传统的 WRITE_EXTERNAL_STORAGE 运行时权限。

配合 MediaRecorder 或 AudioRecord 的写文件逻辑:

写法 A(Android 10 及以上:使用 FileDescriptor):

Java

java 复制代码
public void prepareRecorderForQAndAbove(MediaRecorder recorder) throws IOException {
    ContentValues values = new ContentValues();
    values.put(MediaStore.Audio.Media.DISPLAY_NAME, "record_" + System.currentTimeMillis() + ".mp3");
    values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/mp3");
    // 指定保存路径在公共 Music 文件夹中的子目录
    values.put(MediaStore.Audio.Media.RELATIVE_PATH, Environment.DIRECTORY_MUSIC + "/MyRecordings");

    ContentResolver resolver = getContentResolver();
    Uri audioUri = resolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values);

    if (audioUri != null) {
        // 通过 ParcelFileDescriptor 将文件句柄传给 MediaRecorder
        ParcelFileDescriptor pfd = resolver.openFileDescriptor(audioUri, "w");
        if (pfd != null) {
            recorder.setOutputFile(pfd.getFileDescriptor());
        }
    }
}

适配全版本的完整流程逻辑:

Java

scss 复制代码
private void checkPermissionAndRecord() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        // Android 10+ 写入 MediaStore 公共目录不需要申请 WRITE_EXTERNAL_STORAGE 权限
        startRecordWithMediaStore();
    } else {
        // Android 9 及以下需要申请传统的写入权限
        if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            startRecordLegacy();
        } else {
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1001);
        }
    }
}

💡 总结与建议

方案 存储路径 权限需求 Play Store 上架
全文件权限 (ACTION_MANAGE) 任意路径 MANAGE_EXTERNAL_STORAGE 极难通过审查
应用专属目录 (getExternalFilesDir) Android/data/包名/files 零权限 100% 允许
媒体库 (MediaStore) Music/, Movies/ 等公共区 Android 10+ 零权限 Android 9- 需 WRITE_EXTERNAL_STORAGE 100% 推荐规范

最佳实践 :请将原代码中的 ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION 逻辑移除,根据你的需求选择切换到 应用专属目录 或 MediaStore API。

相关推荐
千里马学框架2 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台2 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone2 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc2 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo3 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077003 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone3 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen3 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone3 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui