Android fusedLocationProviderClient.lastLocation.addOnSuccessListener始终为空

Android fusedLocationProviderClient.lastLocation.addOnSuccessListener始终为空,android,android-location,Android,Android Location,我刚刚更新了我的位置API以使用FusedLocationProviderClient,但我遇到了这个问题,当我关闭和打开GPS时,我总是得到空位置: val fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(callingActivity) fusedLocationProviderClient.flushLocati

我刚刚更新了我的位置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)
                        }
            }
直到我打开另一个使用位置的应用程序,如谷歌地图或优步,它才起作用

由于这个答案,我有了一些线索

谷歌的解释是:

fusedLocationClient.lastLocation .addOnSuccessListener{ 地点:地点?-> //已获取最后一个已知位置。在某些罕见情况下,此值可以为空。 }

getLastLocation()方法返回一个任务,您可以使用该任务获取具有纬度和经度坐标的Location对象 指地理位置。中的location对象可能为空 以下情况:

“设备设置”中的“位置”已关闭。结果可能是 即使上次检索到的位置为空,因为 禁用位置也会清除缓存。设备从未录制 它的位置,可能是新设备或 已恢复为出厂设置。谷歌在线播放服务 设备已重新启动,并且没有活动的融合位置提供程序 服务重新启动后已请求位置的客户端。到 避免这种情况,您可以创建一个新的客户端和请求位置 更新你自己。有关更多信息,请参阅接收位置 更新


但它没有说明如何处理这个问题,我能做什么?

我找到了一个解决方案,这就是发生的情况,当位置为空时,这意味着位置缓存被清除,当关闭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!!。RequestLocationUpdate(getLocationRequest(), mLocationCallback,null)

然后,当调用回调时,将获得一个新的位置,并再次开始获取位置


有时,当您打开GPS时,位置不是空的,但精度不好,因此我也会检查位置精度是否足够好(对我来说足够好是100米)

您可以对FusedLocationPrivedClient对象使用getLocationAvailability()方法,如果返回true,则只使用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 ();
        }
FusedLocationProviderClient FusedLocationProviderClient=
getFusedLocationProviderClient(InitActivity.this);
如果(ActivityCompat.checkSelfPermission)(this.getApplicationContext(),
android.Manifest.permission.ACCESS\u FINE\u位置)
==PackageManager.权限(已授予){
fusedLocationProviderClient.getLocationAvailability().addOnSuccessListener(新OnSuccessListener()){
@凌驾
成功时公共无效(位置可用性位置可用性){
Log.d(标记“onSuccess:locationAvailability.isLocationAvailable”+locationAvailability.isLocationAvailable());
if(locationAvailability.isLocationAvailable()){
如果(ActivityCompat.checkSelfPermission)(InitActivity.this.getApplicationContext()),
android.Manifest.permission.ACCESS\u FINE\u位置)
==PackageManager.权限(已授予){
Task locationTask=fusedLocationProviderClient.getLastLocation();
locationTask.addOnCompleteListener(新的OnCompleteListener(){
@凌驾
未完成的公共void(@NonNull任务){
位置=task.getResult();
}
});
}否则{
requestLocationPermissions();
}
}否则{
fusedLocationProviderClient.RequestLocationUpdate(locationRequest,PendingContent);
}
}
});
}否则{
requestLocationPermissions();
}

它返回null,因为获取最后一个已知位置需要时间。所以你可以做的是,检查位置是否为空,如果是,则显示。如果我等待10-15分钟,它会一直返回空值,直到我打开谷歌地图。听起来你是在清除位置缓存,关闭GPS,然后询问最后一个位置并获取空值。对我来说,这似乎是意料之中的行为。如果需要获得位置修复,请先检查LAST,如果它为null,则需要添加LocationRequest并侦听。如果可以的话,这需要一点时间才能得到修复,并启动回调,然后下次您将同时拥有您的位置和最后一个位置。@Ankur_009您找到解决方案了吗?您是否尝试过移动手机?AFAIK仅在位置更改时更新缓存。在打开GPS的新模拟器API 19上不起作用<未调用code>onLocationResult。什么是
PendingContent
<代码>位置可用性?.isLocationAvailable==false在新鲜API 19模拟器中。