Building a Kiosk Application in Android 5.0 (Lollipop)

Android L introduced “Screen Pinning” API. This allows an application to temporarily restrict a user from navigating away from your activity. When Screen Pinning in enabled, it restricts a user from gaining access to notification bar on top as well as the navigation bar at the bottom. Prior to Android L, developers had to hack around in order to build a kiosk type application. Those workarounds included making the application a “default launcher”, write code to forcefully close the notification bar back up so users could not gain access to them.
In this post we will go over the new API and build a simple Kiosk application that will show an informational product webpage. Users will not be able to navigate away from the activity or gain access to notification bar.

Getting Android L
At the time of this writing Android L is still in preview. You can download and install Android L for Nexus 5/7. You can follow the steps at http://developer.android.com/preview/index.html#download. If you are new to flashing these images, please follow the flashing instructions posted here: https://developers.google.com/android/nexus/images#instructions
After you have successfully flashed your device, you can follow along with this post and try out Screen Pinning.

Building the application
Lets begin by creating a simple android project. We set the compileSdkVersion to 21 in your build.gradle file. This builds using the Android 5.0 SDK. In the Android manifest set the permission to use Internet. This will allow our application to access the Internet to load the webpage.

In the layout file, add a WebView tag. We will load information about the latest Nexus 6 device on that webview component.

To take advantage of full screen we need to set Immersive mode. We do that by setting System UI flags in the DecorView.

On “onResume”, we will call the new method “startLockTask” which was introduced as part of Android L SDK. By calling that method, it will run the activity in Screen Pinning mode. Lets start the application. You should notice that we get a popup confirming Screen Pinning. Accept it to start Screen pinning.

screen pinning

In this mode, pressing home, back or recents button does not do anything. By default pressing and holding back and recents button will get you out of screen pinning mode.

immersive mode

exit

Above mode is perfect for apps that needs to restrict users from accessing the notification or navigation bar. Business apps used to display presentation for sales consultants, or educational apps that may need to restrict students from navigating away from the activity are good examples. In the new SDK, google introduced the concept of “Device Owner”. It is a specialized type of device administrator that has additional abilities to create/remove secondary user profiles and to configure global settings. The Device owner app can run screen pinning without the user confirmation we saw above. When Device owner app runs screen pinning, it needs to call “stopLockTask()” to get out of the screen pinning mode. As of this writing, there is no simple way to make an app, “device owner” without root. According to the documentation, Device owner mode can be set via NFC but there is no specific instructions as to how it can be done. (http://developer.android.com/about/versions/android-5.0.html#DeviceOwner) To try out the capability of a device owner, you can root your device and set an app as a device owner. To do this, you would need to create a device_owner.xml file and place it in /data/system folder. You can do this by following the steps below on a rooted device: (You can finds steps to root Nexus 7 with Android L on the internet)
Create a device_owner.xml, copy it over to /data/system Example device_owner.xml

cp /sdcard/device_owner.xml /data/system
chown system:system device_owner.xml
(App with the package name described in device_owner.xml must be present on the device before you copy the xml to it)
Lets modify our application to request device administrator access. To do so we will need to create a receiver class that extends DeviceAdminReceiver class. We will define an empty implementation as we don’t need to do anything specific as an administrator, except for being an administrator.

Define the receiver in the AndroidManifest.xml file:

After that is defined, in our activity we can request to be an “Administrator” if it isn’t already.

In “provisionOwner()” method, we request to be device administrator. We then enable the application to call startLockTask. When our modified application starts screen pinning, the only way to get out of that mode is by calling “stopLockTask()”. Lets do that when the back button is pressed. (You can make it so the user needs to enter a pin code etc before screen pinning is disabled, for this demo we will call it when user presses the back button)

If you run the app now, app will automatically go into screen pinning mode. (Notice no confirmation dialog is shown) When you hit back would get you out of the screen pinning.

Admin Confirmation

admin

You can find the source of the sample at https://github.com/manijshrestha/LollipopKiosk

About the Author

Object Partners profile.

One thought on “Building a Kiosk Application in Android 5.0 (Lollipop)

  1. Ole says:

    There seems to be a screen pinning unlock feature, have you been able to make that work?

  2. Manuel Michel says:

    Thank you for that great tutorial. I’m fighting to get a secure kiosk app on a nexus 9 for one week now. i downloaded your example and it works well. i rooted the device and and copied the device_owner.xml in /data/system/ but the app still get’s no root (I’m still asked to confirm pinning and get the toast messages how to unlock). Do you have an idea what’s I do wrong?

    1. Manuel Michel says:

      The kiosk app is listed as device admin and got rights for lock screen and for deactivate keyguard. But the app still asks for permission to pin the screen and shows the toast messages how to unlock the screen.

  3. Manuel Michel says:

    just found the missing part – you have to change ownership of device_owner.xml

    – cd /data/system/
    – chown system:system device_owner.xml
    – reboot

    (http://stackoverflow.com/questions/21183328/how-to-make-my-app-a-device-owner)

  4. Joby George says:

    If you have Samsung device try this free app, no root
    https://play.google.com/store/apps/details?id=com.ospolice.kiosktabbrowser&hl=en

  5. workpanda says:

    thanks for your post.

    I have one question.
    I have already implemented the code as admin, but I want to lock screen without any confirm.

    any method?

    Thanks.

  6. hayden says:

    thanks very much for this guide, and even putting up the code on github! its a great way to kiosk the device and it took me a few days to realise this great feature of lollipod (pinning), as all the kiosk apps on the play store dont work anywhere near as smoothly and the cost a fortune with plenty having on going subscriptions or per device fees….

    one thing that got me stuck is that you need to reboot after creating the device_owner.xml file for it to take effect.

    also reading here it may be possible to do this without root, though i have not tried: http://stackoverflow.com/questions/21183328/how-to-make-my-app-a-device-owner

  7. bikramjit kaur says:

    Good Article,
    Also, Check device lockdown solution at https://ems.devicemax.com/

  8. fcafra says:

    if i want, when the screen is pinning, launch an instance of chrome…. i got the same error E/ActivityManager: startActivityUnchecked: Attempt to violate Lock Task Mode… someone can help me ?

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Blog Posts
Android Development for iOS Developers
Android development has greatly improved since the early days. Maybe you tried it out when Android development was done in Eclipse, emulators were slow and buggy, and Java was the required language. Things have changed […]
Add a custom object to your Liquibase diff
Adding a custom object to your liquibase diff is a pretty simple two step process. Create an implementation of DatabaseObject Create an implementation of SnapshotGenerator In my case I wanted to add tracking of Stored […]
Keeping Secrets Out of Terraform State
There are many instances where you will want to create resources via Terraform with secrets that you just don’t want anyone to see. These could be IAM credentials, certificates, RDS DB credentials, etc. One problem […]
Validating Terraform Plans using Open Policy Agent
When developing infrastructure as code using terraform, it can be difficult to test and validate changes without executing the code against a real environment. The feedback loop between writing a line of code and understanding […]