Android 13位置权限异常:直接触发isAnyPermissionPermanentlyDenied问题
Android 13位置权限请求异常问题分析与解决
问题现象
在Android 13系统中,使用Dexter请求ACCESS_FINE_LOCATION权限时,直接进入isAnyPermissionPermanentlyDenied分支,不会向用户发起权限请求;即使在系统设置中手动授予该权限,仍会触发该分支。
问题原因
- Android 13权限机制变更:Android 13对位置权限逻辑做了调整,
ACCESS_FINE_LOCATION无法单独发起请求,必须与ACCESS_COARSE_LOCATION同时请求,系统会合并弹出包含精确/模糊位置选项的权限对话框。单独请求精确位置权限时,系统会直接判定请求异常,导致Dexter误判为永久拒绝。 - Dexter版本兼容性问题:旧版本Dexter未适配Android 13的新权限模型,无法正确识别权限请求状态,错误触发永久拒绝分支。
- 权限状态同步延迟:手动授予权限后,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
相关产品推荐
相关产品推荐

