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

Xamarin Android中Directory.GetFiles返回Null问题排查求助

问题分析与解决方案

嘿,我来帮你捋清楚这个问题!首先先指出你代码里一个明显的逻辑bug——你把文件夹存在性的判断写反了:

var folder = "/storage/emulated/0/Pictures/Viber"; 
// 这里的!Directory.Exists(folder)是"如果文件夹不存在"的意思,你却输出"folder exist"
if (!Directory.Exists(folder)) Console.WriteLine("folder exist"); 
else Console.WriteLine("doesnt exist"); 

修正后应该是:

var folder = "/storage/emulated/0/Pictures/Viber"; 
if (Directory.Exists(folder)) 
    Console.WriteLine("folder exists"); 
else 
    Console.WriteLine("folder doesn't exist"); 

接下来说说你遇到的核心问题:明明文件夹存在,但Directory.GetFiles返回空(正常情况下这个方法要么返回数组,要么抛异常,大概率是返回空数组),主要原因有两个:

1. 存储权限未正确获取

从Android 6.0(API 23)开始,读取外部存储属于危险权限,必须在运行时动态申请,只在AndroidManifest.xml里声明是不够的:

  • 对于Android 12及以下,你需要在AndroidManifest.xml中添加:
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    
    然后在代码中用Xamarin.Essentials请求权限:
    var status = await Permissions.RequestAsync<Permissions.StorageRead>();
    if (status != PermissionStatus.Granted)
    {
        Console.WriteLine("存储权限未授予,无法访问文件夹");
        return;
    }
    
  • 对于Android 13及以上,权限名称变了,需要替换为:
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
    
    对应的权限请求是:
    var status = await Permissions.RequestAsync<Permissions.MediaImages>();
    

2. Android 10+的Scoped Storage限制

从Android 10(API 29)开始,系统默认启用Scoped Storage,限制了App直接通过绝对路径访问外部存储的大部分目录,包括第三方App创建的子目录(比如这里的Viber图片目录)。此时Directory类的文件系统操作会被系统拦截,导致无法读取到文件。

这种情况下,推荐使用Android系统提供的MediaStore来查询媒体文件,而不是直接操作文件路径。比如这段代码可以获取Viber文件夹下的所有图片:

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

public List<string> GetViberImageFiles(Context context)
{
    var viberImages = new List<string>();
    
    // 定义要查询的字段(这里只需要文件路径)
    string[] projection = { MediaStore.Images.Media.Data };
    // 筛选路径包含"/Pictures/Viber/"的文件
    string selection = $"{MediaStore.Images.Media.Data} LIKE ?";
    string[] selectionArgs = new string[] { "%/Pictures/Viber/%" };

    using (ICursor cursor = context.ContentResolver.Query(
        MediaStore.Images.Media.ExternalContentUri,
        projection,
        selection,
        selectionArgs,
        null))
    {
        if (cursor != null)
        {
            int pathColumnIndex = cursor.GetColumnIndex(MediaStore.Images.Media.Data);
            while (cursor.MoveToNext())
            {
                string filePath = cursor.GetString(pathColumnIndex);
                viberImages.Add(filePath);
            }
            cursor.Close();
        }
    }

    return viberImages;
}

总结

你现在的问题本质是:

  • 代码逻辑错误导致你对文件夹存在性的判断出现误解
  • 未正确申请存储权限,导致无法访问目标目录
  • Android 10+的存储政策限制了直接路径访问,需要用MediaStore替代

按照上面的步骤修正后,应该就能正常获取到Viber文件夹里的文件了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 15:02:43