Reputation: 3377
In my app I need to get users location (one shot, not continuously track), to calculate routes. So the location needs to be as accurate as possible but I do not want to keep user waiting too long when my app tries to get the accurate location.
Im using Google Play services location api like this:
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setNumUpdates(1);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,locationRequest, this);
mLocationHandler.sendEmptyMessageDelayed(0, 15000); // Time out location request
I have Handler mLocationHandler, which cancels locationRequest after 15 second, as I do not want to keep user waiting too long.
Is there any way, how I can try to get not so accurate location if the high accuracy location times out?
Upvotes: 2
Views: 1719
Reputation: 9113
I use external library for this: Android-ReactiveLocation. Check the Cooler examples
section which presents exactly what you want:
LocationRequest req = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setExpirationDuration(TimeUnit.SECONDS.toMillis(LOCATION_TIMEOUT_IN_SECONDS))
.setInterval(LOCATION_UPDATE_INTERVAL);
Observable<Location> goodEnoughQuicklyOrNothingObservable = locationProvider.getUpdatedLocation(req)
.filter(new Func1<Location, Boolean>() {
@Override
public Boolean call(Location location) {
return location.getAccuracy() < SUFFICIENT_ACCURACY;
}
})
.timeout(LOCATION_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS, Observable.just((Location) null), AndroidSchedulers.mainThread())
.first()
.observeOn(AndroidSchedulers.mainThread());
goodEnoughQuicklyOrNothingObservable.subscribe(...);
Upvotes: 2
Reputation:
You can try this after the time out,
Location currentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
It will give you the last known location and check if the accuracy is better than what you got from the location updates.
Update your updates something like this:
final LocationRequest REQUEST = LocationRequest.create()
.setInterval(16)
.setFastestInterval(16) // 16ms = 60fps
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
This will ensure that you will have updates. You can then reduce your timeouttime not more than a second should be enough. Then you can remove the locationupdaterequest like this:
if(mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,this);
}
Upvotes: 3