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

Android Google Maps首次请求定位权限触发SecurityException崩溃

崩溃根因

@SuppressLint("MissingPermission")注解仅用于屏蔽编译阶段的Lint权限警告,不会在运行时自动做权限校验,你的代码存在两个核心问题:

  1. 执行时序错误:onViewCreated中直接调用getMapAsync加载地图,地图加载完成后会立刻触发onMapReady回调,这个回调时机早于你的权限申请、授权流程。首次启动时位置权限还未授予,onMapReady中没有做权限判断就直接调用gMap.setMyLocationEnabled(true)——该方法必须持有位置权限才能调用,直接触发SecurityException崩溃,此时权限弹窗刚弹出,应用已经闪退。
  2. 逻辑遗漏:你写的checkLocationPermission()仅在onResume中调用,权限申请成功的回调里没有同步开启地图的位置图层、也没有触发地图位置更新;同时onMapReady里先添加标记再调用gMap.clear(),刚添加的标记会被直接清空,属于顺序写反的逻辑错误。
修复方案

按以下步骤修改代码即可解决问题:

  • 修改onMapReady逻辑,调用位置相关API前先做运行时权限校验,同时修正标记添加、清除的顺序:
@Override
public void onMapReady(@NonNull GoogleMap googleMap) {
    gMap = googleMap;
    // 有权限才开启我的位置图层
    if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
        || ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        gMap.setMyLocationEnabled(true);
    }
    gMap.clear(); // 先清空旧标记,再添加新标记
    // 未拿到位置前使用默认坐标,避免0,0经纬度定位到大西洋
    LatLng currentPos = new LatLng(39.9042, 116.4074);
    if (latitude != 0 && longitude != 0) {
        currentPos = new LatLng(latitude, longitude);
    }
    gMap.addMarker(new MarkerOptions().position(currentPos).title("当前位置"));
    gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentPos, 15f));
}
  • 补全权限申请成功回调的逻辑,拿到权限后同步开启地图位置图层、启动位置更新:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSION_REQUEST_ACCESS_FINE_LOCATION: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.d("Location", "Now the permission is granted");
                fusedLocationClient = LocationServices.getFusedLocationProviderClient(requireActivity());
                // 权限授予后再开启地图位置图层
                if (gMap != null) {
                    gMap.setMyLocationEnabled(true);
                }
                startLocationUpdates();
                getLastKnownLocation();
            } else {
                Log.d("Location", "Permission still not granted");
            }
            break;
        }
    }
}
  • 在位置更新回调里同步刷新地图标记和视角,确保拿到新位置后地图能自动跟进:
@Override
public void onLocationResult(LocationResult locationResult) {
    if (locationResult == null) {
        Log.d("main_activiyt_maps", "location request is null");
        return;
    }
    for (Location location : locationResult.getLocations()) {
        Log.d("Location", "New Location received: " + location.toString());
        latitude = location.getLatitude();
        longitude = location.getLongitude();
        Log.d("main_activiyt_maps", String.valueOf(latitude));
        Log.d("main_activiyt_maps", String.valueOf(longitude));
        // 拿到新位置后刷新地图
        if (gMap != null) {
            gMap.clear();
            LatLng currentPos = new LatLng(latitude, longitude);
            gMap.addMarker(new MarkerOptions().position(currentPos).title("当前位置"));
            gMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentPos, 15f));
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 05:27:47