Reputation: 321
I am developing an Android application which is run on tablets for a bar in Tokyo.
Everything is going well but I have got an issue that while customer using the tablet they are able to quit my application as well as reboot the device by pressing hard button on it and my client doesn't allow them to do that and ask me to configure my application in order to prevent that case.
I have researched a lots but seems like there is no clear answer for this. Any suggestion would be appreciated, thanks
Upvotes: 0
Views: 815
Reputation: 966
You want to setup a Dedicated Device. As @DevWithZachary mentions, this used to be called 'kiosk mode'.
Here is how I implemented it for my device:
Add a device admin receiver to your manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.yourapp">
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
<!-- other stuff... -->
<receiver
android:name=".YourDeviceAdminReceiver"
android:description="@string/app_name"
android:exported="true"
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"/>
<action android:name="android.app.action.PROFILE_PROVISIONING_COMPLETE"/>
</intent-filter>
</receiver>
</application>
Implement a DeviceAdminReceiver:
package com.example.yourapp
import android.app.admin.DeviceAdminReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import android.os.UserManager
import android.provider.Settings
import android.util.Log
class YourDeviceAdminReceiver : DeviceAdminReceiver() {
val tag = "YourDeviceAdminReceiver"
override fun onEnabled(context: Context, intent: Intent) {
super.onEnabled(context, intent)
lockDownApp(context)
Log.i(tag, "*** Device Admin Enabled ***")
}
private fun lockDownApp(context: Context) {
val devicePolicyManager = getManager(context)
val adminComponentName = ComponentName(context.applicationContext, this::class.java.name)
devicePolicyManager.addUserRestriction(adminComponentName, UserManager.DISALLOW_SAFE_BOOT)
devicePolicyManager.addUserRestriction(adminComponentName, UserManager.DISALLOW_FACTORY_RESET)
devicePolicyManager.addUserRestriction(adminComponentName, UserManager.DISALLOW_ADD_USER)
devicePolicyManager.addUserRestriction(adminComponentName, UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS)
// DISALLOW_MOUNT_PHYSICAL_MEDIA prevents USB or other storage devices from being mounted on the generator.
// DISALLOW_USB_FILE_TRANSFER prevents the generator from being either the USB host or device when transferring files.
// Usually, DISALLOW_USB_FILE_TRANSFER can be considered a superset that includes DISALLOW_MOUNT_PHYSICAL_MEDIA.
devicePolicyManager.addUserRestriction(adminComponentName, UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA)
devicePolicyManager.addUserRestriction(adminComponentName, UserManager.DISALLOW_USB_FILE_TRANSFER)
devicePolicyManager.setKeyguardDisabled(adminComponentName, true)
devicePolicyManager.setStatusBarDisabled(adminComponentName, true)
devicePolicyManager.setGlobalSetting(adminComponentName, Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
BatteryManager.BATTERY_PLUGGED_AC.toString())
devicePolicyManager.setLockTaskPackages(adminComponentName, arrayOf(context.packageName))
// set activity as home intent receiver so that it is started on reboot
val intentFilter = IntentFilter(Intent.ACTION_MAIN)
intentFilter.addCategory(Intent.CATEGORY_HOME)
intentFilter.addCategory(Intent.CATEGORY_DEFAULT)
devicePolicyManager.addPersistentPreferredActivity(adminComponentName, intentFilter,
ComponentName(context.packageName, YourActivity::class.java.name)
)
}
}
Once your app is loaded, set it as device owner from the shell:
dpm set-device-owner com.example.yourapp/.YourDeviceAdminReceiver
Upvotes: 1