Xamarin Forms使用PCL Storage读取文件遇权限拒绝问题
你遇到的这个问题其实挺常见的——明明在Manifest里加了权限、能检测到文件存在,但就是读不了,核心原因大多和Android版本迭代后的权限机制变化有关。我给你梳理几个关键的排查和解决方向:
1. 别忽略动态权限申请(Android 6.0+必做)
只在AndroidManifest.xml里声明权限已经不够了!从Android 6.0(API 23)开始,危险权限需要在运行时动态向用户申请,哪怕你已经在Manifest里加了READ_EXTERNAL_STORAGE。如果是Android 13及以上,还要额外申请READ_MEDIA_VIDEO权限(专门针对媒体文件的读取)。
给你一段Xamarin环境下的权限申请示例代码:
private async Task RequestNecessaryPermissions() { // 检查并申请存储读取权限 var storageStatus = await Permissions.CheckStatusAsync<Permissions.StorageRead>(); if (storageStatus != PermissionStatus.Granted) { storageStatus = await Permissions.RequestAsync<Permissions.StorageRead>(); } // Android 13+ 需要单独申请媒体视频读取权限 if (DeviceInfo.Version.Major >= 13) { var videoStatus = await Permissions.CheckStatusAsync<Permissions.MediaVideo>(); if (videoStatus != PermissionStatus.Granted) { videoStatus = await Permissions.RequestAsync<Permissions.MediaVideo>(); } } }
记得在调用PCL Storage读取文件前,先执行这个权限申请方法。
2. 适配Android 10+的分区存储机制
从Android 10(API 29)开始,Google引入了分区存储,默认情况下应用不能直接访问外部存储的公共目录(比如根目录下的File文件夹),哪怕你有读写权限。这里有几个应对方案:
方案A:临时兼容旧机制(适合targetSdkVersion <29)
在AndroidManifest.xml的application标签里添加以下属性,绕过分区存储限制:
<application ... android:requestLegacyExternalStorage="true">
方案B:使用应用私有外部存储(推荐)
把视频文件放到应用的私有外部存储目录下(比如/Android/data/你的应用包名/files/File/),这个目录不需要额外权限,PCL Storage可以通过以下代码访问:
// 获取应用私有外部存储的File文件夹 var privateFolder = await FileSystem.Current.ExternalStorage.GetFolderAsync("File"); var videoFile = await privateFolder.GetFileAsync("你的视频文件名.mp4"); // 读取字节数组 var fileBytes = await videoFile.ReadAllBytesAsync();
方案C:适配分区存储的MediaStore(适合公共目录文件)
如果视频必须放在公共目录,那就要通过MediaStore来查询和读取文件,而不是直接通过路径访问。这种方式符合Android 10+的规范,但代码会相对复杂一些。
3. 确认PCL Storage的路径是否正确
你提到把视频放到了名为File的文件夹,要确认这个文件夹的实际位置:
- 如果是外部存储根目录下的
File文件夹,在Android 10+下会触发分区存储限制,建议换成私有存储; - 如果是应用内部存储的
File文件夹,应该用FileSystem.Current.LocalStorage.GetFolderAsync("File")来获取。
4. 检查文件本身的权限
有时候从电脑复制到设备的文件,权限可能不是当前应用能访问的。你可以先打印出文件的绝对路径,然后通过adb shell命令查看文件权限:
ls -l /你打印的文件绝对路径
如果权限不对,可以尝试在代码里用原生的Java.IO.File类先尝试读取,排除PCL Storage本身的问题。
内容的提问来源于stack exchange,提问作者Tina Ahmed

