Search code examples
javaandroidandroid-activityandroid-location

Can I share a FusedLocationProviderClient between several activities?


I have an app which uses positioning from GPS, like this:

    FusedLocationProviderClient _locationProviderClient = LocationServices.getFusedLocationProviderClient(context);

    locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(500);
    locationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
            if (locationResult == null) {
                return;
            }
            for (Location location : locationResult.getLocations()) {
                if (location != null) {
                    // Do some stuff with the location
                }
            }
        }
    };

    _locationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());

Now, this works ok, although there is often a few seconds delay on my phone before it starts working. I can live with that, but a bigger problem is that my app consists of multiple activities, and each time it switches to a new activity, it takes a few seconds for the new activity to get location updates (since I execute the above code again in the new activity's onCreate-method).

So my question is: Can I share the FusedLocationProviderClient between activities, and if so, how?


Solution

  • You can mitigate the delay in getting updates by using the last known location, which presumably will be pretty fresh if you've obtained it in one activity before moving on to the next.

    If that is insufficient for you needs, you can cache the location provider instance either via a singleton or in your custom application class (my preference, as the object belongs to the whole "app").

    Singleton Example:

    public class LocationProviderSingleton {
        private static FusedLocationProviderClient instance
    
        public static FusedLocationProviderClient get(Context context) {
            if (instance == null) {
                instance = LocationServices.getFusedLocationProviderClient(context.getApplicationContext())
            }
    
            return instance;
        }
    }
    

    Application Example

    public class MyApp extends Application {
        private FusedLocationProviderClient mLocationProvider;
    
        public void onCreate() {
            mLocationProvider = LocationServices.getFusedLocationProviderClient(this)
        }
    
        public FusedLocationProviderClient getLocationProvider() {
            return mLocationProvider;
        }
    }
    

    Then in your activities:

    LocationProviderSingleton.get(this)
    // OR
    (getApplicationContext() as MyApp).getLocationProvider()