Reputation: 1247
How to force FusedLocationProviderClient explicitly ask for a new location?
A few months ago, I upgraded the FusedLocationProviderClient. Ever since, requesting to sample a new location won't provide a new one.
// Request a single location.
// Note: FusedLocationProviderClient.lastLocation
// is no better
val request = LocationRequest()
.setNumUpdates(1)
.setExpirationDuration(0)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setMaxWaitTime(10*DateUtils.SECOND_IN_MILLIS)
.setFastestInterval(0)
fusedLocationClient?.requestLocationUpdates(request, object:LocationCallback() {
override fun onLocationResult(result: LocationResult?) {
super.onLocationResult(result)
Log.v(LOG_TAG, "Single fused location request yields ${result?.lastLocation} ")
callOnDone(result?.lastLocation)
}
}, Looper.getMainLooper())
When I get request locations, even seconds apart, it gets me the same location with the same time stamp.
I use emulator with a GPX recording of my track, so that GPS readouts are always available.
However, when I tried to request a location from the location manager (and do nothing with the result), it works much better.
(context?.getSystemService(Context.LOCATION_SERVICE) as? LocationManager)?
.requestSingleUpdate(
LocationManager.GPS_PROVIDER,
object :LocationListener{...dummy, just log the callback...},
Looper.getMainLooper())
Conclusion: FusedLocationProviderClient won't request new locations from the OS, even on High Priority mode. However, it does accept new locations if one is available from outside.
The question is: How do I force FusedLocationProviderClient to proactively request a new location when I need a new one here and now?
Upvotes: 5
Views: 1751
Reputation: 721
This question is quite old, but I came here with a similar question, and I see about 65 others have over the last couple months. The following code works. It delivers a Location to the onLocationResult callback, at locationResult.getLastLocation():
public void getNewLocation() {
LocationRequest locationRequest = new LocationRequest()
.setNumUpdates(1)
.setFastestInterval(0)
.setSmallestDisplacement(0)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if (ActivityCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
fusedLocationProviderClient.requestLocationUpdates(locationRequest,
new com.google.android.gms.location.LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
locationListener.onLocationChanged(locationResult.getLastLocation());
}
},
Looper.getMainLooper());
}
The difference here is that I've removed the setMaxWaitTime and setExpirationDuration. Evidently they break the call. If I interpret setExpirationDuration correctly, it means this request should expire in x millis. Setting it zero means the request expires immediately, so when a Location does become available, the request has already expired. Hence no callback to onLocationChanged.
I hope this helps somebody.
Upvotes: 1