Всем привет это моя первая публикация. И первый опыт написания статей по разработке.
Давайте начнем с небольшого знакомства.
Меня зовут Давран, я андройд разработчик с 8 летнем стажем разработки мобильных приложений разного спектра.
Мой опыт работы:
Сегодня я хотел начать свое повествование с темы Android Kiosk.
На первый взгляд kiosk приложение на Android - это что то простое: нужно просто "залочить" пользователя внутри одного экрана.
На практике все оказалось немного сложнее.
В рамках нашего проекта Pai, я занимался разработкой приложения под планшет, а так же написанием лаунчера(как в итоге оказалось не совсем лаунчером)
*Что такое киоск *
Kiosk-приложение - это приложение с ограниченным доступом в котором пользователь не может выйти за пределы одного приложения.
Такие решения используется в терминалах, POS системах инфокиосках и устройствах самообслуживания.
Требования
На старте требования казались простыми, у меня был небольшой опыт написания лаунчера под android, и я думал что этих знаний и каких нибудь pet проектов на гитхабе хватит для решения задачи.
Но у меня было много вопросов которые направили меня на поиск документации для этой области(ссылка)
Итого нам нужно чтобы:
- Пользователь не смог выйти из приложения
- Приложение должно запускаться автоматически при включении устройства
- Нельзя давать доступ к системным настройкам и UI
Реализация
Все что мне потребовалось это немного документации,
пару снипетов кода.
За основу решения были взяты Device Owner и Lock Task Mode.
Ну что же, теперь перейдем непосредственно к коду и реализации...
Kiosk Controller
Первым делом нам предстоит ознакомиться с DevicePolicyManager API
если в двух словах то это API для администратора устройства которое позволяет нам много вещей(управление приложениями, управление настройками девайса и прочие вещи)
но для этого нам нужно одно из двух, либо нужные пермишины либо же админ права(это не есть рут устройства)
Дальше нам предстоит ознакомиться с KeyguardManager API
это API нужно нам для работы с лок скрином девайса а точнее для прослушивание его стейтов.
И так же нам нужно создать DeviceAdminReceiver для получения установленных настроек в наше приложение
1 - Нам нужно создать white list приложений которые можно будет запускать в режиме киоска поэтому мы создадим массив названия пакетов:
private val WHITE_LIST_PACKAGES = arrayOf(
"your.package.name",
"dev.firebase.appdistribution",
"com.android.settings"
)
2 - Мы создаем класс KioskController и создаем ссылки на системные сервисы
private val dpm = context.getSystemService(DevicePolicyManager::class.java)
private val keyguard = context.getSystemService(KeyguardManager::class.java)
private val admin = ComponentName(context, AdminReceiver::class.java)
3 - Основную работу будет делать нам DevicePolicyManager
и первая магическая строчка это
dpm.setLockTaskPackages(admin, arrayOf(WHITE_LIST_PACKAGES))
данная команда отдает системе белый список приложений которые можно будет открыть в режиме киоска
вторая магичечская строчка
dpm.setLockTaskFeatures(
admin,
DevicePolicyManager.LOCK_TASK_FEATURE_NONE
)
данная команда отключает все настраиваемые элементы с UI в режиме киоска(статус бар,навигационный бар, одним словом у вас в киоск режиме отключается весь внешний UI системы)
из минусов я нашел только вновь кривой API, так как флаг
DevicePolicyManager.LOCK_TASK_FEATURE_NONE выключает все
но нет флажка включить все, поэтому придется использовать комбинацию флажков чтобы вернуться с режима киоска
dpm.setLockTaskFeatures(
admin,
DevicePolicyManager.LOCK_TASK_FEATURE_HOME or
DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW or
DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS or
DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS
)
и на выходе у нас получаются две функции
fun enterAdminMode() {
if (!isDeviceOwner()) return
dpm.setLockTaskFeatures(
admin,
DevicePolicyManager.LOCK_TASK_FEATURE_HOME or
DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW or
DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS or
DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS
)
}
fun exitAdminMode() {
if (!isDeviceOwner()) return
dpm.setLockTaskFeatures(admin, DevicePolicyManager.LOCK_TASK_FEATURE_NONE)
}
есть еще вспомогательные
fun canStartLockTask(): Boolean {
if (!isDeviceOwner()) return false
if (!dpm.isLockTaskPermitted(context.packageName)) return false
return !keyguard.isDeviceLocked
}
isLockTaskPermitted - это проверка на на наличие прав у приложение переходить в режим киоска.
fun isDeviceOwner(): Boolean = dpm.isDeviceOwnerApp(context.packageName)
Проверка на наличие прав админа устройства
Так же у DevicePolicyManager есть функция addRestriction
которая позволяет выключить ту или иную вещь на девайсе:
- Сейф бут
- сброс заводских настроек
- подключение внешних юсб
- добавление аккаунтов на устройство
- настройки блютуза и еще много чего.
переменная admin - это DeviceAdminReceiver
который помогает системе определить куда вести все эти настройки в действие.
*Установка приложения *
На этом создание контролера завершено, далее нам нужно сбросить девайс до заводских настроек, включить USB debugging, разрешить установку через USB и не создавать и не авторизовываться ни под каким аккаунтом на устройстве.
Мы ставим наше приложение на устройство, открываем терминал и выполняем команду
Установка девайс овнера
adb shell dpm set-device-owner "your.package.name/com.example.AdminReceiver
Удаление девайс овнера
adb shell dpm remove-active-admin "your.package.name/com.example.AdminReceiver
и указываем путь до нашего AdminReceiver(это DeviceAdminReceiver который мы создали в KioskController)
class AdminReceiver : DeviceAdminReceiver()
На этом нам осталось лишь установить наше приложение как домашний лаунчер устройства и поздравляю вас, вы теперь админ устройства в режиме киоска.
P.S - я использовал SingleActivity архитектуру для того чтобы добавить скрытую кнопку которая позволит открыть AdminScreen
ввести пин код админа и выйти с режима киоска для конфигурации планшета.
Если хотите могу эту часть тоже описать.

Top comments (0)