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
相关产品推荐
相关产品推荐

