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

使用Geocoder获取当前位置地址 开启GPS后出现空指针异常问题

问题根源

  • 你在RESOLUTION_REQUIRED分支调用弹窗请求用户开启GPS后,没有处理用户操作完成后的系统回调,用户同意开启GPS后代码不会自动执行getCurrentLocation方法,仅在GPS原本就处于开启状态时才会调用该方法。
  • fusedLocationProviderClient.getLastLocation()本身允许返回null:尤其是GPS刚开启的场景下,系统还没有生成最近的定位缓存,此时task.getResult()拿到的Location对象为空,你没有做非空校验就直接调用getLatitude(),就会触发空指针异常。
  • 额外风险:Geocoder.getFromLocation也可能返回空列表,直接取下标为0的元素也存在崩溃风险。

修复方案

步骤1:处理GPS开启结果回调

在HomeActivity中重写onActivityResult方法,接收用户对GPS开启弹窗的操作结果,用户确认开启后主动调用getCurrentLocation:

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CHECK_SETTINGS) {
        // 用户确认开启GPS
        if (resultCode == RESULT_OK) {
            getCurrentLocation();
        } else {
            // 用户拒绝开启GPS,可做对应提示
            Toast.makeText(this, "需要开启GPS才能获取位置", Toast.LENGTH_SHORT).show();
        }
    }
}

步骤2:优化getCurrentLocation方法,增加空校验

对Location对象做非空判断,拿不到缓存定位时主动请求一次实时定位,同时增加地址列表的空校验:

@RequiresApi(api = Build.VERSION_CODES.M)
private void getCurrentLocation() {
    if (!checkLocationFinePermission() || !checkLocationCoarsePermission() ) {
        requestLocationPermission();
        return;
    }
    // 先尝试拿缓存定位
    fusedLocationProviderClient.getLastLocation().addOnCompleteListener(new OnCompleteListener<Location>() {
        @Override
        public void onComplete(@NonNull Task<Location> task) {
            Location location = task.getResult();
            if (location != null) {
                // 缓存定位不为空,直接转地址
                parseLocationToAddress(location);
            } else {
                // 缓存为空,主动请求一次实时定位
                fusedLocationProviderClient.getCurrentLocation(LocationRequest.PRIORITY_HIGH_ACCURACY, null)
                        .addOnCompleteListener(new OnCompleteListener<Location>() {
                            @Override
                            public void onComplete(@NonNull Task<Location> task) {
                                Location realTimeLocation = task.getResult();
                                if (realTimeLocation != null) {
                                    parseLocationToAddress(realTimeLocation);
                                } else {
                                    Toast.makeText(HomeActivity.this, "获取位置失败,请稍后重试", Toast.LENGTH_SHORT).show();
                                }
                            }
                        });
            }
        }
    });
}

// 抽离公共的地址转换方法
private void parseLocationToAddress(Location location) {
    Geocoder geocoder = new Geocoder(HomeActivity.this, Locale.getDefault());
    try {
        List<Address> addresses = geocoder.getFromLocation(
                location.getLatitude(), location.getLongitude(), 1
        );
        if (addresses != null && !addresses.isEmpty()) {
            adresseEditText.setText(addresses.get(0).getAddressLine(0));
        } else {
            adresseEditText.setText("无法解析当前位置地址");
        }
    } catch (IOException e) {
        e.printStackTrace();
        adresseEditText.setText("地址解析失败");
    }
}

内容的提问来源于stack exchange,提问作者Android dev mrbt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 14:57:04