Xamarin.Android在Pixel设备创建外部存储文件夹失败求助
问题核心原因
Pixel设备运行原生Android系统,严格遵循谷歌从Android 10(API 29)开始推行的分区存储机制,而部分品牌厂商对该机制做了宽松适配,导致你的代码在非Pixel设备正常运行,Pixel设备触发权限报错。以下是针对性解决方案:
解决方案步骤
1. 优先使用应用专属外部存储目录(推荐)
如果不需要将文件共享给其他应用,直接使用应用专属外部存储目录,无需申请任何读写权限,所有Android版本(包括Pixel设备)都能正常工作:
// 替换原路径获取代码 var folderPath = Path.Combine(Android.App.Application.Context.GetExternalFilesDir(null).AbsolutePath, "CorpFiles");
该路径为/storage/emulated/0/Android/data/[你的应用包名]/files/CorpFiles,系统默认授予读写权限,无需额外配置。
2. 若必须访问根目录下的自定义文件夹
(1)适配Android 10(API 29)
在AndroidManifest.xml的<application>标签中添加属性,暂时绕过分区存储限制:
<application android:requestLegacyExternalStorage="true" ...>
注意:该属性仅对Android 10生效,Android 11+不再起作用。
(2)正确申请MANAGE_EXTERNAL_STORAGE权限
MANAGE_EXTERNAL_STORAGE是特殊权限,无法通过ActivityCompat.RequestPermissions直接请求,需引导用户手动到应用设置开启:
// 在MainActivity中检查并引导授权 if (!Android.OS.Environment.IsExternalStorageManager) { Intent intent = new Intent(); intent.SetAction(Android.Provider.Settings.ActionManageAppAllFilesAccessPermission); Uri uri = Android.Net.Uri.FromParts("package", PackageName, null); intent.SetData(uri); StartActivity(intent); }
同时确保清单中已声明该权限(你已添加,无需重复操作):
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
⚠️ 注意:使用该权限的应用需符合Google Play政策(如文件管理器类应用),否则上架时可能被拒绝。
3. 完善权限请求回调处理
确认权限是否真正被授予,在MainActivity中重写权限回调方法:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults) { Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults); base.OnRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 1) { bool allPermissionsGranted = grantResults.All(perm => perm == Android.Content.PM.Permission.Granted); if (!allPermissionsGranted) { // 提示用户必须授予权限才能使用相关功能 } } }
4. Android 13(API 33)额外适配
Android 13将原读写权限拆分为媒体文件权限,若需访问媒体文件,需在清单中添加对应权限:
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
并在代码中请求这些权限(替代原READ_EXTERNAL_STORAGE)。
内容的提问来源于stack exchange,提问作者Katya Appazova

