# Kiosk
Application demonstrates basic usage of Android Lock Task mode for creating Kiosk app
### Usage
1. Make factory reset
2. Skip adding google account
3. Install apk
```bash
$ adb install path/to/kiosk.apk
```
4. Set device owner
```bash
$ adb shell dpm set-device-owner pl.mrugacz95.kiosk/.MyDeviceAdminReceiver
```
### Screenshots
<img src="https://user-images.githubusercontent.com/12548284/37874490-775d37d6-3030-11e8-897c-e5d930a3d44f.png" width="292" height="519" /> <img src="https://user-images.githubusercontent.com/12548284/37874485-6c9b6a70-3030-11e8-8ea4-75ec19f10a59.png" width="292" height="519" />
# Article
### How to turn your Android application into a kiosk
Nowadays, we find kiosk devices in more places than ever before. We use these at the train station, tourist information centers, shops, museums, hotels, post offices, and more. They usually provide an app giving useful information, the ability for communication, commerce, entertainment marketing or education. These are often equipped with a colorful touchscreen to facilitate user interaction.
Android devices can be turned into kiosks by configuring them as a COSU app (Corporate Owned Single Use application) or a Single-Use device. In this article, I will explain how to enable kiosk mode and build a simple application for this purpose.
### COSU / Kiosk mode
To create a secure kiosk mode we have to disable some Android features. It is important to capture the user within one application, without a way to close it or run a different app. To achieve this we need to satisfy these requirements:
* A single application – the user shouldn't be able to exit our application and access any settings or private data
* Hidden Home and Recent Apps buttons – these buttons are the most common way to navigate in Android
* Disabled status bar – it is possible to navigate to settings or use a notification to change context
* Running with device's boot – device should be ready to use immediately after powering on
* Turning off incoming calls – interaction with the application shouldn't be interrupted
* Blocking all paths to settings – there are many ways to access settings and we should consider them all (for example it is possible to go to language settings through the keyboard)
* The device should be always awake – the user will not have to search for the power button,
* The app is in fullscreen mode
Starting from Android 5.0 we have the opportunity to easily create a kiosk application in Android. Let's see how we can achieve it.
### Screen Pinning
Screen Pinning is a feature which allows you to show only one application until unpinning. It can be used when giving your phone to children or other people without risk of leaking personal information. On every smartphone with system version starting from Android 5.0 Lollipop, you can enable this feature manually in `Settings → Security → Screen pinning → On`. You can also specify if the device should show your lock screen after unpinning.
After that, when clicking the Recent Apps button you will see a blue pin icon which allows you to pin the application to your screen. To exit the pinned screen you have to hold recent and home buttons down for a while. With screen pinned enabled, the system behaviour has changed:
* the status bar is blank and status icons are hidden,
* Home and Recent apps buttons are disabled, and
* other apps cannot launch new activities.
![image](https://github.com/mrugacz95/kiosk/assets/12548284/cda3e65b-8743-421f-90e9-cd958558f45a)
The pinned application has a visible but disabled home and recent button and it's still possible to change context. We will need more privileges to lock the user in our kiosk and pin the screen without confirmation.
### Device Admin
It is possible to make our application the administrator of the device, which will enable more possibilities to adjust system settings and manage applications. You can find your current privileged apps in `Settings → Security → Device admin apps`. After opening the admin details you can see the permissions each app are using. Most permissions are related with wiping device data and blocking the screen if you lose your phone.
If our application is a device admin, it can pin screen without confirmation. Home and Recent apps buttons are also hidden, so exiting from the application is not possible manually and only available from the code.
### LockTask mode
Our Kiosk application will mostly be based on a class inheriting from DeviceAdminReceiver and ComponentName. First, we have to tell the system that our app is pretending to become device administrator. We can do it by adding a receiver in `AndroidManifest.xml` containing metadata with name `android.app.device_admin`:
```xml
<application
...
android:testOnly="true">
<receiver
android:name=".MyDeviceAdminReceiver"
android:description="@string/admin_description"
android:label="@string/app_name"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/device_admin_receiver" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
</intent-filter>
</receiver>
</application>
```
Here we can provide the same basic information about our admin like name and description, which will be displayed in device's settings. Also take note of `testOnly="true"`, which will allow us to remove the admin without complications, which will be discussed in next section.
As you can see there is also a path to an xml file containing some information about policies which the admin app will use. To do this we have to create a new directory in `res` with name `xml`.
![image](https://github.com/mrugacz95/kiosk/assets/12548284/25e59905-a99d-4184-9e64-86b1db08728f)
```xml
<?xml version="1.0" encoding="utf-8"?>
<device-admin>
<uses-policies>
<limit-password />
<watch-login />
<reset-password />
<force-lock />
<wipe-data />
<expire-password />
<encrypted-storage />
<disable-camera />
<disable-keyguard-features />
</uses-policies>
</device-admin>
```
And finally, we can add a class inheriting from `DeviceAdminReceiver`. This class can also catch intents related to administrator settings and react to them:
```kotlin
// ...
class MyDeviceAdminReceiver : DeviceAdminReceiver() {
companion object {
fun getComponentName(context: Context): ComponentName {
return ComponentName(context.applicationContext, MyDeviceAdminReceiver::class.java)
}
}
}
```
From this point, we should install our application, but enabling admin is only possible on devices which don't have any users added. So before we install app we have to wipe device/factory reset if any Google accounts have been added:
* Wipe/Factory reset device
* Do not add Google account on the first start, just skip it
* Install our application with Android Studio or command line: adb install path/to/kiosk.apk
* Set device admin:
```shell
adb shell dpm set-device-owner pl.mrugacz95.kiosk/.MyDeviceAdminReceiver
```
If everything has gone well we should be able to see our application in the list of device's administrators in `Settings → Security → Device admin apps`.
We can also check if our application is device admin programmatically:
```kotlin
//...
class MainActivity : AppCompatActivity() {
private lateinit var mAdminComponentName: ComponentName
private lateinit var mDevicePolicyManager: DevicePolicyManager
override fun onCreate(savedInstanceState: Bundle?) {
...
mAdminComponentName = MyDeviceAdminReceiver.getComponentName(this)
mDevicePolicyManager = getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
if (mDevicePolicyManager.isDeviceOwnerApp(packag