devha
devha

Reputation: 3377

Get best possible location in certain time

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

Answers (2)

Marian Paździoch
Marian Paździoch

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

user5156016
user5156016

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

Related Questions