Google Play Services Location API

Location awareness in Android part II

Posted by Romina Liuzzi on January 9, 2018

To implement location awareness in your Android app Google supports two location strategies: android.location package and Google Play Services Location API. Google strongly advices developers to use the second approach.

In fairness Google has simplified the process greatly and claims following this approach improves battery performance in most cases. This makes sense as the Location Service is run as system process to which you subscribe. On the less bright side this approach depends on Google Play Services being installed in the phone.

So in order to implement this solution and make sure your app gracefully handles all possible combination of scenarios there are a few things you need to do.

  1. Setup Google Play Services Location API
  2. Verify Google Play Services is installed
  3. Handle App Permissions
  4. Implement Location Service

Setup Google Play Services Location API

Google Play Services comprises several services. To get the user current location and request location updates from your Android app you will need to include the play-services-location package.

In order to include this package in your app as a selective dependency of the Google Play Services you need to follow these steps:

  1. If you haven't already done so, download and install Google Play Services from Android Studio's SDK Manager.
  2. Include google() or maven { url "https://maven.google.com" } repository to top level build.gradle
  3. Include play-services-location dependency to app level build.gradle
    			compile 'com.google.android.gms:play-services-location:11.8.0'
  4. Sync Gradle dependencies

Verify Google Play is installed

Your app should verify the required version of the Google Play Services APK is installed in the device. There are two strategies to perform this step:

  1. Delegate the check on the service client object by passing an Activity at time on instatiation*
    			//this must be an Activity
    FusedLocationClient client = LocationServices.getFusedLocationProviderClient(this);
  2. Use the GoogleApiAvailibility singlenton service to manually check:
    			public boolean checkPlayServices(final IcabbiActivity activity) {
    GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
    int resultCode = apiAvailability.isGooglePlayServicesAvailable(context);
    if (resultCode != ConnectionResult.SUCCESS) {
    if (apiAvailability.isUserResolvableError(resultCode)) {
    Dialog playServicesErrorDialog = apiAvailability.getErrorDialog(activity, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST);
    playServicesErrorDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
    @Override
    public void onCancel(DialogInterface dialogInterface) {
    activity.finish();
    }
    });
    playServicesErrorDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
    @Override
    public void onDismiss(DialogInterface dialog) {
    }
    });
    playServicesErrorDialog.show();
    } else {
    Timber.e(String.format("This device is not supported. Result code: %s", resultCode));
    activity.finish();
    }
    return false;
    }
    return true;
    }
    Then in your activiy get the intent result
    			@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PermissionHelper.PLAY_SERVICES_RESOLUTION_REQUEST) {
    if (resultCode != ConnectionResult.SUCCESS) {
    Timber.e(String.format("This device is not supported. Result code: %s", resultCode));
    finish();
    }
    }
    }

Handle App Permissions

Since Android M permission granting was moved from install time to runtime. This is good for the user and hell for the developer. There is no way around this one. Before accessing the device location you must cofirm you have permission to do so and fail gracefully if you don't.

I am currently using the Permision Dispatcher library to handle the permissions checks.

Implement Location Service

If you need to get location updates from you app you need to be aware that since Android O, if your app is running in the background the number of requests your app can make to the FusedLocationManager and the LocationsManager are restricted to a few every hour.*.

Every app is different. If you need to request frequent updates you can run your location service as a foreground service*.

References