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

调用GoogleMap.setMyLocationEnabled缺定位权限 闪退无权限弹窗

运行时报错信息
Missing permissions required by GoogleMap.setMyLocationEnabled: android.permission.ACCESS_COARSE_LOCATION or android.permission.ACCESS_FINE_LOCATION
问题场景

调用地理围栏定位功能,选择地理围栏区域时应用闪退。已在AndroidManifest.xml中声明ACCESS_COARSE_LOCATION、ACCESS_FINE_LOCATION相关权限,但应用启动时从未弹出权限授权申请弹窗。

运行时权限缺失报错截图

问题原因

当前动态权限申请逻辑存在两处致命问题:

  • 重复嵌套了两层完全一致的ActivityCompat.shouldShowRequestPermissionRationale判断,该方法仅在用户曾经拒绝过权限申请、且未勾选“不再询问”选项时才会返回true。应用首次安装启动时该方法返回值为false,导致现有逻辑永远不会在首次启动时触发权限申请流程,自然不会弹出授权弹窗。
  • 代码逻辑错误地将shouldShowRequestPermissionRationale作为发起权限申请的前置条件,完全没有覆盖首次安装启动的权限申请场景,调用mMap.setMyLocationEnabled(true)时没有获得对应权限,直接触发闪退。

注:Android 6.0(API 23)及以上版本的危险权限,仅在清单文件声明不会自动授予,必须通过动态申请流程获得用户授权后才能调用相关接口。

修复步骤
  1. 修正enableUserLocation方法逻辑,移除无意义的重复判断,未获得权限时直接发起申请:
// 定位权限请求码,可自行定义取值
private static final int FINE_LOCATION_ACCESS_REQUEST_CODE = 1001;

private void enableUserLocation(){
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
        // 已获得权限再开启位置图层
        mMap.setMyLocationEnabled(true);
    } else {
        // 未获得权限时直接发起申请,无需等shouldShowRequestPermissionRationale返回true
        // 该方法仅用于判断是否需要向用户展示权限用途说明,不是申请权限的前置条件
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
                FINE_LOCATION_ACCESS_REQUEST_CODE);
    }
}
  1. 重写权限申请结果回调,用户授权完成后再执行开启位置图层的逻辑:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == FINE_LOCATION_ACCESS_REQUEST_CODE) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // 校验权限确实授予后再开启位置图层
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                mMap.setMyLocationEnabled(true);
            }
        } else {
            // 用户拒绝权限时给出提示
            Toast.makeText(this, "定位权限是使用地理围栏功能的必要权限,请在应用设置中手动开启", Toast.LENGTH_LONG).show();
        }
    }
}
额外注意事项
  • 如果你的应用适配Android 10(API 29)及以上版本用到ACCESS_BACKGROUND_LOCATION后台定位权限,不能和前台定位权限同时申请,必须等用户同意前台定位权限后,再单独发起后台定位权限的申请,否则系统会直接拒绝该权限请求。
  • 如果需要给用户解释权限用途,可以在shouldShowRequestPermissionRationale返回true的时候先弹一个说明弹窗,用户确认后再调用requestPermissions,不要把这个判断作为拦截权限申请的条件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 13:15:35