Introduction
In my app I want to get a one-off accurate location of where the user currently is. When I used FusedLocationProviderApi.getLastLocation
sometimes this would be null or out of date location because I found out this just gets a cached location and does not request a new location update.
The solution was to request a location update only once as seen below.
LocationRequest locationRequest = LocationRequest.create()
.setNumUpdates(1)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(0);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,locationRequest,this)
Now I get a more accurate location all the time.
My Question
How can I determine if a location update failed? Since I am only requesting 1.
When a location update is obtained this callback is invoked
@Override
public void onLocationChanged(Location location) {
}
However this does not get called if a location update failed.
What I have tried
I saw there was a ResultCallback. However, onSuccess seems to be always called even if the one-off location update failed.
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,locationRequest,this).setResultCallback(new ResultCallbacks<Status>() {
@Override
public void onSuccess(@NonNull Status status) {
DebugUtils.log("requestLocationUpdates ResultCallback onSuccess + " + status.toString(),true,true);
}
@Override
public void onFailure(@NonNull Status status) {
DebugUtils.log("requestLocationUpdates ResultCallback onFailure + " + status.toString(),true,true);
}
});
Other
Using com.google.android.gms:play-services-location:8.4.0
Thanks for reading, please help me out.
Accuracy of defined location varies based on number of visible satellites, device hardware and environment. Usually it's about 3m in case if there are no high buildings or metallic structures (hiding satellites from your device sight) around.
The fused location provider manages the underlying location technologies, such as GPS and Wi-Fi, and provides a simple API that you can use to specify the required quality of service. For example, you can request the most accurate data available, or the best accuracy possible with no additional power consumption.
The fused location provider is one of the location APIs in Google Play services. It manages the underlying location technology and provides a simple API so that you can specify requirements at a high level, like high accuracy or low power. It also optimizes the device's use of battery power.
An app can use service APIs of Location Kit to obtain the last known location of a device.
After digging around the API a little more and doing some tests, I found a solution to my problem which seems to be working.
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, new LocationCallback() {
@Override
public void onLocationResult(LocationResult result) {
DebugUtils.log("onLocationResult");
}
@Override
public void onLocationAvailability(LocationAvailability locationAvailability) {
DebugUtils.log("onLocationAvailability: isLocationAvailable = " + locationAvailability.isLocationAvailable());
}
}, null);
Instead of using LocationListener
. I used LocationCallback
onLocationResult
is only called to provide the latest Location result based on the LocationRequest
. It is not called if a location could not be provided and during my tests it is not when Location was disabled and GPS was used indoors etc. Please call result.getLastLocation()
to get the actual location object.
onLocationAvailablity
is always called. locationAvailability.isLocationAvailable()
Returns true if the device location is known and reasonably up to date within the hints requested by the active LocationRequests. False is returned when failure to determine location may from a number of causes including disabled location settings or an inability to retrieve sensor data in the device's environment.
I have tested with no location services, GPS only while indoors. In each case I removed all existing location history (to prevent cached locations). An accurate up-to-date location was always returned.
Could others vouch for this?
Note: The last parameter for the requestLocationUpdates
call is a looper. Passing in null means it will use the calling thread's message queue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With