Search code examples
androidgeolocationandroid-location

Getting user location with minimal impact for battery on Android


I'm starting to develop an app that will stay in background forever and detect when a user is staying in a certain location for a while (and then display a notification to invite the user to open the app to obtain informations about that place).

It's something very similar to what Google Maps does when you're in a restaurant and it shows you a notification to check ratings about it.

What I want is to have a minimal impact on device, so location updates should be very "passive", getting the location only when user is not moving and, if possible, recycling location data that is already got by other activities - maybe by Google Maps itself or other location apps that are running on the devices. This is not a navigation app, so I don't need to have the live fine location but simply the approximate place with the best accuracy and minimal effort, and only if user is not moving.

LocationListener and onLocationChanged seems to be my men, but can I specify that I don't want to trigger device's sensors and only re-use location data when it's available for other scopes? My app should check these informations and then decide to do a reverse geocode if and when they are accurate enough.


Solution

  • Yes, LocationListener and onLocationChanged are your men, though for a passive implementation, there are a few options you can go through.

    First you can check for the last known location, maybe compare it in terms of its time; i.e. getTime() and verify whether it is of use to you.

    In terms of code, literally...
    Google samples, android location has what is relevant for the last location part:

      /**
         * Runs when a GoogleApiClient object successfully connects.
         */
        @Override
        public void onConnected(Bundle connectionHint) {
            // Provides a simple way of getting a device's location and is well suited for
            // applications that do not require a fine-grained location and that do not need location
            // updates. Gets the best and most recent location currently available, which may be null
            // in rare cases when a location is not available.
            mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    

    Further, you can combine it with LocationRequest object, this helps your implementation as you can call it right after trying getLastLocation() and basically have a more reliable arrangement for obtaining location.

         // Create the location request
                mLocationRequest = LocationRequest.create()
    //priority object needs to be set, the following will definitely get results for you  
    .setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)  
    
    //interval updates can be on the lines of 15mins or 30... acc to your requirement
                                .setInterval(UPDATE_INTERVAL)  
                                .setFastestInterval(FASTEST_INTERVAL);
                        // Request location updates
                        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
                                mLocationRequest, this);
    

    i suggest give PRIORITY_NO_POWER a try, could work well in combination with getLastLocation(). These power modes have been added specifically for optimising battery/power consumption and efficiency for retrieving location.