Как отключить кнопку "Домой" в Android, как это делают приложения на экране блокировки?
Я знаю, что этот вопрос задают много раз, но я обнаружил, что ни одно из решений не работает. Я попробовал код, приведенный ниже...
protected void onPause() {
super.onPause();
Intent intent = new Intent(this,LockActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT |Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
Что он делает, так это то, что он выводит текущую активность снова на передний план, когда запускается домашний экран Android, но требуется почти 3-4 секунды, чтобы вернуть активность на передний план, когда запускается домашний экран.
Я использовал некоторые приложения для блокировки экрана, которые даже не запускают домашний экран при нажатии кнопки "Домой". Я хочу добиться чего-то подобного.
Я также использовал метод onUserLeavesHint, метод onKeyDown и метод onKeyDispatch, но ни один из них не работал для меня.
И, пожалуйста, не отвечайте и не комментируйте, так как невозможно отключить кнопку "Домой" в Android. Для таких ответов или комментариев я бы посоветовал вам просмотреть некоторые приложения блокировки экрана в PlayStore. Также я нашел работающее приложение на github вместе с исходным кодом. Он работал на моем телефоне, и приложение использовало disableKeyguard, но когда я делаю то же самое в своем приложении, оно не работает (disableKeyguard устарело, но я использую предупреждения @supress("deprecation")).
6 ответов
Источник - https://github.com/shaobin0604/Android-HomeKey-Locker
//Copy this class
public class HomeKeyLocker {
private OverlayDialog mOverlayDialog;
public void lock(Activity activity) {
if (mOverlayDialog == null) {
mOverlayDialog = new OverlayDialog(activity);
mOverlayDialog.show();
}
}
public void unlock() {
if (mOverlayDialog != null) {
mOverlayDialog.dismiss();
mOverlayDialog = null;
}
}
private static class OverlayDialog extends AlertDialog {
public OverlayDialog(Activity activity) {
super(activity, R.style.OverlayDialog);
WindowManager.LayoutParams params = getWindow().getAttributes();
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
params.dimAmount = 0.0F; // transparent
params.width = 0;
params.height = 0;
params.gravity = Gravity.BOTTOM;
getWindow().setAttributes(params);
getWindow().setFlags( WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, 0xffffff);
setOwnerActivity(activity);
setCancelable(false);
}
public final boolean dispatchTouchEvent(MotionEvent motionevent) {
return true;
}
protected final void onCreate(Bundle bundle) {
super.onCreate(bundle);
FrameLayout framelayout = new FrameLayout(getContext());
framelayout.setBackgroundColor(0);
setContentView(framelayout);
}
}
}
//Paste this in your activity
mHomeKeyLocker = new HomeKeyLocker();
mHomeKeyLocker.lock(this);
Вы можете использовать библиотеку shaobin0604 для этого. Это также отключит кнопку Назад. Ваша деятельность будет выглядеть так:
public class MainActivity extends Activity {
HomeKeyLocker homeKeyLocker;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
homeKeyLocker = new HomeKeyLocker();
homeKeyLocker.lock(this);
}
}
Надежный способ обеспечить безупречную функциональность экрана блокировки без полномочий root - это объединить идею вашего приложения "locker" с приложением запуска.
Простое изменение в манифесте позволит вашему приложению зарегистрироваться в качестве домашнего экрана / средства запуска, что даст вашему.apk полный контроль над кнопкой home:
<application
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="ch.arnab.simplelauncher.HomeScreen"
android:label="@string/app_name"
android:launchMode="singleTask"
android:excludeFromRecents="true"
android:screenOrientation="nosensor">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<!-- These 2 intent-filters identify a launcher: -->
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
Вытащил из этого урока
Затем у вас будет два занятия: одно для домашнего экрана, другое для экрана блокировки.
Вам нужно будет определить, когда экран выключен / включен, чтобы показать вашу активность на экране блокировки:
public class MainActivity extends Activity {
//Create a receiver for screen-on/screen-off
BroadcastReceiver mybroadcast = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
//Show lock-screen
}
else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
//Also show lock-screen, to remove flicker/delay when screen on?
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver(mybroadcast, new IntentFilter(Intent.ACTION_SCREEN_ON));
registerReceiver(mybroadcast, new IntentFilter(Intent.ACTION_SCREEN_OFF));
}
}
Вытащил из этого ответа
К вашему сведению: поскольку ваш "экран блокировки" все еще будет считаться частью вашей панели запуска, приложения смогут запускаться поверх экрана блокировки, что плохо, если: у пользователя есть доступ к ящику уведомлений, чтобы нажать на сообщения / твиты и т. д., но также могут быть полезны: возможность отвечать на входящие вызовы без разблокировки телефона.
В любом случае, ваша активность на экране блокировки должна быть отменена onPause
, проверьте, является ли пользователь "аутентифицированным", если нет, предположите, что пользователь что-то открыл и должен вернуться к экрану блокировки:
@Override
public void onPause() {
super.onPause();
if(password!=storedPassword) {
//Lockscreen activity shouldn't ever be escaped without the right password!
//Return to launcher without root!
Intent homeIntent = new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory(Intent.CATEGORY_HOME);
homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(homeIntent);
}
}
Для лучшего взаимодействия с пользователем вы должны разрешить нескольким приложениям обходить экран блокировки (например, Spotify), вы можете включить его в if
заявление выше (напр. if(password!=storedPassword||isForegroundAppSpotify)
).
Что касается загрузки приложений на домашний экран, вы можете обратиться к учебным пособиям в Google для создания своей собственной деятельности по запуску.
Комбинирование launcher+lock-screen - это самый простой способ избежать root-доступа. Возможно, вам будет проще использовать root, но вы ограничите свою клиентскую базу.
Надеюсь это поможет!
Я провел много исследований для разработки экрана блокировки и, наконец, нашел решение. Android отключил эту функцию для переопределения системных панелей, кроме кнопки "Назад". Но есть немного работы, чтобы сделать эту работу:
Понимайте и выполняйте закрепление экрана терпеливо, и вы будете успешны.
Вы можете создать приложение для управления всеми приложениями, в которых вы хотите реализовать закрепление экрана, или же вы можете внедрить закрепление экрана непосредственно в том же приложении, которое хотите закрепить.
Я собираюсь показать вам более позднюю реализацию в этой статье:
1. Во-первых, ваше приложение должно быть владельцем устройства.
Вы можете сделать это несколькими способами, и проще всего выполнить команду:
adb shell dpm set-device-owner [yourPackageName] /. [MyDeviceAdminReceiver]
Создайте получатель (MyDeviceAdminReceiver), который расширяет DeviceAdminReceiver. Вам не нужно иметь никакого кода здесь. Для получения дополнительной информации о реализации устройства владельца, перейдите по этой ссылке
http://florent-dupont.blogspot.com/2015/02/10-things-to-know-about-device-owner.html
Зарегистрируйте получателя в файле AndroidManifest.xml следующим образом:
<receiver
android:name=".MyDeviceAdminReceiver"
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" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
2. Ваш метод onCreate должен выглядеть следующим образом:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lock_screen);
ComponentName deviceAdmin = new ComponentName(this, MyDeviceAdminReceiver.class);
DevicePolicyManager mDpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
if (mDpm.isDeviceOwnerApp(getPackageName())) {
mDpm.setLockTaskPackages(deviceAdmin, new String[]{getPackageName()});
}
if (mDpm.isLockTaskPermitted(this.getPackageName()))
startLockTask();
3. Чтобы открепить экран и сделать функциональную панель навигации:
Вызовите функцию stopLockTask() в том месте кода, где вы хотите открепить. Например, в моем приложении, как только я проверяю, что пользователь ввел правильный пароль, я вызываю эту функцию:
if (userInput.length() == 4) {
if (userInput.equals(passcode)) {
userInput = "";
etxtPasscodeDisplay.setText("");
stopLockTask(); // this is what you need
unlockHomeButton(); // A method to show home screen when
passcode is correct
finishAffinity(); //kill other activities
}
Дополнительная информация, которая обычно требуется для экранов блокировки:
1. Если ваше приложение первое, что появляется после загрузки:
Для этого вам нужен сервис (StartAtBootService) и получатель (BootCompletedReceiver).
2. Если вы хотите, чтобы ваше приложение отображалось после блокировки и разблокировки экрана (кнопка питания нажата для блокировки и разблокировки):
Создайте AEScreenOnOffService, который расширяет службу, и AEScreenOnOffReceiver, который расширяет BroadcastReceiver, чтобы запускать вашу деятельность, когда экран включен.
Для получения подробной информации обо всем, что я упомянул здесь, см. http://www.sureshjoshi.com/mobile/android-kiosk-mode-without-root/
Это отличная статья, которая мне очень помогла. Отдельное спасибо автору.
Мне нужно не менее 10 репутации, чтобы разместить более двух ссылок. Поскольку я новичок в stackru, у меня недостаточно репутации, поэтому я извиняюсь за то, что не смог поделиться всеми ссылками, на которые я ссылался. Обязательно обновлю пост, как только получу доступ.
Простой ответ на ваш вопрос: вы не можете этого сделать.
Решение, которое вы упомянули, было предложено мной около четырех лет назад [Ссылка].
onUserLeavesHint, onKeyDown и onKeyDispatch никогда не будут "отключать" аппаратные ключи.
Если вы действительно хотите "обработать" кнопку "Домой", вам нужно будет сделать приложение домашним экраном. Смотрите это и это.
Если вы действительно хотите отключить аппаратный ключ, не создавая приложение домашнего экрана, вам нужно выполнить рутирование вашего устройства и удалить соответствующий файл устройства из модуля ядра. (Попробуйте на свой страх и риск!)
То, что вы могли бы сделать, это переопределить функцию home key следующим образом:
@Override public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_HOME)
{
//The Code Want to Perform.
}
});
Тогда вы сможете запретить пользователю возвращаться на домашний экран с помощью этой кнопки. Надеюсь, что это работает для вас.
РЕДАКТИРОВАТЬ: Проблема с переопределением кнопки "Домой" заключается в том, что Google рассматривает ее как дыру в безопасности, поэтому каждый раз, когда кто-то находит способ переопределить ее, Google исправляет эту "дыру".