#java #android #c_sharp #xamarin
Необходимо запустить приложение для андройда в режиме "Kiosk Mode". Необходимо, чтобы
пользователь не мог закрыть или свернуть приложение, а также войти в настройки устройства.
Стоит задача сделать приложение для отзывов. Работать оно будет на планшете, доступном
клиентам.
Для достижения поставленной задачи я уже сделал следующее (используется Xamarin):
Запустил приложение как лаунчер и развернул приложение на весь экран:
[Activity(Label = "App1", MainLauncher = true, Icon = "@drawable/icon",
Theme = "@android:style/Theme.Light.NoTitleBar.Fullscreen")]
[IntentFilter(new[] { Intent.ActionMain }, Categories = new[] {
Intent.CategoryHome, Intent.CategoryDefault })]
Сделал пустым обработчик события кнопки назад:
public override void OnBackPressed(){}
Сейчас пользователь может использовать панель уведомлений и кнопку домой и кнопку
назад. Доступ к кнопкам домой и назад не страшен, так как кнопка домой возвращает пользователя
к приложению, и из меню задач лаунчер (это приложение) закрыть нельзя.
Необходимо заблокировать панель уведомлений или сделать так, чтобы ее использовать
было практически невозможно (чтобы пользователь не смог зайти в настройки, выключить
Wi-fi и так далее). Есть рут права.
Использовать изоленту, бесцветный лак, ломать тачскрин и другие аппаратные способы
блокирования доступа к панели уведомлений использовать нельзя.
Дополнение 1
Использование следующего кода приводит к полному отключению экрана до перезагрузки.
Возможно, если команда для отключения только строки состояния?
Java.Lang.Process proc = Java.Lang.Runtime.GetRuntime().Exec(
new String[] { "su", "-c", "service call activity 42 s16 com.android.systemui" });
proc.Wait();
Дополнение 2
При использовании программ full!screen и Hide System Bar(Full Screen) программа не
отображается. Отображается только картинка рабочего стола и больше ничего до перезагрузки.
Планшет Prestigo multipad weze 3341 3g (PMT 3341_3G), android 5.1.1
Ответы
Ответ 1
Похоже, что вам нужeн Single-Purpose Devices. Официальная документация Set up Single-Purpose
Devices
Ещё есть статья на русском с разными хаками по ограничениям взаимодействия пользователя
с устройством Kiosk Mode приложения на Android
На Xamarin можно использовать любые нативные API, насколько мне известно. Так что
думаю с этим проблем возникнуть не должно.
Ответ 2
Kiosk mode - это не фул-скрин, а полная блокировка bottom и status bar. Тогда пользователь
действительно не сможет ничего сделать, помимо использования функционала программы
(если конечно программа не выбросит ошибку).
Мне приходилось делать такую программу, но использовалось средствами Android Studio,
а не Xamarin. Делать это можно как через функцию:
private void hideBar(){
try
{
Process proc = Runtime.getRuntime().exec(new String[]{"su","-c","service call
activity 42 s16 com.android.systemui"});
proc.waitFor();
}
catch(Exception ex)
{
Toast.makeText(getApplicationContext(), ex.getMessage(), Toast.LENGTH_LONG).show();
Log.e("ROOT ERROR", ex.getMessage());
}
}
Или через shell:
adb shell
su
pm disable com.android.systemui //(enable) чтобы включить обратно
Возможно следующие команды помогут добиться желаемого результата и с помощью Xamarin.
Из личного опыта советую создать плавающие системные кнопки управления (как минимум
"назад") которая появляется при выходе из приложения. На случай, когда приложение вылетает
или надо что-то поменять в настройках Вам не придется включать .systemui обратно.
Ответ 3
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
return true;
}
return false;
}
Может быть так?
Ответ 4
К сожалению некогда читать все ваши комментарии, но из того что прочел решил что
у вас осталась проблема только лишь в том, чтобы заблокировать выпадающую панель. Попробуйте
добавить строку:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY);
setContentView(R.layout.activity_main);
Ну а дальше читайте официальную документацию
Ответ 5
Чтобы заблокировать открытие статусбара (подобно мастеру настройки (SetupWizard))
вам необходимо с помощью рефлексии вызвать метод disable в классе android.os.StatusBarManager.
Если нужна поддержка всех андроидов то придется полазить по исходникам, так как могут
быть разные версии метода. Вроде как, говорят, что это будет генерировать SecurityException
с требованием выставить разрешения на статусбар в манифесте. И это конечно же ничего
не изменит, в логах при установке будет написано, что данное разрешение доступно только
для системных приложений.
Если есть рут права - это ничего не меняет. Впринципе, можно переносить приложение
в system/app но помимо этого приложение должно быть подписано системным сертификатом,
который почти никак не узнать. Но есть один выход: прошить устройства на CyanogenMod
(Lineage) - там сис.ключ открытый, но я не нашел никакой информации на эту тему.
Как вариант
Можно поставить на устройства Xposed Framework + модуль BusyBox, 100% в нем есть
функция блокировки статусбара (или вообще, скрытия) или какой-то другой модуль, или
напишите свой, Xposed Framework есть на гитхабе.
Еще?
Возможно, дурно, но все же. При запуске приложения переименовать system/app/SystemUI.apk
(или переместить (или поменять пермишны)) и обновлять граф.интерфейс, а при закрытии
(+ включении устройства (вдруг сядет)) восстанавливать..
+
Не знаю, можно ли. Сделайте фуллскрин-приложение и в onTouchEvent в случае если action
= MOVE (юзер смещает палец) закрывайте статусбар (метод collapsePanels (вроде) - это
можно сделать без каких-либо ограничений.
P.S Во всяком случае в UС Browser при просмотре видео если открыть статусбар то видео
ставится на паузу, значит можно ставить слушатель на выдвигание (там фуллскрин, свайп
для показа полосы шторки останавливает видео).
++
Можете вместо использования рефлексии поюзать шелл (закрыть статусбар)
input swipe 0 100 0 0
Тоесть делаем свайп по Y от 100 сверху к нулю. Можно наверное это делать в каком
то цикле (?)
Идеи кончились
Ответ 6
Убил строку состояния приложением Custom Quick Settings и командами под рутом:
settings put secure user_setup_complete 0
settings put global device_provisioned 0