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

Android 13位置权限异常:直接触发isAnyPermissionPermanentlyDenied问题

Android 13位置权限请求异常问题分析与解决

问题现象

在Android 13系统中,使用Dexter请求ACCESS_FINE_LOCATION权限时,直接进入isAnyPermissionPermanentlyDenied分支,不会向用户发起权限请求;即使在系统设置中手动授予该权限,仍会触发该分支。

问题原因

  1. Android 13权限机制变更:Android 13对位置权限逻辑做了调整,ACCESS_FINE_LOCATION无法单独发起请求,必须与ACCESS_COARSE_LOCATION同时请求,系统会合并弹出包含精确/模糊位置选项的权限对话框。单独请求精确位置权限时,系统会直接判定请求异常,导致Dexter误判为永久拒绝。
  2. Dexter版本兼容性问题:旧版本Dexter未适配Android 13的新权限模型,无法正确识别权限请求状态,错误触发永久拒绝分支。
  3. 权限状态同步延迟:手动授予权限后,Dexter的权限检测逻辑未及时同步系统权限状态,依然沿用之前的错误判定结果。

解决方案

1. 适配Android 13位置权限请求逻辑

同时请求ACCESS_COARSE_LOCATION和ACCESS_FINE_LOCATION权限,符合Android 13的权限请求规范:

val permissions = arrayListOf(
    Manifest.permission.ACCESS_COARSE_LOCATION,
    Manifest.permission.ACCESS_FINE_LOCATION
)
Dexter.withActivity(this).withPermissions(permissions)
    .withListener(object : MultiplePermissionsListener {
        override fun onPermissionsChecked(report: MultiplePermissionsReport) {
            // 精准判断精确位置权限的授予状态
            val fineLocationGranted = report.getPermissionState(Manifest.permission.ACCESS_FINE_LOCATION).isGranted
            when {
                fineLocationGranted -> checkAppUpdate()
                report.isAnyPermissionPermanentlyDenied -> startActivity(
                    Intent(
                        Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                        Uri.parse("package:" + BuildConfig.APPLICATION_ID)
                    )
                )
                else -> checkPermission()
            }
        }

        override fun onPermissionRationaleShouldBeShown(
            permissions: List<PermissionRequest>,
            token: PermissionToken
        ) {
            token.continuePermissionRequest()
        }
    }).onSameThread().check()

2. 升级Dexter到兼容Android 13的版本

在项目build.gradle中更新Dexter依赖到最新兼容版本:

implementation 'com.karumi:dexter:6.2.3' // 或更高兼容版本

3. 手动校验权限状态

绕过Dexter的自动判定,直接调用系统API校验权限状态,避免依赖库的兼容性问题:

private const val REQUEST_LOCATION_CODE = 1001

private fun checkLocationPermission() {
    val fineLocationGranted = ContextCompat.checkSelfPermission(
        this,
        Manifest.permission.ACCESS_FINE_LOCATION
    ) == PackageManager.PERMISSION_GRANTED

    if (fineLocationGranted) {
        checkAppUpdate()
        return
    }

    // 判断是否需要展示权限说明
    if (ActivityCompat.shouldShowRequestPermissionRationale(
            this,
            Manifest.permission.ACCESS_FINE_LOCATION
        )
    ) {
        showPermissionRationale() // 自定义展示权限必要性的逻辑
    } else {
        // 发起符合Android 13规范的权限请求
        ActivityCompat.requestPermissions(
            this,
            arrayOf(
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION
            ),
            REQUEST_LOCATION_CODE
        )
    }
}

// 处理权限请求结果
override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode != REQUEST_LOCATION_CODE) return

    val fineLocationGranted = grantResults.getOrNull(1) == PackageManager.PERMISSION_GRANTED
    if (fineLocationGranted) {
        checkAppUpdate()
    } else {
        // 判断是否为永久拒绝
        val shouldShowRationale = ActivityCompat.shouldShowRequestPermissionRationale(
            this,
            Manifest.permission.ACCESS_FINE_LOCATION
        )
        if (!shouldShowRationale) {
            startActivity(
                Intent(
                    Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                    Uri.parse("package:" + BuildConfig.APPLICATION_ID)
                )
            )
        } else {
            checkLocationPermission()
        }
    }
}

内容的提问来源于stack exchange,提问作者Cijo K Paul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 17:35:30