Переопределить кнопку "Назад", чтобы действовать как кнопка "Домой"

После нажатия кнопки "Назад" я бы хотел, чтобы мое приложение перешло в состояние останова, а не в уничтоженное состояние.

В документации для Android говорится:

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

Как мне воспроизвести эту функцию в моем собственном приложении?

Я думаю, что должно быть три варианта...

  1. Захватите кнопку "назад" (как показано ниже) и затем вызовите любой метод, который вызывает кнопка "Домой".

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK)) {
            Log.d(this.getClass().getName(), "back button pressed");
        }
        return super.onKeyDown(keyCode, event);
    }
    
  2. Захватите кнопку "Назад" и затем нажмите кнопку "Домой".

  3. Захватите кнопку "Назад", затем запустите "Активность" на домашнем экране, фактически переведя "Активность" моего приложения в состояние остановки.

Изменить: я знаю об услугах, и я использую один в приложении, с которым связана эта проблема. Этот вопрос, в частности, касается перевода Действия в остановленное состояние, а не в уничтоженное состояние при нажатии кнопки "Назад".

9 ответов

Решение

Большую часть времени вам нужно создать Сервис для выполнения чего-либо в фоновом режиме, и ваш видимый Activity просто контролирует это Service, (Я уверен, что музыкальный проигрыватель работает таким же образом, поэтому пример в документации кажется немного вводящим в заблуждение.) Если это так, то ваш Activity Можно finish как обычно и Service все еще будет работать.

Более простой подход состоит в том, чтобы захватить Back Нажмите кнопку и вызовите moveTaskToBack(true) следующим образом:

// 2.0 and above
@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

// Before 2.0
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        moveTaskToBack(true);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

Я думаю, что предпочтительный вариант должен состоять в том, чтобы Activity завершалась нормально и могла воссоздать себя, например, при необходимости читая текущее состояние из Service. Но moveTaskToBack может быть использована в качестве быстрой альтернативы при необходимости.

ПРИМЕЧАНИЕ: как отметил Дейв ниже, Android 2.0 представил новый onBackPressed метод, и эти рекомендации о том, как обрабатывать кнопку Назад.

Используйте следующий код:

public void onBackPressed() {    
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    startActivity(intent);
}

Если вы хотите поймать кнопку "Назад", загляните в этот пост в блоге разработчиков Android. Он описывает более простой способ сделать это в Android 2.0 и лучший способ сделать это для приложения, работающего на 1.x и 2.0.

Однако, если ваша активность остановлена, она все равно может быть уничтожена в зависимости от наличия памяти на устройстве. Если вы хотите, чтобы процесс запускался без пользовательского интерфейса, вы должны создать Service, В документации сказано об услугах:

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

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

Попытаться переопределить пустоту onBackPressed() определено в классе android.app.Activity.

Если это помогает кому-то еще, у меня было упражнение с двумя макетами, которые я включал и выключал для наглядности, пытаясь эмулировать некую структуру page1 > page2. если бы они были на странице 2 и нажали кнопку "назад", я бы хотел, чтобы они вернулись на страницу 1, если они нажали кнопку "назад" на странице 1, она все равно должна работать как обычно. Это довольно простой, но это работает

@Override
public void onBackPressed() {
// check if page 2 is open
    RelativeLayout page2layout = (RelativeLayout)findViewById(R.id.page2layout);
    if(page2layout.getVisibility() == View.VISIBLE){
        togglePageLayout(); // my method to toggle the views
        return;
    }else{
        super.onBackPressed(); // allows standard use of backbutton for page 1
    }

}

надеюсь, это поможет кому-то, ура

Рабочий пример..

Убедитесь, что не вызываете super.onBackPressed();

@Override
public void onBackPressed() {
   Log.d("CDA", "onBackPressed Called");
   Intent setIntent = new Intent(Intent.ACTION_MAIN);
   setIntent.addCategory(Intent.CATEGORY_HOME);
   setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   startActivity(setIntent);
}

Таким образом, кнопка "Назад" действует как кнопка "Домой". Это не завершает вашу деятельность, но взять на задний план

Второй способ это позвонить moveTaskToBack(true); в onBackPressed и не забудьте удалить super.onBackPressed

Переопределить onBackPressed() после Android 2.0. Такие как

@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

Еще лучше, как насчет OnPause ():

Вызывается как часть жизненного цикла действия, когда действие переходит в фоновый режим, но еще не было уничтожено. Аналог onResume().

Когда действие B запускается перед действием A, этот обратный вызов будет вызываться для A. B не будет создан до тех пор, пока функция onPause() A не будет возвращена, поэтому обязательноenter code here не делайте ничего длинного здесь.

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

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

Я использую @Mirko N. с помощью автоответчика сделал новый Custom EditText

 public class EditViewCustom extends EditText {

    Button cancelBtn;
    RelativeLayout titleReleLayout;
    public EditViewCustom(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public EditViewCustom(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EditViewCustom(Context context) {
        super(context);
    }

    public void setViews(Button cancelBtn,RelativeLayout titleReleLayout){
        this.cancelBtn = cancelBtn;
        this.titleReleLayout = titleReleLayout;
    }

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            Log.d("KEYCODE_BACK","KEYCODE_BACK");
            cancelBtn.setVisibility(View.GONE);
            this.setFocusableInTouchMode(false);
            this.setFocusable(false);
            titleReleLayout.setVisibility(View.VISIBLE);

            return super.onKeyPreIme(keyCode, event);
          }

        return super.onKeyPreIme(keyCode, event);
    }

}

Затем установите данные из вашей деятельности

 searchEditView.setViews(cancelBtn, titleRelativeLayout);

Спасибо.

Я пробовал все вышеперечисленные решения, но ни одно из них не помогло мне. Следующий код помог мне при попытке вернуться к MainActivity способом, который вызывается onCreate:

Intent.FLAG_ACTIVITY_CLEAR_TOP - это ключ.

  @Override
  public void onBackPressed() {
      Intent intent = new Intent(this, MainActivity.class);
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
      startActivity(intent);
  }
Другие вопросы по тегам