Как отключить кнопку "Домой" в 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 исправляет эту "дыру".

Другие вопросы по тегам