Android Xamarin:目录文件无法添加至Spinner列表问题求助
问题:Spinner无法加载指定目录的文件列表
尝试将指定目录下的文件添加到Spinner中,但Spinner始终为空。目标文件夹确实存在且包含3个文件,代码中“目录已找到”的Toast能正常触发,但循环内的“找到文件”提示从未弹出。
原代码
public class MainActivity : Activity { Button btnGetFiles; Spinner spinnerGetFiles; List<string> fileList; protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.Main); spinnerGetFiles = FindViewById<Spinner>(Resource.Id.spinnerGetFiles); btnGetFiles = FindViewById<Button>(Resource.Id.btnGetFiles); btnGetFiles.Click += delegate { fileList = GetFilesFromDirectory("/storage/emulated/0/MyFolder"); ArrayAdapter<string> adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleSpinnerItem, fileList); spinnerGetFiles.Adapter = adapter; }; } List<string> GetFilesFromDirectory(string strDirectoryPath) { List<string> files = new List<string>(); if (Directory.Exists(strDirectoryPath)) { Toast.MakeText(Application.Context, "Directory found", ToastLength.Long).Show(); string[] fileList2 = Directory.GetFiles(strDirectoryPath); foreach (string file in fileList2) { files.Add(Path.GetFileName(file)); Toast.MakeText(Application.Context, "File found : " + file, ToastLength.Long).Show(); } } else { Toast.MakeText(Application.Context, "No directory was found!!", ToastLength.Long).Show(); } return files; } }
问题排查与解决
1. 存储权限缺失(核心原因)
Android 6.0(API 23)及以上版本,读取外部存储需要动态申请权限,仅在Manifest中声明权限无效:
- 先在
AndroidManifest.xml中添加权限声明:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- Android 10+ 需全存储访问可添加: --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
- 在代码中补充权限申请逻辑,修改
OnCreate方法:
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.Main); spinnerGetFiles = FindViewById<Spinner>(Resource.Id.spinnerGetFiles); btnGetFiles = FindViewById<Button>(Resource.Id.btnGetFiles); // 启动时检查存储权限 if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.ReadExternalStorage) != Permission.Granted) { ActivityCompat.RequestPermissions(this, new string[] { Manifest.Permission.ReadExternalStorage }, 100); } btnGetFiles.Click += delegate { // 确认权限授予后再读取文件 if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.ReadExternalStorage) == Permission.Granted) { string folderPath = Path.Combine(Environment.ExternalStorageDirectory.AbsolutePath, "MyFolder"); fileList = GetFilesFromDirectory(folderPath); ArrayAdapter<string> adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleSpinnerItem, fileList); spinnerGetFiles.Adapter = adapter; } else { Toast.MakeText(this, "请授予存储权限", ToastLength.Long).Show(); } }; } // 处理权限申请结果 public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults) { base.OnRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 100) { if (grantResults.Length > 0 && grantResults[0] == Permission.Granted) { Toast.MakeText(this, "权限已授予", ToastLength.Long).Show(); } else { Toast.MakeText(this, "权限被拒绝,无法读取文件", ToastLength.Long).Show(); } } }
2. 避免硬编码路径
不要直接写/storage/emulated/0/MyFolder,改用系统API获取路径,适配不同设备:
string folderPath = Path.Combine(Environment.ExternalStorageDirectory.AbsolutePath, "MyFolder");
3. Android 10+ 适配
若目标版本为Android 10(API 29)及以上,默认启用Scoped Storage,直接读取外部目录可能受限:
- 可在
AndroidManifest.xml的<application>标签中添加过渡配置:android:requestLegacyExternalStorage="true"; - 长期方案建议使用MediaStore API查询文件,适配Scoped Storage规范。
4. 调试文件获取逻辑
可在GetFilesFromDirectory中添加日志,确认文件数组长度:
string[] fileList2 = Directory.GetFiles(strDirectoryPath); Log.Debug("FileDebug", $"找到{fileList2.Length}个文件");
内容的提问来源于stack exchange,提问作者Anthony Magerera
相关产品推荐
相关产品推荐

