如何在MAUI应用中读写Android外部存储文件并获取文件列表
在MAUI中实现Android外部存储的文件读写与列表获取
一、权限配置
首先需要在Android项目中配置必要的存储权限,同时处理动态权限申请(Android 6.0+要求):
修改AndroidManifest.xml
在Platforms/Android/AndroidManifest.xml中添加权限声明:<!-- Android 12及以下读写权限 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <!-- Android 13+ 媒体文件权限 --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> <!-- 如需访问所有外部存储(需Google Play审核) --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="33" />动态申请权限
MAUI提供了Permissions类简化权限申请,封装权限检查方法:private static async Task<bool> HasStoragePermissionsAsync() { if (DeviceInfo.Platform != DevicePlatform.Android) return true; var sdkVersion = (int)Android.OS.Build.VERSION.SdkInt; PermissionStatus readStatus, writeStatus; if (sdkVersion >= 33) { // Android 13+ 申请媒体读写权限 readStatus = await Permissions.CheckStatusAsync<Permissions.MediaRead>(); writeStatus = await Permissions.CheckStatusAsync<Permissions.MediaWrite>(); if (readStatus != PermissionStatus.Granted) readStatus = await Permissions.RequestAsync<Permissions.MediaRead>(); if (writeStatus != PermissionStatus.Granted) writeStatus = await Permissions.RequestAsync<Permissions.MediaWrite>(); } else { // Android 6-12 申请存储读写权限 readStatus = await Permissions.CheckStatusAsync<Permissions.StorageRead>(); writeStatus = await Permissions.CheckStatusAsync<Permissions.StorageWrite>(); if (readStatus != PermissionStatus.Granted) readStatus = await Permissions.RequestAsync<Permissions.StorageRead>(); if (writeStatus != PermissionStatus.Granted) writeStatus = await Permissions.RequestAsync<Permissions.StorageWrite>(); } return readStatus == PermissionStatus.Granted && writeStatus == PermissionStatus.Granted; }
二、获取外部存储路径
根据需求选择对应的外部存储目录:
公共存储目录(如Downloads、Documents)
适用于访问系统公共文件夹的场景:// 获取公共Downloads目录路径 var publicDownloadsPath = Android.OS.Environment .GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads) .AbsolutePath; // 获取公共Documents目录路径 var publicDocumentsPath = Android.OS.Environment .GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDocuments) .AbsolutePath;应用专属外部存储目录
该目录属于应用私有,卸载应用时会被清空,无需额外权限:var appExternalPath = Android.App.Application.Context .GetExternalFilesDir(null) .AbsolutePath;
三、封装抽象API实现类似Directory.GetFiles
封装跨平台兼容的方法,在Android平台完成权限校验和文件列表获取:
public static class FileHelper { public static async Task<string[]> GetFilesInFolderAsync(string folderPath) { if (!await HasStoragePermissionsAsync()) throw new UnauthorizedAccessException("未获得存储访问权限"); if (!Directory.Exists(folderPath)) throw new DirectoryNotFoundException("指定文件夹不存在"); return Directory.GetFiles(folderPath); } // 权限检查方法 private static async Task<bool> HasStoragePermissionsAsync() { if (DeviceInfo.Platform != DevicePlatform.Android) return true; var sdkVersion = (int)Android.OS.Build.VERSION.SdkInt; PermissionStatus readStatus, writeStatus; if (sdkVersion >= 33) { readStatus = await Permissions.CheckStatusAsync<Permissions.MediaRead>(); writeStatus = await Permissions.CheckStatusAsync<Permissions.MediaWrite>(); if (readStatus != PermissionStatus.Granted) readStatus = await Permissions.RequestAsync<Permissions.MediaRead>(); if (writeStatus != PermissionStatus.Granted) writeStatus = await Permissions.RequestAsync<Permissions.MediaWrite>(); } else { readStatus = await Permissions.CheckStatusAsync<Permissions.StorageRead>(); writeStatus = await Permissions.CheckStatusAsync<Permissions.StorageWrite>(); if (readStatus != PermissionStatus.Granted) readStatus = await Permissions.RequestAsync<Permissions.StorageRead>(); if (writeStatus != PermissionStatus.Granted) writeStatus = await Permissions.RequestAsync<Permissions.StorageWrite>(); } return readStatus == PermissionStatus.Granted && writeStatus == PermissionStatus.Granted; } }
四、使用示例
try { // 替换为你需要访问的文件夹路径 string targetFolder = ""; if (DeviceInfo.Platform == DevicePlatform.Android) { targetFolder = Android.OS.Environment .GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads) .AbsolutePath; } var files = await FileHelper.GetFilesInFolderAsync(targetFolder); // 遍历文件列表做后续处理 foreach (var file in files) { Console.WriteLine($"找到文件:{file}"); } } catch (Exception ex) { Console.WriteLine($"出错:{ex.Message}"); }
五、关键注意事项
- Scoped Storage限制:Android 10+引入了Scoped Storage,直接使用
Directory类访问非应用专属的公共目录可能受限。若需访问更多目录,推荐使用MediaStore或Storage Access Framework(SAF);若必须用文件路径方式,需申请MANAGE_EXTERNAL_STORAGE权限,但该权限需通过Google Play特殊审核。 - 应用专属存储优先:如果不需要共享文件给其他应用,优先使用应用专属外部存储,无需额外权限且不受Scoped Storage限制。
- 跨平台兼容:若需支持多平台,建议定义抽象接口,在不同平台实现对应的文件操作逻辑,避免代码耦合。
内容的提问来源于stack exchange,提问作者Divya Prakash Jha
相关产品推荐
相关产品推荐

