Многие из нас каждый день трудятся на определёнными приложениями, создают что-то своё или выполняют требования нерадивого заказчика. Одним из таких требований может быть что-то вроде: «Хочу что бы из приложения нельзя было выйти, не хочу чтобы можно было делать что-то ещё, кроме как находится в моём приложений». В этом топике хочу поделиться мыслями, как же такое сделать.
Первое к чему мы приходим, что узнаём о новом типе приложений — Kiosk Mode — особый тип приложений, обычно работающие на устройствах в публичных местах. В таких приложениях функционал, к которому пользователь может иметь доступ ограничен самим приложением. Доступ к системе или каким-либо настройкам недопустим. Из таких приложений нельзя выйти. И так как мы здесь говорим об Андроиде, то, к большому сожалению, их API не предоставляет никаких возможностей для создания такого типа приложений. Попытаемся же разобраться, что со всем этим мы можем сделать и как хоть немного угодить нашему заказчику.
Хардварные кнопки и разъёмы
Каждое устройство предоставляем нам определённым набор кнопок и различных различных разьёмов, таких как USB, питание и т.к. В этом случае, как разработчики, мы поделать особо ничего не можем. Придётся при размещении предусмотреть конструкцию, которая бы полностью блокировала возможность использования такие вещей.
Панель с виртуальными кнопками
Начиная с версии Андроид 3.0 нам предлагают некоторую альтернативу хардварным кнопкам, такую как панель в нижней части экрана. Сюда входят кнопки «Назад», «Домой», «Опции», статус батареи и прочее.
Но для нашего приложения данная панель может очень мешать, так как позволяет выйти из приложения, войти в настройки системы и прочее, что может нарушить необходимый ход работы. Но есть один способ исчезнуть эту панель. Всё что будет описано здесь и далее, требует root прав на вашем устройстве.
И так, нам будет необходимо выполнит простую команду:
service call activity 79 s16 com.android.systemui
Данную команду может выполнить либо через adb, либо же напрямую из приложения:
Runtime.getRuntime().exec(new String[]{"su","-c","service call activity 79 s16 com.android.systemui"});
Это заставит враждебную для нас панель уйти с наших глаз. Но если вдруг эта панель будет нам нужна то вернуть её можно также просто командой:
am startservice -n com.android.systemui/.SystemUIService
Или же:
Runtime.getRuntime().exec(new String[]{"am","startservice","-n","com.android.systemui/.SystemUIService"});
Данное решение успешно работало на Андроид 3.0. Как обстоят дела с 4.0 пока сказать не могу.
Кнопки Home и Back
Если по каким-то причинам панель нужна, но нужно изменить поведение кнопок, то вот один рецепт. Начнём с простого, кнопки Back. Здесь всё легко, переопределяем метод:
@Override
public void onBackPressed() {
//Наше поведение...
}
Теперь сложнее, кнопка Home. Google предусмотрительно отнёсся к этой кнопке, так как это единственный способ покинуть приложение и вернуться на главный экран, но для нас это беда, как раз именно это нам и не нужно. Что мы можем сделать:
- Нам необходимо добавить в AndroidManifest необходимые настройки для нашей стартовой активити:
<intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.HOME" /> <category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter>
Это даст нам следующее, при нажатии на Home будет всплывать диалог:
Уже неплохо, но как сделать чтобы этот диалог не появлялся, а открывалось наше приложение.
- Мы можем выбрать галочку, перезагрузить девайс и наше приложение будет запускаться по умолчанию, но это не тру вей, мы можем также легко снять эту галку в настройках системы. Пойдём по другому пути, мы найдём лаунечер в недрах операционной системы и просто переименуем его и/или отправим в другое место:
mv /путь/Laucher.apk /путь2/LaucherOld.apk
Всё, на этом основное приложение на устройстве одно — наше. Больше никакого всплывающего диалогов. Если же нужно иметь доступ к Launcher'у, то либо возвращаем его назад, либо создаём секретное меню и запускаем Laucnher оттуда куда мы его перенесли.
Проблемы
К сожалению, не всё так радужно как кажется. Не все вопросы решены до конца. К примеру, посмотрим на стандартную клавиатуру:
В нижнем левом углу имеется маленькая кнопочка, которая позволяет перейти к настройкам клавиатуры, что не есть хорошо:
Решение — создать полностью свою клавиатуру, благо API это позволяет. Но решение слишком муторное, ради одной маленькой кнопочки.
Различный системные диалоги
Во время работы нашего приложения могут всплывать различные системные алерты и уведомления, наподобие низкого заряда батарей или уведомления об обновлении системы. Некоторые из них могут иметь доступ к системным настройкам.
К сожалению, мне не удалось выяснить как запретить показ таких диалогов. Если первый диалог можно выключить в настройках, то со вторым хуже, из него мы можем напрямую попасть в сами настройки. Решение — сделать так же как мы поступили с Launcher.apk — перенести или переименовать приложение настроек.
Заключение
В этой статье я постарался описать известные мне методы для создания Kiosk mode приложений. Если у хабрасообщества есть ещё какие-либо методы, то было бы здорово ими поделиться. Спасибо.
Автор: agent10