Android перехватить кнопку недавних приложений

У меня есть приложение, предназначенное для детей, и я не хочу, чтобы они могли нажимать кнопку "Недавние приложения" (ту, которая выглядит как два прямоугольника друг над другом). Я забочусь о захвате кнопки "Назад" и кнопки "Домой", и я много раз искал и читал о попытке перехватить кнопку "Последние приложения", но большинство говорят, что вы не можете или то, как они это делают, очень сомнительно.

Приложение "Детское место" открывает окно с надписью "Действие не разрешено" и перенаправляет вас на главный экран, если вы нажимаете кнопку "Последние приложения", это работает, даже если вы находитесь в другом приложении, так как они это делают?

Любые предложения, советы будут оценены.

Благодарю.

5 ответов

После многих поисков и кодирования лучшее решение, которое я нашел, состоит в следующем:

   @Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);

    if (!hasFocus) {
        windowCloseHandler.postDelayed(windowCloserRunnable, 0);
    }
}

private void toggleRecents() {
    Intent closeRecents = new Intent("com.android.systemui.recent.action.TOGGLE_RECENTS");
    closeRecents.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
    ComponentName recents = new ComponentName("com.android.systemui", "com.android.systemui.recent.RecentsActivity");
    closeRecents.setComponent(recents);
    this.startActivity(closeRecents);
}

private Handler windowCloseHandler = new Handler();
private Runnable windowCloserRunnable = new Runnable() {
    @Override
    public void run() {
        ActivityManager am = (ActivityManager)getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
        ComponentName cn = am.getRunningTasks(1).get(0).topActivity;

        if (cn != null && cn.getClassName().equals("com.android.systemui.recent.RecentsActivity")) {
            toggleRecents();
        }
    }
}

Это требует, чтобы вы использовали <uses-permission android:name="android.permission.GET_TASKS" />

При использовании этого подхода, когда пользователь нажимает кнопку недавних приложений, это приведет к тому, что ваша активность пройдет жизненный цикл активности следующим образом: onPause -> onWindowFocusChanged -> onResume.

Для пользователя поведение выглядит так, что нажатие на кнопку недавних приложений не имеет ответа. ПРИМЕЧАНИЕ: я обнаружил, что если вы быстро нажмете кнопку недавних приложений, она будет отображаться в течение короткого времени.

Это не лучшее решение, но это удар. Если у вас есть лучшее решение, пожалуйста, поделитесь.

Лучший способ, который я нашел, это сделать это:

public class BaseActivity extends Activity {
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);

            Log.d("Focus debug", "Focus changed !");

        if(!hasFocus) {
            Log.d("Focus debug", "Lost focus !");

            Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
            sendBroadcast(closeDialog);
        }
    }
}// all credit goes here: http://www.juliencavandoli.com/how-to-disable-recent-apps-dialog-on-long-press-home-button/

Это не мой собственный код, но он просто скрывает список последних приложений.

В принятом ответе вы используете ClassName только для Android 4.2 - 4.4. Он не будет работать на 5.0 и выше или Android 4.1.

Вот список ClassNames для основных версий Android:

  • Android 4.1: "com.android.internal.policy.impl.RecentApplicationsDialog"
  • Android 4.2 - 4.4: "com.android.systemui.recent.RecentsActivity"
  • Android 5.0 - 7.1: "com.android.systemui.recents.RecentsActivity" (добавлено письмо "s")

Лучшее решение для вас будет использовать Accessibility Service. Override onAccessibilityEvent() метод, отфильтруйте перечисленные выше ClassNames и сделайте что-нибудь, когда обнаружите это событие. Например, смоделируйте нажатие кнопки "Домой". Вы можете сделать это, выполнив глобальное действие в Accessibility Service.

Если вы заинтересованы в отключении всех системных кнопок, возможно, вам будет предложено полностью убить системную панель, см. Простой способ скрыть системную панель на Android ICS.

Спасибо esse за решение для более высокого SDK! Я скучаю по этому.

Но в моем случае мне нужно дублировать вызов (или эффект нестабилен)

        if (SDK>15){
            windowCloseHandler.postDelayed(windowCloserRunnable, 10);
            windowCloseHandler.postDelayed(windowCloserRunnable, 300);
        }
Другие вопросы по тегам