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

Android MAUI应用中Directory.GetFiles无法读取USB复制的外部存储文件

解决VS MAUI Android应用无法读取外置存储卡Download文件夹全部文件的问题

核心原因

问题源于Android 10及以上版本的**Scoped Storage(分区存储)**机制限制,以及MANAGE_EXTERNAL_STORAGE这类特殊权限需手动授权(仅在Manifest声明无效);同时硬编码外置存储路径也会导致兼容性问题。

具体解决步骤

1. 精简AndroidManifest权限

清理重复、无效权限,保留必要项:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<!-- 保留业务必需的其他权限,如CAMERA、INTERNET等 -->
  • WRITE_EXTERNAL_STORAGE添加maxSdkVersion="28"是因为Android 10+不再依赖该权限访问公共目录,由分区存储或MANAGE_EXTERNAL_STORAGE替代。

2. 引导用户授予MANAGE_EXTERNAL_STORAGE权限

该权限为特殊权限,无法通过常规弹窗申请,需跳转至应用设置手动开启:

using Android.Content;
using Android.OS;
using AndroidX.Core.App;

// 在文件读取逻辑前调用
public void RequestFullStorageAccess()
{
    if (Build.VERSION.SdkInt >= BuildVersionCodes.R)
    {
        if (!Environment.IsExternalStorageManager)
        {
            Intent intent = new Intent(Settings.ActionManageAppAllFilesAccessPermission);
            intent.SetData(Android.Net.Uri.Parse($"package:{Android.App.Application.Context.PackageName}"));
            StartActivityForResult(intent, 1001);
        }
    }
}

// 处理权限申请结果
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
    base.OnActivityResult(requestCode, resultCode, data);
    if (requestCode == 1001)
    {
        if (Build.VERSION.SdkInt >= BuildVersionCodes.R && Environment.IsExternalStorageManager)
        {
            // 权限已授予,重新执行文件读取逻辑
            LoadDownloadFiles();
        }
    }
}

3. 用系统API获取Download目录,避免硬编码路径

硬编码路径会导致设备兼容性问题,改用系统API获取正确路径:

// Android平台获取外置公共Download目录
string downloadPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath;

// 读取文件
var files = Directory.GetFiles(downloadPath);

4. 适配Scoped Storage(无需特殊权限,可选)

若不想申请MANAGE_EXTERNAL_STORAGE(需Google Play审核),可通过MediaStore查询Download目录文件:

using Android.Content;
using Android.Database;
using Android.Provider;

public List<string> GetAllDownloadFiles()
{
    List<string> filePaths = new();
    string[] projection = { MediaStore.Files.FileColumns.Data };
    string selection = $"{MediaStore.Files.FileColumns.MediaType} = {MediaStore.Files.FileColumns.MediaTypeFile}";
    string sortOrder = $"{MediaStore.Files.FileColumns.DateAdded} DESC";

    using ICursor cursor = ContentResolver.Query(MediaStore.Files.GetContentUri("external"), projection, selection, null, sortOrder);
    if (cursor != null)
    {
        int dataIndex = cursor.GetColumnIndex(MediaStore.Files.FileColumns.Data);
        while (cursor.MoveToNext())
        {
            string path = cursor.GetString(dataIndex);
            if (path.Contains(Android.OS.Environment.DirectoryDownloads))
                filePaths.Add(path);
        }
        cursor.Close();
    }
    return filePaths;
}

这种方式符合分区存储规范,无需特殊权限,易通过应用商店审核。

验证流程

  1. 重新编译安装应用,首次运行引导用户开启「所有文件访问权限」(Android 11+)。
  2. 使用系统API路径读取文件,替换硬编码路径。
  3. 测试USB复制的文件是否能被正常列出。

内容的提问来源于stack exchange,提问作者Mats Claesgård

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 20:55:28