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

