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

Xamarin Android API33权限请求对话框不弹出问题排查

Xamarin Android API33存储权限请求对话框不弹出问题排查与解决

问题背景

相同的权限请求代码在Android API31中能正常弹出存储权限授权对话框,但升级到API33后完全无弹窗,已在Manifest和MainActivity中配置READ_MEDIA_IMAGES、READ_MEDIA_VIDEO等权限,目前只能引导用户手动前往应用设置授权,需明确API33下弹窗不出现的原因。

相关代码:

PermissionStatus storageStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage);

if (storageStatus != PermissionStatus.Granted)
{
    Dictionary<Permission, PermissionStatus> results = null;
    if (Device.RuntimePlatform == Device.Android)
    {
        await _FileHelper.ShowSnackbar("AppName requires permission to access and save reports.");
        results = await CrossPermissions.Current.RequestPermissionsAsync(new[] { Permission.Storage });
    }
    else
        results = await CrossPermissions.Current.RequestPermissionsAsync(new[] { Permission.Storage });

    storageStatus = results[Permission.Storage];
}

核心原因

Android 13(API33)对存储权限体系做了根本性调整:

  • 旧的READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE权限被废弃,取而代之的是细分的媒体权限(READ_MEDIA_IMAGES、READ_MEDIA_VIDEO、READ_MEDIA_AUDIO)。
  • 代码中使用的Permission.Storage在API33下对应已废弃的旧权限,系统不会为这类权限弹出授权对话框——因为API33中访问媒体文件无需旧存储权限,而是需要对应的细分媒体权限;同时WRITE权限在API33中已被移除,应用写入媒体库或私有目录都无需额外授权。
  • 若CrossPermissions库版本较旧,可能未适配API33的新权限枚举,导致请求的权限不被系统识别,自然无法触发弹窗。

解决方案

  1. 升级CrossPermissions库到最新版本
    确保使用的CrossPermissions已适配Android 13的新权限体系,新版本会提供Permission.MediaImages、Permission.MediaVideo等枚举值。

  2. 替换权限请求目标
    根据实际业务需求,将原请求Permission.Storage的逻辑替换为对应的细分媒体权限,同时做好版本兼容:

PermissionStatus storageStatus = default;
var permissions = new List<Permission>();

if (Device.RuntimePlatform == Device.Android)
{
    // 区分Android版本处理权限请求
    if (DeviceInfo.Version.Major >= 13)
    {
        // API33及以上请求细分媒体权限
        permissions.Add(Permission.MediaImages);
        permissions.Add(Permission.MediaVideo);
        // 根据需求添加其他媒体权限,比如MediaAudio
    }
    else
    {
        // API31及以下继续使用旧的Storage权限
        permissions.Add(Permission.Storage);
    }

    // 检查权限状态
    var statuses = await CrossPermissions.Current.CheckPermissionStatusAsync(permissions);
    storageStatus = statuses.Any(s => s.Value != PermissionStatus.Granted) ? PermissionStatus.Denied : PermissionStatus.Granted;

    if (storageStatus != PermissionStatus.Granted)
    {
        await _FileHelper.ShowSnackbar("AppName requires permission to access and save reports.");
        var results = await CrossPermissions.Current.RequestPermissionsAsync(permissions.ToArray());
        // 检查所有请求的权限是否都已授权
        storageStatus = results.All(r => r.Value == PermissionStatus.Granted) ? PermissionStatus.Granted : PermissionStatus.Denied;
    }
}
else
{
    // 其他平台继续使用原逻辑
    storageStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage);
    if (storageStatus != PermissionStatus.Granted)
    {
        var results = await CrossPermissions.Current.RequestPermissionsAsync(new[] { Permission.Storage });
        storageStatus = results[Permission.Storage];
    }
}
  1. 确认Manifest权限配置
    确保Manifest中已正确声明所需的新权限,例如:
<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" /> -->

补充说明

  • API33中,应用写入媒体库可通过MediaStore API完成,无需任何WRITE权限;写入应用私有目录(如Context.GetExternalFilesDir)也无需权限。
  • 若用户之前已拒绝过权限请求,系统会直接返回拒绝状态,不会再弹出对话框,这种情况才需要引导用户去应用设置手动授权。

内容的提问来源于stack exchange,提问作者Yohanes AI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 19:13:13