Android 11设备无法读取已下载音频及音乐文件仅能获取闹钟铃声
问题根因
Android 11 对分区存储(Scoped Storage)权限规则做了强制收紧:
- 以 Android 11(API 30)及以上版本为目标平台的应用,无法再依靠
requestLegacyExternalStorage标记获取全量外置存储访问权限 - 若未正确申请对应音频读取权限、或媒体查询逻辑限定了闹钟铃声范围,就只会返回系统闹钟类铃声,无法识别用户下载的音乐、其他音频文件
- Android 10 及更低版本无上述强制限制,原有存储权限逻辑可正常读取全量音频
修复方案
- 调整清单文件权限声明,按系统版本适配对应权限:
<!-- Android 12及以下版本使用的外置存储读权限,在API33及以上自动失效 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <!-- Android 13及以上版本读取全量音频文件的专属权限 --> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
- 临时兼容方案(不推荐长期使用):若应用
targetSdkVersion低于30,可在Manifest的<application>标签下添加android:requestLegacyExternalStorage="true",可在Android11设备上临时沿用旧存储逻辑读取全量文件,但该配置在targetSdkVersion升级到30及以上时会被系统强制忽略,无法作为长期适配方案。 - 修正动态权限申请逻辑:
- 系统版本 < API 30:申请
READ_EXTERNAL_STORAGE即可 - 系统版本在API 30~32区间:申请
READ_EXTERNAL_STORAGE即可 - 系统版本 >= API33:仅需申请
READ_MEDIA_AUDIO
- 系统版本 < API 30:申请
- 修正媒体库查询逻辑:
- 查询全量音频必须使用
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI作为查询URI,禁止误用MediaStore.Audio.Alarms.EXTERNAL_CONTENT_URI这类仅对应闹钟铃声的URI - 去掉查询selection语句中
IS_ALARM = 1、IS_NOTIFICATION = 1、IS_RINGTONE = 1这类仅过滤铃声类文件的条件,确保能返回普通音乐、下载音频、录音等全类型音频条目 - 禁止直接通过硬编码的文件路径访问非本应用创建的音频文件,必须通过MediaStore返回的
content://类型URI读取文件流
- 查询全量音频必须使用
验证要点
- 权限申请弹窗弹出时,需确认用户授予了音频文件访问权限
- 查询返回的Cursor条目数与系统自带文件管理器中显示的音频文件数量匹配,可正常读取下载目录、Music目录下的非铃声类音频
内容的提问来源于stack exchange,提问作者Sheraz Ghani
相关产品推荐
相关产品推荐

