Android-GeoFire项目出现Location NullPointerException问题求助
解决你的空指针崩溃问题
首先看你的错误日志:
java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference at com.jamesboyle.firsthelp.PatientMapActivity$2.onClick(PatientMapActivity.java:83)
这个错误指向非常明确:你在调用Location.getLatitude()时,mLastLocation这个对象是null,也就是还没被初始化就直接拿来用了,对应你代码里按钮点击事件里的这两行:
geoFire.setLocation(userID, new GeoLocation(mLastLocation.getLatitude(), mLastLocation.getLongitude())); pickupLocation = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
为什么会出现这个问题?
大概率是你还没成功获取到设备的位置信息,就触发了按钮点击。比如:
- 位置权限没申请/没通过(Android 6.0+需要动态申请位置权限)
- 设备位置服务没开启
- 获取位置的异步操作还没返回结果,
mLastLocation还没被赋值
具体修复步骤
先给
mLastLocation加非空判断
在执行位置相关代码前,先检查mLastLocation是否为空,避免直接调用方法:mRequest.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 先检查用户是否已登录 FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser(); if (currentUser == null) { Toast.makeText(PatientMapActivity.this, "请先登录账号", Toast.LENGTH_SHORT).show(); return; } // 检查位置是否成功获取 if (mLastLocation == null) { Toast.makeText(PatientMapActivity.this, "无法获取当前位置,请检查位置服务是否开启", Toast.LENGTH_SHORT).show(); return; } // 下面是原来的业务逻辑 String userID = currentUser.getUid(); DatabaseReference ref = FirebaseDatabase.getInstance().getReference("patientRequest"); GeoFire geoFire = new GeoFire(ref); geoFire.setLocation(userID, new GeoLocation(mLastLocation.getLatitude(), mLastLocation.getLongitude())); pickupLocation = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude()); mMap.addMarker(new MarkerOptions().position(pickupLocation).title("Respond Now")); mRequest.setText("Locating Responder..."); getClosestResponder(); } });确保位置权限和位置获取流程正确
- 检查你是否已经动态申请了
ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION权限,并且用户已经同意 - 如果你用的是
FusedLocationProviderClient或LocationManager获取位置,要确保在位置回调成功拿到Location对象后,再给mLastLocation赋值,甚至可以在拿到位置前把按钮设为不可点击(mRequest.setEnabled(false)),避免用户误操作
- 检查你是否已经动态申请了
额外的潜在问题排查
你的getClosestResponder()方法里用到了pickupLocation,如果pickupLocation因为mLastLocation为空没被初始化,后续也会抛出空指针,所以上面的非空判断能同时避免这个连锁问题。
内容的提问来源于stack exchange,提问作者James Boyle
相关产品推荐
相关产品推荐

