Слушатель кнопки «Назад» в системе Android с длительным нажатием

Я хочу добавить прослушиватель, когда кнопка «Назад» системы Android долго нажимается, то есть версия с длительным нажатием Activity.onBackPressed

Это должно работать только тогда, когда мое приложение видно.

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


person MeatPopsicle    schedule 06.07.2019    source источник
comment
проверьте этот ответ stackoverflow.com/a/4930950/8596924   -  person Tobibur Rahman    schedule 06.07.2019


Ответы (3)


Вы можете попробовать переопределить метод onKeyLongPress внутри вашего файла Activity.

@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        System.out.println("Back button long pressed");
        return true;
    }
    return super.onKeyLongPress(keyCode, event);
}
person oemel09    schedule 06.07.2019
comment
Кнопки «Назад» не создают ключевых событий. - person Gabe Sechan; 06.07.2019
comment
Я протестировал его на образце приложения, и он отлично работал. - person oemel09; 06.07.2019
comment
До Android 10 onKeyLongPress мог перехватывать событие нажатия кнопки «Назад». Но после Android 10 onKeyLongPress не может уловить обратный жест от края до края. - person Fantasy Fang; 27.01.2021

Вы можете посмотреть, как Firefox реализует Long Back Press.

https://github.com/mozilla-mobile/fenix/blob/master/app/src/main/java/org/mozilla/fenix/HomeActivity.kt

они реализуют его, используя как onKeyDown/onKeyUp, так и onKeyLongPress.

причина, по которой используются оба, заключается в том, что

Устройства Android N и Huawei сломали события onKeyLongPress для кнопки «Назад», поэтому вместо этого мы сами реализуем поведение длительного нажатия.

  • Для коротких нажатий отменяем обратный вызов в onKeyUp
  • Для длинных нажатий обычное нажатие клавиши помечается как отмененное, поэтому оно не будет обрабатываться где-либо еще (но Android по-прежнему обеспечивает тактильную обратную связь), и выполняется действие длительного нажатия.

Ниже представлена ​​их реализация.

// See onKeyDown for why this is necessary
private var backLongPressJob: Job? = null

private fun shouldUseCustomBackLongPress(): Boolean {
    val isAndroidN =
        Build.VERSION.SDK_INT == Build.VERSION_CODES.N || Build.VERSION.SDK_INT == Build.VERSION_CODES.N_MR1
    // Huawei devices seem to have problems with onKeyLongPress
    // See https://github.com/mozilla-mobile/fenix/issues/13498
    val isHuawei = Build.MANUFACTURER.equals("huawei", ignoreCase = true)
    return isAndroidN || isHuawei
}

private fun handleBackLongPress(): Boolean {
    supportFragmentManager.primaryNavigationFragment?.childFragmentManager?.fragments?.forEach {
        if (it is OnBackLongPressedListener && it.onBackLongPressed()) {
            return true
        }
    }
    return false
}

final override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
    // Inspired by https://searchfox.org/mozilla-esr68/source/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java#584-613
    // Android N and Huawei devices have broken onKeyLongPress events for the back button, so we
    // instead implement the long press behavior ourselves
    // - For short presses, we cancel the callback in onKeyUp
    // - For long presses, the normal keypress is marked as cancelled, hence won't be handled elsewhere
    //   (but Android still provides the haptic feedback), and the long press action is run
    if (shouldUseCustomBackLongPress() && keyCode == KeyEvent.KEYCODE_BACK) {
        backLongPressJob = lifecycleScope.launch {
            delay(ViewConfiguration.getLongPressTimeout().toLong())
            handleBackLongPress()
        }
    }
    return super.onKeyDown(keyCode, event)
}

final override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
    if (shouldUseCustomBackLongPress() && keyCode == KeyEvent.KEYCODE_BACK) {
        backLongPressJob?.cancel()
    }
    return super.onKeyUp(keyCode, event)
}

final override fun onKeyLongPress(keyCode: Int, event: KeyEvent?): Boolean {
    // onKeyLongPress is broken in Android N so we don't handle back button long presses here
    // for N. The version check ensures we don't handle back button long presses twice.
    if (!shouldUseCustomBackLongPress() && keyCode == KeyEvent.KEYCODE_BACK) {
        return handleBackLongPress()
    }
    return super.onKeyLongPress(keyCode, event)
}
person Angel Koh    schedule 27.11.2020

Я надеюсь, что приведенная ниже идея работает !!!

Добавьте ниже код в свою деятельность

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        //This event will be triggered after 1 second. 
        //In case if you move out of KEYCODE_BACK, onKeyUp event will be triggered and this event will be cancelled 
        handler.postDelayed(mLongPressed, 1000); 
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    handler.removeCallbacks(mLongPressed);
    return super.onKeyUp(keyCode, event);
}

код обработчика:

final Handler handler = new Handler();
Runnable mLongPressed = new Runnable() {
    public void run() {
        Log.i("Activity", "Long press detected").
       //Add your code
    }
};
person DeC    schedule 02.08.2019