使用当前位置时一直返回location null,搭配Geoquery查询附近用户异常
你遇到的currentLocation返回null的核心原因是位置获取为异步操作:点击按钮调用findClosestCars时,GoogleApiClient还未完成连接,onLocationChanged还没有收到首次位置回调,currentLocation还没完成赋值就被调用,就会触发空值问题。
另外注意你的代码中存在方法名拼写错误:builGoogleApiClient少了字母d,应为buildGoogleApiClient,如果没有其他地方正确调用该方法,会导致位置客户端从未初始化,永远拿不到位置。
同时你提到自己没有使用fusedlocation,但实际代码中调用的LocationServices.FusedLocationApi本身就是FusedLocationProvider的能力,你已经在使用fusedlocation相关API。
- 新增空值拦截,避免直接崩溃
在findClosestCars方法最开头增加空值判断,未拿到位置时先提示用户,不要直接调用经纬度取值方法:
private void findClosestCars() { // 新增空值判断 if (currentLocation == null) { Toast.makeText(this, "正在获取位置,请稍候重试", Toast.LENGTH_SHORT).show(); return; } // 原有逻辑保持不变 latitude=currentLocation.getLatitude(); longitude=currentLocation.getLongitude(); databaseReference = FirebaseDatabase.getInstance().getReference("Lenders"); GeoFire geoFire = new GeoFire(databaseReference); GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(latitude, longitude), radius); geoQuery.removeAllListeners(); geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() { @Override public void onKeyEntered(String key, GeoLocation location) { if (!driverFound) { driverFound = true; driverFoundID = key; closestLender = FirebaseDatabase.getInstance().getReference("Users").child("Lenders").child(driverFoundID); showPictureAndPrice(); } radius++; } @Override public void onKeyExited(String key) { } @Override public void onKeyMoved(String key, GeoLocation location) { } @Override public void onGeoQueryReady() { if (!driverFound) { radius++; } } @Override public void onGeoQueryError(DatabaseError error) { } }); }
提前初始化位置客户端
不要等点击按钮才初始化位置能力,在页面生命周期的onCreate/onStart阶段就调用修复拼写后的buildGoogleApiClient方法,提前完成客户端连接、注册位置监听,让currentLocation在用户点击按钮前就完成赋值。增加缓存位置取值,减少等待时间
在onConnected方法中新增缓存位置读取逻辑,有历史缓存位置时可以直接赋值,不用等待首次位置回调:
@Override public void onConnected(@Nullable Bundle bundle) { mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(1000); mLocationRequest.setFastestInterval(1000); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // 补充动态权限申请逻辑,权限通过后再执行后续位置操作 return; } // 新增:读取历史缓存位置优先赋值 Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); if (lastLocation != null) { currentLocation = lastLocation; } LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); }
补全动态权限逻辑
现有代码中权限校验失败后直接return,没有申请权限,如果用户未授予位置权限,永远无法拿到位置值。需要补充动态权限申请逻辑,权限申请通过后再初始化位置客户端、请求位置更新。按钮状态管控
在拿到首次位置前,将触发findClosestCars的按钮置灰不可点击,避免用户在位置就绪前重复点击触发无效请求。
内容的提问来源于stack exchange,提问作者Timothy Smith

