Как отключить домашнюю кнопку в 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 невозможно. Для таких ответов или комментариев я предлагаю вам пройти через некоторые приложения Lock Screen на PlayStore. Также я нашел рабочее приложение для github по исходному коду. Он работал на моем телефоне, а приложение использовало disableKeyguard, но когда я делаю то же самое в своем приложении, оно не работает (disableKeyguard устарел, но я использую предупреждения @supress ( "устаревание" )).

Ответы

Ответ 1

source - 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);

Ответ 2

Верный способ обеспечения безупречной функциональности блокировки с помощью не-root - это объединить идею приложения "locker" с приложением для запуска.

Простое изменение манифеста позволит вашему приложению зарегистрироваться в качестве главного экрана/запуска, что даст вашему .apk полный контроль над домашней кнопкой:

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

Извлечен из этого ответа

FYI: поскольку ваш "блокирующий экран" по-прежнему будет считаться частью вашей пусковой установки в этот момент, приложения смогут запускаться поверх вашего экрана блокировки, что плохо, если: у пользователя есть доступ к ящику уведомлений нажимать на сообщения/твиты и т.д., но также может быть полезно: возможность отвечать на входящие вызовы без разблокировки телефона.

В любом случае активность блокировки экрана должна переопределяться 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 для создания вашей собственной активности запуска.

Объединение пусковой установки + блокировка экрана - самый простой способ избежать доступа root. Возможно, вам будет проще использовать root, но вы ограничите свою клиентскую базу.

Надеюсь, это поможет!

Ответ 3

Вы можете использовать shaobin0604 library для этого. Он также отключит кнопку "Назад". Вы будете выглядеть так:


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

}

код >

Ответ 4

Я провел много исследований по созданию экрана блокировки и, наконец, нашел решение. 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 репутации, чтобы разместить более двух ссылок. Поскольку я новичок в stackoverflow, у меня недостаточно репутации, поэтому я сожалею, что не могу поделиться всеми ссылками, которые я упоминал. Обязательно обновите сообщение после получения доступа.

Ответ 5

Простой ответ на ваш вопрос: вы не можете этого сделать.

Решение, которое вы упомянули, было предложено мной около четырех лет назад [Ссылка].

onUserLeavesHint, onKeyDown и onKeyDispatch никогда не будут "отключать" аппаратные ключи.

Если вы действительно хотите "обрабатывать" кнопку "Домой", вам нужно будет сделать свое приложение в качестве главного экрана. См. и .

Если вы действительно хотите отключить свой аппаратный ключ, не создавая приложение для домашнего экрана, вы должны запустить ваше устройство и удалить соответствующий файл устройства из модуля ядра. (Попробуйте на свой страх и риск!)

Ответ 6

Что вы можете сделать, это переопределить функцию домашнего ключа следующим образом:

@Override public boolean onKeyDown(int keyCode, KeyEvent event)
{
    if(keyCode == KeyEvent.KEYCODE_HOME)
    {
        //The Code Want to Perform.
    }
});

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

EDIT: Проблема с переопределением кнопки "домой" считается как дыра в безопасности Google, поэтому каждый раз, когда кто-то находит способ переопределить его, Google исправляет эту "дыру".