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

为何X-plore可列出安卓全目录,而System.IO.Directory.GetDirectories却遭权限拒绝?

解决Xamarin Android访问/storage/emulated/0/Android权限被拒的问题

核心原因

从Android 10(API 29)开始引入的**分区存储(Scoped Storage)**限制了应用对外部存储的访问,/storage/emulated/0/Android属于系统保护目录,常规的READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE权限无法直接访问。X-plore这类文件管理器能正常访问,是因为它们完成了MANAGE_EXTERNAL_STORAGE特殊权限的申请与系统级授权流程。

具体解决方案

1. 完善Manifest配置

确保AndroidManifest.xml的权限声明和版本适配正确:

<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" />

<!-- Android 10及以下兼容分区存储限制 -->
<application ... android:requestLegacyExternalStorage="true">
  • WRITE_EXTERNAL_STORAGE在API 29+已废弃,添加maxSdkVersion="28"避免冗余声明。
  • requestLegacyExternalStorage="true"可让应用在Android 10上暂时绕过分区存储限制。

2. 运行时权限申请

(1)常规读写权限(API < 30)

针对Android 11以下设备,需在运行时主动申请READ_EXTERNAL_STORAGE:

if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.ReadExternalStorage) != Permission.Granted)
{
    ActivityCompat.RequestPermissions(this, new string[] { Manifest.Permission.ReadExternalStorage }, 100);
}

(2)MANAGE_EXTERNAL_STORAGE特殊权限(API >= 30)

Android 11及以上版本中,MANAGE_EXTERNAL_STORAGE属于特殊权限,无法通过常规弹窗申请,必须引导用户到系统设置手动开启:

if (Build.VERSION.SdkInt >= BuildVersionCodes.R)
{
    if (!Environment.IsExternalStorageManager)
    {
        Intent intent = new Intent(Settings.ActionManageAppAllFilesAccessPermission);
        intent.Data = Android.Net.Uri.Parse($"package:{PackageName}");
        StartActivityForResult(intent, 200);
    }
}

需在OnActivityResult或OnRequestPermissionsResult中校验权限是否成功授予,再执行文件遍历逻辑。

3. 代码优化建议

在递归遍历逻辑中增加权限校验,避免无权限时触发异常:

private void RecursivelyListFilesAndDirectories(string directoryPath, List<string> fileList)
{
    try
    {
        // 先校验当前路径是否可读
        Java.IO.File targetDir = new Java.IO.File(directoryPath);
        if (!targetDir.CanRead())
        {
            return;
        }

        string[] files = System.IO.Directory.GetFiles(directoryPath);
        string[] directories = System.IO.Directory.GetDirectories(directoryPath);

        fileList.AddRange(files);

        foreach (string subDir in directories)
        {
            fileList.Add(subDir);
            RecursivelyListFilesAndDirectories(subDir, fileList);
        }
    }
    catch (UnauthorizedAccessException ex)
    {
        Console.WriteLine($"无权限访问路径: {directoryPath} | 错误信息: {ex.Message}");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"遍历出错: {ex.Message}");
    }
}

4. 注意事项

  • Google Play对MANAGE_EXTERNAL_STORAGE权限审核严格,仅文件管理器类应用易通过审核,普通应用优先使用分区存储API(如MediaStore、SAF)访问文件。
  • 测试时优先使用真实设备,部分模拟器的权限逻辑与真机存在差异。

内容的提问来源于stack exchange,提问作者jca

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 04:25:24