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

Fused Location Provider getLastLocation()返回空值致应用崩溃排查

解决Fused Location Provider Client返回空值导致的空指针崩溃问题

问题核心

你遇到的java.lang.NullPointerException,是因为直接调用了getLastLocation()返回的null对象的getLongitude()方法。getLastLocation()返回空值的常见场景包括:

  • 设备从未获取过有效位置信息
  • 位置服务刚开启,还未生成缓存位置
  • 应用未获得定位权限
  • Google Play服务版本过低或运行异常

具体修复方案

1. 给getLastLocation()的返回值强制判空

修改你的位置获取代码,先校验位置对象是否非空,再执行后续逻辑:

fusedLocationProviderClient.getLastLocation()
    .addOnSuccessListener(baseView, position -> {
        if (position != null) { // 先判空,避免空指针
            Log.d("TAG", "updateGPS: position elements are : " + "lon = " + position.getLongitude() + "lat = " + position.getLatitude() + "alt " + position.getAltitude() + "Acc= " + position.getAccuracy() + " Speed = " + position.getSpeed());
            if (position.getAccuracy() <= 20f) {
                location.setLongitude(position.getLongitude());
                location.setLatitude(position.getLatitude());
                location.setAltitude(position.getAltitude());
                location.setAccuracy(position.getAccuracy());
                location.setSpeed(position.getSpeed());
            }
        } else {
            // 无缓存位置时触发实时更新
            startLocationUpdate();
            Log.d("TAG", "updateGPS: 无缓存位置,启动实时位置更新");
        }
    })
    .addOnFailureListener(e -> {
        // 处理获取位置失败的异常,比如权限问题或服务错误
        Log.e("TAG", "获取位置失败: ", e);
    });

2. 移除assert,改用安全的空值判断

assert在release版本中会被自动忽略,无法起到空值防护作用,修改你的LocationCallback:

locationCallback = new LocationCallback() {
    @Override
    public void onLocationResult(@NonNull LocationResult locationResult) {
        super.onLocationResult(locationResult);
        Location location = locationResult.getLastLocation();
        if (location != null) { // 用if判断替代assert
            Log.d("TAG", "onLocationResult: callback method  " + "longitude " + location.getLongitude() + "latitude " + location.getLatitude() + "Accuracy " + location.getAccuracy() + "Speed " + location.getSpeed());
            // 在这里处理实时获取到的位置,比如更新你的全局location对象
            if (location.getAccuracy() <= 20f) {
                // 执行位置赋值逻辑
            }
        }
    }
};

3. 补全权限申请流程

你的startLocationUpdate()仅做了权限检查,但没有主动申请权限的逻辑,补充如下:

// 检查并请求定位权限
private void checkLocationPermission() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1001);
    } else {
        // 权限已授予,启动位置更新
        locationSettings();
    }
}

// 处理权限申请结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 1001) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            locationSettings();
        } else {
            Toast.makeText(this, "需要定位权限才能获取位置信息", Toast.LENGTH_SHORT).show();
        }
    }
}

之后在初始化时调用checkLocationPermission(),而非直接调用locationSettings()。

4. 优先依赖实时位置更新

getLastLocation()仅返回缓存位置,可靠性较低。建议以LocationCallback的实时更新作为主要位置来源,getLastLocation()仅作为补充方案。

5. (可选)使用新版LocationRequest构建方式

如果你的Google Play服务版本≥19.0.0,推荐使用更规范的LocationRequest.Builder构建请求:

public void locationSettings() {
    newlocationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 30000)
            .setMinUpdateIntervalMillis(5000)
            .build();
    startLocationUpdate();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:10:26