DEV Community

Davran Khasanov
Davran Khasanov

Posted on

Разработка Android Kiosk приложения

Всем привет это моя первая публикация. И первый опыт написания статей по разработке.

Давайте начнем с небольшого знакомства.
Меня зовут Давран, я андройд разработчик с 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"
)
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

3 - Основную работу будет делать нам DevicePolicyManager
и первая магическая строчка это

dpm.setLockTaskPackages(admin, arrayOf(WHITE_LIST_PACKAGES))

Enter fullscreen mode Exit fullscreen mode

данная команда отдает системе белый список приложений которые можно будет открыть в режиме киоска

вторая магичечская строчка

dpm.setLockTaskFeatures(
admin,
DevicePolicyManager.LOCK_TASK_FEATURE_NONE
)
Enter fullscreen mode Exit fullscreen mode

данная команда отключает все настраиваемые элементы с 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
        )
Enter fullscreen mode Exit fullscreen mode

и на выходе у нас получаются две функции

 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
        )
    }

Enter fullscreen mode Exit fullscreen mode
fun exitAdminMode() {
        if (!isDeviceOwner()) return

        dpm.setLockTaskFeatures(admin, DevicePolicyManager.LOCK_TASK_FEATURE_NONE)
    }
Enter fullscreen mode Exit fullscreen mode

есть еще вспомогательные

fun canStartLockTask(): Boolean {
        if (!isDeviceOwner()) return false
        if (!dpm.isLockTaskPermitted(context.packageName)) return false
        return !keyguard.isDeviceLocked
    }
Enter fullscreen mode Exit fullscreen mode

isLockTaskPermitted - это проверка на на наличие прав у приложение переходить в режим киоска.

fun isDeviceOwner(): Boolean = dpm.isDeviceOwnerApp(context.packageName)
Enter fullscreen mode Exit fullscreen mode

Проверка на наличие прав админа устройства

Так же у DevicePolicyManager есть функция addRestriction
которая позволяет выключить ту или иную вещь на девайсе:

  • Сейф бут
  • сброс заводских настроек
  • подключение внешних юсб
  • добавление аккаунтов на устройство
  • настройки блютуза и еще много чего.

переменная admin - это DeviceAdminReceiver
который помогает системе определить куда вести все эти настройки в действие.

*Установка приложения *

На этом создание контролера завершено, далее нам нужно сбросить девайс до заводских настроек, включить USB debugging, разрешить установку через USB и не создавать и не авторизовываться ни под каким аккаунтом на устройстве.

Мы ставим наше приложение на устройство, открываем терминал и выполняем команду

Установка девайс овнера

adb shell dpm set-device-owner "your.package.name/com.example.AdminReceiver
Enter fullscreen mode Exit fullscreen mode

Удаление девайс овнера

adb shell dpm remove-active-admin "your.package.name/com.example.AdminReceiver
Enter fullscreen mode Exit fullscreen mode

и указываем путь до нашего AdminReceiver(это DeviceAdminReceiver который мы создали в KioskController)

class AdminReceiver : DeviceAdminReceiver()
Enter fullscreen mode Exit fullscreen mode

На этом нам осталось лишь установить наше приложение как домашний лаунчер устройства и поздравляю вас, вы теперь админ устройства в режиме киоска.

P.S - я использовал SingleActivity архитектуру для того чтобы добавить скрытую кнопку которая позволит открыть AdminScreen
ввести пин код админа и выйти с режима киоска для конфигурации планшета.

Если хотите могу эту часть тоже описать.

Top comments (0)