You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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+环境下自动权限请求可能失效,需手动前置权限检查:

  1. 调用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();
        }
    }
    
  2. 若无需公共目录存储,可直接保存到应用私有目录(无需权限):
    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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 11:01:29