C# Maui如何无需用户干预获取安卓设备公共文件列表
C# MAUI 安卓无干预遍历文档解决方案
核心问题分析
- Android 10+ 默认启用分区存储(Scoped Storage),直接用
Directory类访问/sdcard等硬编码路径会被系统限制,即便声明普通存储权限也无效。 MANAGE_EXTERNAL_STORAGE是特殊高危权限,仅在Manifest中声明不足以获取权限,必须引导用户到系统设置手动开启。- 硬编码存储路径(如/sdcard、/internal storage)不可靠,不同设备的实际存储路径可能存在差异。
步骤1:完善权限配置
在platforms/android/AndroidManifest.xml中添加以下配置:
<!-- 声明外部存储管理权限 --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> <!-- 兼容Android 10及以下的分区存储绕过(可选,用于旧版本兼容) --> <application android:requestLegacyExternalStorage="true" ...>
步骤2:动态申请特殊权限
MANAGE_EXTERNAL_STORAGE无法通过常规弹窗请求获取,必须跳转至系统设置页面让用户手动开启:
using Android.Content; using Android.OS; using Microsoft.Maui.ApplicationModel; public async Task<bool> RequestManageStoragePermission() { if (OperatingSystem.IsAndroidVersionAtLeast(11)) { if (!Android.OS.Environment.IsExternalStorageManager) { var intent = new Intent(Android.Provider.Settings.ActionManageAppAllFilesAccessPermission); intent.AddCategory(Intent.CategoryDefault); intent.SetData(Android.Net.Uri.Parse($"package:{Android.App.Application.Context.PackageName}")); Platform.CurrentActivity.StartActivity(intent); // 等待用户操作后重新校验权限 await Task.Delay(2000); // 实际可通过监听ActivityResult优化此逻辑 return Android.OS.Environment.IsExternalStorageManager; } return true; } // Android 10及以下,申请WRITE_EXTERNAL_STORAGE权限 var status = await Permissions.CheckStatusAsync<Permissions.StorageWrite>(); if (status != PermissionStatus.Granted) { status = await Permissions.RequestAsync<Permissions.StorageWrite>(); } return status == PermissionStatus.Granted; }
步骤3:获取正确存储路径并遍历
不要硬编码路径,通过Android系统API获取外部存储根目录:
using System.IO; public async Task TraverseDocuments() { var hasPermission = await RequestManageStoragePermission(); if (!hasPermission) { // 权限未获取,执行对应处理逻辑 return; } // 获取外部存储根目录 string externalStoragePath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath; // 目标文档目录,例如系统默认Documents文件夹 string documentsPath = Path.Combine(externalStoragePath, "Documents"); if (Directory.Exists(documentsPath)) { // 遍历当前目录文件 foreach (var file in Directory.GetFiles(documentsPath)) { // 处理文件,如记录路径、读取内容等 Console.WriteLine(file); } // 遍历子目录 foreach (var dir in Directory.GetDirectories(documentsPath)) { Console.WriteLine(dir); // 递归遍历子目录(可选) TraverseSubDir(dir); } } } // 递归遍历子目录的辅助方法(可选) private void TraverseSubDir(string dirPath) { try { foreach (var file in Directory.GetFiles(dirPath)) { Console.WriteLine(file); } foreach (var subDir in Directory.GetDirectories(dirPath)) { Console.WriteLine(subDir); TraverseSubDir(subDir); } } catch (UnauthorizedAccessException ex) { // 跳过无权限访问的系统保护目录 Console.WriteLine($"无权限访问目录: {dirPath}, 错误信息: {ex.Message}"); } }
关键注意事项
- Google Play政策限制:
MANAGE_EXTERNAL_STORAGE权限仅允许文件管理器、备份工具等特定类型应用使用,普通应用提交至Google Play可能被拒,企业内部应用或测试用途可忽略此限制。 - 异常处理:遍历过程中会遇到系统保护目录(如/data),必须捕获
UnauthorizedAccessException避免应用崩溃。 - 权限状态校验:每次执行遍历前务必重新校验权限状态,用户可能在系统设置中关闭权限。
内容的提问来源于stack exchange,提问作者lewis bass
相关产品推荐
相关产品推荐

