fusedLocationProviderClient.lastLocation.addOnSuccessListener 始终为空

fusedLocationProviderClient.lastLocation.addOnSuccessListener always null

我刚刚更新了我的位置 API 以使用 FusedLocationProviderClient 但我遇到了这个问题,当我关闭和打开 GPS 时,我总是得到空位置:

val fusedLocationProviderClient =
                        LocationServices.getFusedLocationProviderClient(callingActivity)
            fusedLocationProviderClient.flushLocations()
            getLocationRequest()

            checkLocationSettings(callingActivity, turnOnGpsRequestCode, callback) {
                // Location settings successful
                fusedLocationProviderClient.lastLocation
                        .addOnSuccessListener(callingActivity) {
                            location ->
                            // Here location is always null
callback.onCallback(MenumyRadar.RadarStatus.SUCCESS, location)
                        }
                        .addOnFailureListener {
                            callback.onCallback(MenumyRadar.RadarStatus.ERROR_UNKNOWN, null)
                        }
            }

直到我打开另一个使用位置的应用程序,如 Google 地图或优步,它才起作用。

多亏了这个答案,我有了一些线索

以及 Google 的解释:

fusedLocationClient.lastLocation .addOnSuccessListener { location : Location? -> // Got last known location. In some rare situations this can be null. }

The getLastLocation() method returns a Task that you can use to get a Location object with the latitude and longitude coordinates of a geographic location. The location object may be null in the following situations:

Location is turned off in the device settings. The result could be null even if the last location was previously retrieved because disabling location also clears the cache. The device never recorded its location, which could be the case of a new device or a device that has been restored to factory settings. Google Play services on the device has restarted, and there is no active Fused Location Provider client that has requested location after the services restarted. To avoid this situation you can create a new client and request location updates yourself. For more information, see Receiving Location Updates.

但是没有说怎么处理,怎么办?

我找到了一个解决方案,这是发生了什么,当位置为空时,这意味着位置缓存已被清除,关闭 GPS 时会发生这种情况,所以当我打开它时,没有最后一个位置可以获取,我所做的是:

checkLocationSettings(callingActivity, turnOnGpsRequestCode, callback) {
                // Location settings successful
                mFusedLocationProviderClient!!.lastLocation
                        .addOnSuccessListener(callingActivity) {
                            location ->
                            if (location == null || location.accuracy > 100) {
                                mLocationCallback = object : LocationCallback() {
                                    override fun onLocationResult(locationResult: LocationResult?) {
                                        stopLocationUpdates()
                                        if (locationResult != null && locationResult.locations.isNotEmpty()) {
                                            val newLocation = locationResult.locations[0]
                                            callback.onCallback(Status.SUCCESS, newLocation)
                                        } else {
                                            callback.onCallback(Status.ERROR_LOCATION, null)
                                        }
                                    }
                                }

                                mFusedLocationProviderClient!!.requestLocationUpdates(getLocationRequest(),
                                        mLocationCallback, null)
                            } else {
                                callback.onCallback(Status.SUCCESS, location)
                            }
                        }
                        .addOnFailureListener {
                            callback.onCallback(Status.ERROR_UNKNOWN, null)
                        }
            }

当位置为空时,开始使用回调请求位置并且

mFusedLocationProviderClient!!.requestLocationUpdates(getLocationRequest(), mLocationCallback,空)

然后当回调被调用时,得到一个新的位置,它又开始获取位置。

有时候打开GPS时,位置不为空,但精度不好,所以我也检查定位精度是否足够好(对我来说足够好是100米)

您可以在 FusedLocationPrivedClient 对象上使用 getLocationAvailability() 方法,如果它 returns 为真,则仅使用 getLastLocation() 方法,否则使用 requestLocationUpdates() 方法,如下所示:

FusedLocationProviderClient fusedLocationProviderClient =
            LocationServices.getFusedLocationProviderClient(InitActivity.this);
    if (ActivityCompat.checkSelfPermission(this.getApplicationContext(),
            android.Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {

fusedLocationProviderClient.getLocationAvailability().addOnSuccessListener(new OnSuccessListener<LocationAvailability>() {
                @Override
                public void onSuccess(LocationAvailability locationAvailability) {
                    Log.d(TAG, "onSuccess: locationAvailability.isLocationAvailable " + locationAvailability.isLocationAvailable());
                    if (locationAvailability.isLocationAvailable()) {
                        if (ActivityCompat.checkSelfPermission(InitActivity.this.getApplicationContext(),
                                android.Manifest.permission.ACCESS_FINE_LOCATION)
                                == PackageManager.PERMISSION_GRANTED) {
                            Task<Location> locationTask = fusedLocationProviderClient.getLastLocation();
                            locationTask.addOnCompleteListener(new OnCompleteListener<Location>() {
                                @Override
                                public void onComplete(@NonNull Task<Location> task) {
                                    Location location = task.getResult();                                    
                                }
                            });
                        } else {
                            requestLocationPermissions ();
                        }

                    } else {
fusedLocationProviderClient.requestLocationUpdates(locationRequest, pendingIntent);

                    }

                }
            });
        } else {
            requestLocationPermissions ();
        }