Xamarin无法检测到Android设备上已存在的文件问题咨询
我来帮你排查这个问题——明明Manifest里加了READ_EXTERNAL_STORAGE权限,文件也确实存在,但Xamarin就是找不到它,大概率是权限或路径处理的细节没做好,毕竟Android 7.0在文件访问上有不少需要注意的点:
一、先确认:你是不是没做动态权限申请?
Android 6.0(API 23)及以上版本,仅仅在Manifest里声明权限是不够的,必须在运行时动态申请READ_EXTERNAL_STORAGE权限。Android 7.0正好在这个范围内,如果没做动态申请,你的App实际上没有读取外部存储的权限,自然看不到文件。
给你一段可以直接用的代码示例:
// 定义权限请求标识 const int RequestStoragePermission = 100; string[] requiredPermissions = { Android.Manifest.Permission.ReadExternalStorage }; // 检查权限是否已授予 if (ContextCompat.CheckSelfPermission(this, Android.Manifest.Permission.ReadExternalStorage) != Permission.Granted) { // 申请权限 ActivityCompat.RequestPermissions(this, requiredPermissions, RequestStoragePermission); } else { // 权限已存在,直接执行文件检查逻辑 VerifyFileExists(); } // 处理权限申请结果 public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults) { base.OnRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == RequestStoragePermission) { if (grantResults.Length > 0 && grantResults[0] == Permission.Granted) { // 权限申请成功,重新检查文件 VerifyFileExists(); } else { // 权限被拒绝,提示用户需要开启权限才能访问文件 } } }
二、别再硬编码路径了,用官方API构建更可靠
你直接写/storage/emulated/0/Incoming/item_list.csv这种硬编码路径,虽然大多数设备能用,但不是官方推荐的方式——不同厂商的设备可能会有路径差异。换成Android提供的API来构建路径,兼容性更好:
// 获取外部存储根目录的绝对路径 string externalRoot = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath; // 组合成目标文件路径 string targetFilePath = Path.Combine(externalRoot, "Incoming", "item_list.csv");
用这个方式生成的路径,能避免因设备差异导致的路径错误。
三、检查文件名称的大小写和存在性检测逻辑
Android的文件系统是区分大小写的,确认你代码里的item_list.csv和实际文件的名称完全一致(包括大小写,比如不要把Item_List.csv写成item_list.csv)。
另外,确保你的文件存在性检测逻辑是正确的,比如用File.Exists():
void VerifyFileExists() { string externalRoot = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath; string targetFilePath = Path.Combine(externalRoot, "Incoming", "item_list.csv"); bool isFileExist = File.Exists(targetFilePath); // 这里可以加日志或者调试输出,确认isFileExist的值 }
四、额外排查:StrictMode的Uri限制(可能性较低)
Android 7.0引入了StrictMode对file://Uri的限制,但这主要影响的是分享文件的场景,单纯检测本地文件存在一般不会受影响。如果前面的方法都没解决问题,可以考虑是否有其他代码使用了file://Uri导致的间接影响,但这个概率不高。
按上面的步骤排查下来,基本就能解决文件检测不到的问题啦。
内容的提问来源于stack exchange,提问作者Mr Rob

