.NET MAUI Android权限请求弹窗不显示问题求助
.NET MAUI Android权限弹窗不显示,提示"permissions not granted"的解决方案
一、Android版本适配问题(核心原因)
Android 13(API Level 33)及以上版本彻底废弃了READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE权限,改用细分的媒体权限,若你的目标SDK是33+,现有Manifest里的权限声明已无效:
- 针对Android 12及以下,保留原有存储权限并添加版本限制:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> - 针对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" /> - 若需写入公共下载目录等非媒体目录,Android 13+需申请
MANAGE_EXTERNAL_STORAGE权限(此权限需用户手动在系统设置开启,无法弹窗请求):<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
二、修复权限请求逻辑漏洞
你的CheckForStoragePermission方法未判断权限请求结果,直接返回初始值false,导致授权后仍返回未授权状态。修正后的代码:
public static async Task<bool> CheckForStoragePermission() { var status = await Permissions.CheckStatusAsync<Permissions.StorageWrite>(); if (status == PermissionStatus.Granted) return true; // 若之前被拒绝,提示用户权限必要性 if (status == PermissionStatus.Denied && DeviceInfo.Platform == DevicePlatform.Android) { if (Permissions.ShouldShowRationale<Permissions.StorageWrite>()) { await Toast.Make("需要存储权限来保存文件").Show(); } } status = await Permissions.RequestAsync<Permissions.StorageWrite>(); return status == PermissionStatus.Granted; }
三、FileSaver组件使用注意事项
CommunityToolkit的FileSaver在Android 13+环境下自动权限请求可能失效,需手动前置权限检查:
- 调用SaveAsync前先确认权限:
async Task SaveDocument(MemoryStream memoryStream) { try { bool hasPermission = await CheckForStoragePermission(); if (!hasPermission) { await Toast.Make("存储权限未授予,无法保存文件").Show(); return; } var someLocation = await FileSaver.SaveAsync($"{Guid.NewGuid()}.docx", memoryStream, new CancellationToken()); await Toast.Make($"File is saved: {someLocation}").Show(); } catch (Exception ex) { await Toast.Make($"File is not saved, {ex.Message}").Show(); } } - 若无需公共目录存储,可直接保存到应用私有目录(无需权限):
var privatePath = Path.Combine(FileSystem.AppDataDirectory, $"{Guid.NewGuid()}.docx"); using var fileStream = File.Create(privatePath); memoryStream.Seek(0, SeekOrigin.Begin); await memoryStream.CopyToAsync(fileStream);
四、额外检查项
- 确认项目目标SDK版本:在
Platforms/Android/Android.csproj中查看TargetFramework,确保权限声明与SDK级别匹配。 - 针对Android 10/11(SDK 29-32),需在application标签添加兼容属性:
<application android:allowBackup="true" ... android:requestLegacyExternalStorage="true">
内容的提问来源于stack exchange,提问作者Tanaka Mawere
相关产品推荐
相关产品推荐

