You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 00:03:22