在.NET MAUI安卓应用中获取MP3文件列表遇权限拒绝问题求助
在.NET MAUI安卓端获取MP3文件列表的解决方案
你的问题核心是安卓10及以上版本的**Scoped Storage(分区存储)**限制导致无法直接访问公共存储目录,即使授予存储权限也不行。以下是具体的解决步骤:
1. 配置必要权限
在Platforms/Android/AndroidManifest.xml中添加对应权限,适配不同安卓版本:
<!-- 安卓12及以下版本的存储读取权限 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <!-- 安卓13+版本的音频读取权限 --> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
2. 动态请求权限
安卓6.0+要求动态申请危险权限,在MAUI中使用内置的Permissions API处理:
var permissionStatus = PermissionStatus.Denied; // 根据安卓版本选择对应的权限类型 if (OperatingSystem.IsAndroidVersionAtLeast(33)) { permissionStatus = await Permissions.CheckStatusAsync<Permissions.MediaAudio>(); if (permissionStatus != PermissionStatus.Granted) { permissionStatus = await Permissions.RequestAsync<Permissions.MediaAudio>(); } } else { permissionStatus = await Permissions.CheckStatusAsync<Permissions.StorageRead>(); if (permissionStatus != PermissionStatus.Granted) { permissionStatus = await Permissions.RequestAsync<Permissions.StorageRead>(); } } if (permissionStatus != PermissionStatus.Granted) { // 权限被拒绝,可提示用户开启权限后重试 return; }
3. 通过MediaStore查询MP3文件
由于Scoped Storage限制,不能直接通过Directory.GetFiles访问公共目录,需使用安卓的MediaStore API查询媒体文件:
using Android.Content; using Android.Database; using Android.Provider; // 获取安卓应用上下文与ContentResolver var context = Platform.CurrentActivity.ApplicationContext; var contentResolver = context.ContentResolver; // 定义要查询的媒体文件字段 string[] projection = { MediaStore.Audio.Media.InterfaceConsts.Data, // 文件路径 MediaStore.Audio.Media.InterfaceConsts.DisplayName, // 文件名 MediaStore.Audio.Media.InterfaceConsts.Title // 音频标题 }; // 筛选MP3格式的音频文件(MIME类型为audio/mpeg) string selection = $"{MediaStore.Audio.Media.InterfaceConsts.MimeType} = ?"; string[] selectionArgs = { "audio/mpeg" }; // 执行查询 ICursor cursor = contentResolver.Query( MediaStore.Audio.Media.ExternalContentUri, projection, selection, selectionArgs, null); List<string> mp3FilePaths = new List<string>(); if (cursor != null) { // 获取文件路径字段的索引 int filePathIndex = cursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Data); // 遍历游标提取数据 while (cursor.MoveToNext()) { string filePath = cursor.GetString(filePathIndex); mp3FilePaths.Add(filePath); } cursor.Close(); } // 使用获取到的文件列表 if (mp3FilePaths.Any()) { flabel.Text = mp3FilePaths[0]; }
关键说明
- 安卓10(API 29)及以上版本强制启用Scoped Storage,禁止直接访问公共存储目录(如
/storage/emulated/0/music),必须通过MediaStore或SAF(存储访问框架)访问媒体文件。 - 安卓13(API 33)将原有的
READ_EXTERNAL_STORAGE权限拆分为READ_MEDIA_AUDIO、READ_MEDIA_VIDEO等细分权限,需针对性处理。
内容的提问来源于stack exchange,提问作者Никита Черепанов
相关产品推荐
相关产品推荐

