In Ackee we, Android developers, are mostly dealing with Play Store-oriented apps, aimed at the general public. Shared economy, food and grocery delivery, car management, education, job finding, advertising: apps in these areas are usually easily discoverable and aren’t limited to specific organizations, devices or accounts. But sometimes, our client’s requirement is to develop an internal app for their corporation with different access levels, limitations, remote configuration and strong emphasis on security. Ticketing, logistics, courier navigation are some of the use cases for enterprise apps closed to the public.
Meeting such requirements isn’t so much about the app development itself but more about MDM (Mobile device management). There is a lot of different MDM (Mobile device management) solutions on the market and the choice depends on a particular case and on a corporation infrastructure. But in this post, I will talk about Android Management API, simple and scalable solution from Google, which we chose for the ticketing app that we have developed recently.
Our first requirement was to restrict our client devices to one app only — the ticketing app we’ve developed (to make it either locked to the device or to make it work in kiosk mode with minimum functionality). The second requirement was the ability to make changes in the device configurations remotely without touching the device. And the last one was to provide automatic installation and updates of the app on all enterprise devices.
- Made by Android (Google): smooth integration with Android SDK, no need for third-party software
- Simple but scalable: really easy to get it going with basic configuration, but new functions are easy to be added in the future
- Support of almost all Android devices with version 6.0+
- No need for custom backend solution (but may be integrated)
Now let’s take a look at what needs to be done to make our app run on dedicated device.
Android supports two modes for dedicated devices: more strict lock task mode (status bar and system buttons are hidden, the app completely blocks the screen) and app pinning mode (temporary pins the app to home screen, the user may leave the mode).
For our use case, we chose to completely lock the screen. The only thing the developer has to do to enable lock task mode is to either start it from code for specific activity, or set the lockTaskMode attribute to “if_whitelisted” or “always” in AndroidManifest.xml file.
- Create an enterprise. An enterprise is a resource that represents an organization. To create one all we need is a valid Gmail account not associated with any enterprise. For example, if the account is a part of another organization, we won’t be able to do it. An enterprise consists of policies and devices.
- Create a policy. A policy is a set of rules that defines the behavior of groups of devices that are bound to your enterprise. The changes in policy that are made via Android Management API are applied immediately to linked devices without any manual manipulations.
- Enroll a device. The last part is to bind our device to created policy. The easier way to do it is to create an enrollment token linked to a particular policy and your enterprise. To provision a device, it should be reset to factory settings. Then the created enrollment token may be scanned as a QR code from QR code mode. To enter QR code mode, we need to tap the same spot on the welcome screen six times if you have Android 7.0+ or to enter afw#setup into sign-in field. And voilà, our device is now an enterprise device bound to particular policy.
The easier way to complete all these steps is to go through interactive quickstart guide provided by Google. Otherwise we have to call all these REST API commands manually or via APIs Explorer. Another option for bigger projects is to link Android Management API to enterprise backend. It allows even finer customizations and integrations with organization processes. To call the API from server, the service account is needed.
The simple policy example may be seen below.
After the device enrollment we have it linked with our policy. But even if we have our application allowed in the policy (cz.ackee.example in the example above), we still have to install it on our device somehow. Of course, we could have done it manually or via third party distribution channels but then we would have to do it for each device separately and handle each new update manually. This wasn’t an option for us. But on the other hand, we didn’t want our application to be freely accessible and visible in Play Store.
The solution is really simple. We may publish our app to Google Play as a private app limited to our organization only. Then, if the device is linked to our organization, the app will be accessible through managed Google Play.
To do it we have to upload the app to Google Play and then, in Store Presence -> Pricing & Distribution -> User programs -> Managed Google Play,check Turn on advanced managed Google Play features -> Privately target this app to a list of organizations and choose your organization. If the organization account and Play Store account is the same, the option will be presented, otherwise, we have to add the ID of the organization.
We may even test it in Alpha/Beta channels. All we have to do is to add our organization in Manage testers -> Organizations.
Now, if we have our application installType set to FORCE_INSTALLED in our policy, the application will be installed and updated automatically.
It is really simple to make it work with the easiest configuration. On the other hand, as you may see, policies allow to control device configuration precisely and even change its purpose remotely in handful of clicks (we may change locked one-app device into multi-app kiosk if we want to).
The API is well documented, but, unfortunately, there isn’t much examples and best practices on the matter yet. Moreover, Google has couple similar products (Google Play EMM API for example), and it’s not hard to getbecome confused while choosing your solution and searching the web for information.