Developer Impact of Restricted GMS
Many customers adopting GMS in an enterprise environment will be moving from non-GMS (or AOSP) devices and for many customers making that transition it can be a daunting leap.
Zebra’s new Restricted GMS feature is designed to bridge the gap between the previous generation of non-GMS (AOSP) devices and the current generation of GMS devices. enterprises may still be concerned over the privacy implications of GMS but at the same time will want to take advantage of some of the invaluable features and applications which comprise GMS.
With Restricted GMS an enterprise can take full control over device privacy whilst at the same time allowing an administrator to selectively re-enable those GMS features they require.
What is Restricted GMS?
Restricted GMS is a state into which supported Zebra mobile computers can be placed which disables all Google applications and services that are part of Google Mobile Services (e.g. Chrome, Maps, Photos, YouTube, location services, Play Store etc.).
For a more detailed explanation of what Restricted GMS is and what happens on the device when it is in the Restricted state please refer to the associated guide. This post is written as a companion to that guide, for developers targeting Restricted GMS devices.
Developer Impact
As a developer, how do you detect whether you are running on a Restricted GMS device?
There are a couple of different scenarios to consider:
- Whether your application depends on other GMS Applications.
- Whether your application depends on Google Play Services.
Taking these one at a time:
Detecting the presence of GMS Applications
The most common examples here are creating intents to invoke either Google Maps or the Chrome Browser, as follows:
Uri mapUri = Uri.parse("geo:0,0?q=London");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, mapUri);
Uri browserUri = Uri.parse("http://www.google.co.uk");
Intent browserIntent = new Intent(Intent.ACTION_VIEW, browserUri);
Firstly, do NOT specify the package to receive the intent (e.g. mapIntent.setPackage(" ("com.google.android.apps.maps”),"), doing so will mean you cannot load a 3rd party mapping component, for example.
Secondly, use the package manager to determine whether the intent will resolve before calling startActivity, as follows:
final PackageManager pm = getPackageManager();
if (mapIntent.resolveActivity(pm) != null)
startActivity(mapIntent);
else
Toast.makeText(getApplicationContext(), "No application to handle Map intent", Toast.LENGTH_LONG).show();
This way your application will fail gracefully if there is no package to handle the intent you are sending. If the intent cannot be resolved when you call startActivity then an android.content.ActivityNotFound exception will be thrown. You will need to either re-enable Chrome / Maps with a GMS Restricted profile or install an alternative browser / mapping component respectively which handles the appropriate uri scheme.
Detecting the presence of Google Play Services
In order to use any of the Google Play Services (also known as Google APIs for Android) it is first required to create an instance of the GoogleApi which has a useful method isGooglePlayServicesAvailable that returns whether or not Google Play Services can be used. Note that the GoogleApi replaces the earlier GoogleApiClient which required you to first connect() before calling any APIs. For more information on the transition from GoogleApiClient to GoogleApi please see Google’s documentation. Even using the legacy GoogleApiClient you can still determine whether or not Play Services are available by making use of the onConnected() and onConnectionFailed() callbacks.
Related to Play Services, for location you can also use the SettingsClient to determine whether or not location services are available to your application.
I have created a very simple test app to show the techniques described here, it is not intended as ‘production ready’ and is provided without any guarantees or warranty but demonstrates how to test whether Google services are available on your device. The test app shows both the GoogleApi approach (master branch) and the GoogleApiClient approach (release v0.1)
Something I learned when putting this app together, do NOT include the word ‘Google’ anywhere in the package name since doing so will cause the app to be disabled on a GMS Restricted device.
The test application will demonstrate the availability of Play Services and location under a variety of circumstances:
Configuration |
Play Services available |
Location services available |
Able to launch Maps |
Able to launch Browser |
GMS Restricted |
No |
No |
No |
No |
GMS Restricted with Browser profile |
No |
No |
No |
Yes |
GMS Restricted with Maps Profile |
Yes |
Yes |
Yes |
No |
The above table is true at the time of writing, though may change if GMS application dependencies change in the future.
Note that Google Maps has a dependency on Play Serivces and so reports available with this configuration. The Maps profile also enables the most accurate location available on the device hence why location services are also reported as available.
Recommendations
Restricted GMS is a very powerful feature and can address many, if not all, of the privacy concerns associated with moving to GMS in an enterprise deployment.
Like any feature however, it is important to understand how it works and the associated implications – not having GMS applications or services available on the device can lead to many 3rd party applications either not working or limiting their functionality in unexpected ways. If you understand what it means for applications to not have GMS services available, then apps can be developed to run without issue on Restricted GMS devices.
Darryn Campbell