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

Android 13权限适配异常求助:已授权仍提示手动修改权限

问题分析与修复方案

核心问题点

  1. 权限请求结果判断逻辑错误:当前代码仅判断grantResults.length == 1,如果同时请求多个权限,该条件不满足会直接进入拒绝分支触发提示,即便部分权限已授予。
  2. Android 13权限处理不完整:
    • 仅针对Android 13处理shouldShowRequestPermissionRationale,但该API是区分用户「暂时拒绝」和「永久拒绝(不再询问)」的核心判断逻辑,需覆盖所有版本场景。
    • 未针对每个权限单独判断拒绝状态,直接取第一个权限处理导致误判。
  3. Manifest冗余/无效权限:
    • 重复添加READ_PRIVILEGED_PHONE_STATE,该权限仅系统应用可申请,普通应用无需配置。
    • WRITE_INTERNAL_STORAGE、READ_INTERNAL_STORAGE为系统级权限,普通应用无法获取,应移除。
    • Android 13及以上,READ_EXTERNAL_STORAGE已被媒体权限替代,需添加maxSdkVersion限制仅在低版本生效。

修复后的代码实现

权限请求逻辑(支持多权限校验)

// 按需整理需要申请的权限数组
String[] requiredPermissions = {
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.READ_MEDIA_IMAGES,
    Manifest.permission.READ_CALENDAR
};

// 检查所有权限是否已授予
boolean allPermissionsGranted = true;
for (String perm : requiredPermissions) {
    if (ActivityCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) {
        allPermissionsGranted = false;
        break;
    }
}

if (!allPermissionsGranted) {
    ActivityCompat.requestPermissions(this, requiredPermissions, Datafields.REQUEST_CODE_PERMISSION);
} else {
    Intent intent = new Intent(this, FileLeave.class);
    startActivity(intent);
}

权限请求结果回调(修正多权限与拒绝判断)

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (requestCode == Datafields.REQUEST_CODE_PERMISSION) {
        boolean allGranted = true;
        boolean hasPermanentDenial = false;

        // 遍历所有权限逐一校验授予状态
        for (int i = 0; i < grantResults.length; i++) {
            if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                allGranted = false;
                // 判断该权限是否被永久拒绝(用户勾选「不再询问」)
                if (!shouldShowRequestPermissionRationale(permissions[i])) {
                    hasPermanentDenial = true;
                    break;
                }
            }
        }

        if (allGranted) {
            // 所有权限通过,跳转目标页面
            Intent intent = new Intent(this, FileLeave.class);
            startActivity(intent);
        } else {
            if (hasPermanentDenial) {
                Toast.makeText(this, "请从手机设置手动修改权限", Toast.LENGTH_SHORT).show();
            } else {
                // 用户暂时拒绝,可提示权限必要性引导再次申请
                Toast.makeText(this, "需要相关权限才能正常使用功能", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

修复后的Manifest权限配置

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CAMERA" />

<uses-feature android:name="android.hardware.wifi" />

<!-- 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"/>

<!-- 位置权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<!-- 日历权限 -->
<uses-permission android:name="android.permission.READ_CALENDAR" />

<!-- 电话状态权限(普通应用仅能获取基础状态) -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

<!-- 自定义权限 -->
<uses-permission android:name="in.globalspace.android.gst_communicator_permission" />

<!-- Android 12及以下存储权限,Android 13+自动忽略 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:maxSdkVersion="32" />

额外注意事项

  • 遵循按需申请原则,不要一次性请求所有权限,分场景申请可提升用户授权率。
  • Android 13媒体权限可按需申请,比如仅需访问图片时无需申请READ_MEDIA_AUDIO。
  • shouldShowRequestPermissionRationale返回false时,说明用户已勾选「不再询问」,此时只能引导用户前往设置页开启权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 12:17:40