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

Android 13 Tiramisu 权限请求循环触发异常问题排查修复

问题产生原因
  • Android 13(API 级别33)对存储权限模型做了强制调整:代码中调用的READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE两个权限在API33及以上版本已被正式废弃,系统不会针对这两个权限弹出授权申请弹窗,调用ActivityCompat.requestPermissions申请这两个权限时,系统会直接默认返回拒绝结果,不存在用户交互等待过程。
  • 权限申请逻辑放在了onResume()生命周期中,而权限申请的系统弹窗本身是独立Activity,不管是弹窗弹出还是关闭(包括系统直接拒绝不弹窗的场景),都会重新触发当前页面的onResume回调。在Android13上申请旧存储权限时,系统瞬间返回拒绝结果回到页面,onResume立刻再次执行,再次调用权限申请方法,就形成了无弹窗的无限循环,这也是日志里反复打印方法入口日志的核心原因。
  • 代码本身存在一处笔误:遍历权限时把未授权的权限存入了名为list的ArrayList,但是发起申请时传入的是未定义的permissionsNeeded变量,这段代码正常情况下无法通过编译,属于贴代码时的书写错误。
修复方案
  • 做存储权限的版本适配,针对不同系统版本申请对应合法权限:
    • 系统版本低于API33时,正常申请READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE旧存储权限
    • 系统版本大于等于API33时,完全不要申请旧存储权限,根据自身业务需求申请READ_MEDIA_IMAGES、READ_MEDIA_VIDEO、READ_MEDIA_AUDIO三个细分媒体读取权限;如果需要访问公共目录下的非媒体文件,直接使用SAF存储访问框架实现,不要依赖全局存储权限。
  • 修复代码逻辑错误,把未授权权限列表正确传入申请方法,不要重复申请已经获得授权的权限,修正后的申请逻辑参考:
static boolean requestPermission(int id, String... permissions) {
    System.out.println("REQUEST PERMISSION METHOD");
    boolean allGranted = true;
    ArrayList<String> needRequestList = new ArrayList<>();
    
    for (String permission : permissions) {
        int checkResult = ContextCompat.checkSelfPermission(this, permission);
        boolean hasPermission = (checkResult == PackageManager.PERMISSION_GRANTED);
        allGranted &= hasPermission;
        if (!hasPermission) {
            needRequestList.add(permission);
        }
    }

    if (allGranted) {
        return true;
    } else {
        // 传入实际需要申请的未授权权限列表,不要传全量权限
        ActivityCompat.requestPermissions(this, needRequestList.toArray(new String[0]), id);
        return false;
    }
}
  • 增加防重入标记避免生命周期触发重复调用:不要在onResume里无脑触发权限申请,增加布尔类型标记位isRequestingPermission,发起权限申请前先判断如果标记位为true(正在申请中)就直接返回,发起申请时将标记位置为true,在onRequestPermissionsResult权限结果回调中再将标记位置为false,从根源上避免生命周期重入导致的重复调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 10:01:48