详解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 运行时权限。

配合 MediaRecorderAudioRecord 的写文件逻辑:

写法 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 小时前
MySQL C语言连接 - 从入门到实战
android·c语言·mysql
Meteors.3 小时前
Android性能优化:01. 指标体系 + 分析工具链
android
jike_20264 小时前
安卓平台免费录音转文字工具深度测评:5 款 APP 功能对比与选型指南
android·智能电视
Code Man4 小时前
Windows 下使用 Appium
android·windows·appium
码农coding4 小时前
android 12 中的VSYNC接收
android
GitLqr5 小时前
Flutter 3.44 性能飞跃:深度解析 Android Platform View 的 HCPP 新特性
android·flutter·性能优化
码农coding5 小时前
android 12 SurfaceFlinger中的CompositionEngine
android
Mem0rin6 小时前
[MySQL] 聚合函数、分组查询、连接查询
android·mysql
码龙-DragonCoding6 小时前
一键批量提取音频、提取视频
android·音视频·提取