从 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+:
- 直接文件 API 受限 :原有的标准 File API(如
new File("/sdcard/Download/test.mp3"))不再被允许随意读写公共存储的非特定目录。 - 普通存储权限失效 :
WRITE_EXTERNAL_STORAGE在 API 30+ 上已被废弃或限制,对系统级文件的自由访问需要更高维度的授权。 - 极高的系统权限 :
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。