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

Android Studio获取用户位置时触发空指针异常致应用崩溃

解决LocationManager导致的NullPointerException崩溃问题

嘿,我仔细看了你的代码,崩溃的根源很清晰——你在onCreate里调用locationManager.getLastKnownLocation(locationManager.NETWORK_PROVIDER)时,这个方法返回了null,然后你直接把这个null对象传给了onLocationChanged方法,当你在onLocationChanged里尝试访问location.getLatitude()或者location.getLongitude()这类方法时,就触发了NullPointerException。

为什么会返回null?

getLastKnownLocation只会返回设备之前缓存的位置数据,如果设备从未通过NETWORK_PROVIDER获取过位置,或者当前NETWORK_PROVIDER未启用、没有网络连接,这个方法就会返回null。

完整修复方案

我给你一步步梳理修复步骤:

1. 补全权限请求的完整流程

你的代码里只做了权限检查,但没有主动请求权限。如果用户还没授予位置权限,getLastKnownLocation会直接失败甚至返回null。补充权限请求逻辑:

private static final int LOCATION_PERMISSION_REQUEST_CODE = 100;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ... 其他初始化代码(选择图片、日期显示等) ...

    // 检查并请求位置权限
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
        ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
                LOCATION_PERMISSION_REQUEST_CODE);
        return;
    }
    // 权限已授予,再处理位置逻辑
    setupLocationUpdates();
}

// 处理权限请求结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // 用户授予权限,开始获取位置
            setupLocationUpdates();
        } else {
            Toast.makeText(this, "需要位置权限才能获取坐标", Toast.LENGTH_SHORT).show();
        }
    }
}

2. 安全处理getLastKnownLocation的返回值

不要直接把null传给onLocationChanged,先判断是否为null,同时注册监听器获取实时位置:

private void setupLocationUpdates() {
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    
    // 先尝试获取缓存位置
    Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
    if (lastKnownLocation != null) {
        onLocationChanged(lastKnownLocation);
    } else {
        // 没有缓存位置,注册监听器获取实时更新
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            // 注册NETWORK_PROVIDER
            locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                    10000, // 最小更新时间(毫秒)
                    10,    // 最小更新距离(米)
                    this);
            // 同时注册GPS_PROVIDER,提升获取成功率
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                    10000,
                    10,
                    this);
        }
        Toast.makeText(this, "正在获取实时位置...", Toast.LENGTH_SHORT).show();
    }
}

3. 完善onLocationChanged方法,防御性处理null

确保方法能安全处理可能的null(虽然前面已经做了判断,但防御性编程很有必要):

@Override
public void onLocationChanged(Location location) {
    if (location == null) {
        textView.setText("无法获取位置信息");
        return;
    }
    String locationText = String.format("纬度: %.6f\n经度: %.6f",
            location.getLatitude(), location.getLongitude());
    textView.setText(locationText);
}

4. 销毁时移除监听器,避免内存泄漏

在Activity销毁时清理位置监听器:

@Override
protected void onDestroy() {
    super.onDestroy();
    if (locationManager != null) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            locationManager.removeUpdates(this);
        }
    }
}

额外提示

  • 记得在AndroidManifest.xml中声明必要的位置权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  • 同时注册GPS和NETWORK提供者,能兼顾户外(GPS精准)和室内(NETWORK快速)的位置获取需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:01:17