.NET Maui Android应用获取MANAGE_EXTERNAL_STORAGE权限方案问询
问题描述
我正在使用.NET Maui开发一款Android应用,该应用从Documents目录(/storage/emulated/0/Documents)读取XML文件。应用可自行生成XML文件以确保其存在,但替换该文件时会触发访问拒绝异常。我认为这是因为使用了Storage_Read和Storage_Write权限而非MANAGE_EXTERNAL_STORAGE权限。由于.NET Maui权限系统尚未适配API 34,现寻求获取该权限的替代方案。
当前权限请求代码
PermissionStatus lReadStatus = await Permissions.RequestAsync<Permissions.StorageRead>(); PermissionStatus lWriteStatus =await Permissions.RequestAsync<Permissions.StorageWrite>();
Android Manifest.xml配置
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
解决方案
由于.NET Maui内置权限系统暂未封装MANAGE_EXTERNAL_STORAGE权限,你可以直接通过Android原生API实现权限请求,以下是具体步骤:
1. 跳转系统设置请求权限
MANAGE_EXTERNAL_STORAGE权限无法通过常规弹窗请求,必须引导用户到系统设置页面手动授权。你可以在Android平台项目中实现以下逻辑:
方式一:使用ActivityResultContracts(推荐)
在MainActivity.cs中注册权限请求启动器,并提供调用入口:
using Android.App; using Android.Content; using Android.OS; using Android.Provider; namespace YourAppName.Droid; [Activity(/* 你的Activity原有配置 */)] public class MainActivity : MauiAppCompatActivity { private ActivityResultLauncher<Intent> _manageStorageLauncher; protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // 注册权限请求结果回调 _manageStorageLauncher = RegisterForActivityResult( new ActivityResultContracts.StartActivityForResult(), result => { if (Build.VERSION.SdkInt >= BuildVersionCodes.R) { bool hasPermission = Android.OS.Environment.IsExternalStorageManager; // 这里处理权限授权后的逻辑,比如重新执行文件替换操作 } }); } // 供共享项目调用的方法 public void RequestManageExternalStorage() { if (Build.VERSION.SdkInt >= BuildVersionCodes.R && !Android.OS.Environment.IsExternalStorageManager) { Intent intent = new Intent(Settings.ActionManageAppAllFilesAccessPermission); intent.SetData(Android.Net.Uri.Parse($"package:{PackageName}")); _manageStorageLauncher.Launch(intent); } } }
在共享项目中调用该方法:
#if ANDROID if (Platform.CurrentActivity is YourAppName.Droid.MainActivity mainActivity) { mainActivity.RequestManageExternalStorage(); } #endif
方式二:传统OnActivityResult(兼容旧写法)
如果需要兼容更旧的Android写法,可在MainActivity.cs中重写OnActivityResult:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); if (requestCode == 1001 && Build.VERSION.SdkInt >= BuildVersionCodes.R) { bool hasPermission = Android.OS.Environment.IsExternalStorageManager; // 处理授权结果 } } // 供共享项目调用的方法 public void RequestManageExternalStorage() { if (Build.VERSION.SdkInt >= BuildVersionCodes.R && !Android.OS.Environment.IsExternalStorageManager) { Intent intent = new Intent(Settings.ActionManageAppAllFilesAccessPermission); intent.SetData(Android.Net.Uri.Parse($"package:{PackageName}")); StartActivityForResult(intent, 1001); } }
2. 权限状态检查
在执行文件操作前,先检查是否已获得权限:
#if ANDROID bool hasManagePermission = false; if (Build.VERSION.SdkInt >= BuildVersionCodes.R) { hasManagePermission = Android.OS.Environment.IsExternalStorageManager; } // 低于Android 11的版本,检查传统读写权限即可 else { hasManagePermission = ContextCompat.CheckSelfPermission(Platform.CurrentActivity, Android.Manifest.Permission.WriteExternalStorage) == Android.Content.PM.Permission.Granted; } if (!hasManagePermission) { // 触发权限请求 } #endif
3. 关键注意事项
MANAGE_EXTERNAL_STORAGE权限仅适用于Android 11(API 30)及以上版本,低版本仍使用传统的读写权限即可- 提交Google Play审核时,必须明确说明应用需要该权限的核心场景(如文件管理器类应用),否则可能被拒绝审核
- 优先考虑使用Android的Scoped Storage替代全局存储访问,仅在Scoped Storage无法满足需求时才使用
MANAGE_EXTERNAL_STORAGE权限
内容的提问来源于stack exchange,提问作者Redalertiscool
相关产品推荐
相关产品推荐

