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


253

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

В документации для 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. Захватите кнопку «Назад», затем запустите «Активность» на домашнем экране, фактически переведя «Активность» моего приложения в состояние остановки.

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


см. аналогичный ответ stackoverflow.com/questions/5914040/…
Zar E Ahmer

Ответы:


338

Большую часть времени вам нужно создать Сервис для выполнения чего-либо в фоновом режиме, и ваш видимый 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);
}

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

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


1
moveTaskToBack () работает так, как нужно. Каковы могут быть недостатки использования этого метода? Есть ли случаи, когда это может работать не так, как ожидалось?
2010 года

1
После более внимательного прочтения документа я думаю, что он должен работать нормально. (Сначала я думал, что это применимо к заданию, но на самом деле оно говорит «задание, содержащее это задание».) Но вы, конечно, должны проверить это сами. :)
Мирко Н.

Спасибо Мирко, метод, кажется, работает хорошо. Было бы здорово, если бы вы дали больше внимания своей правке в нижней части вашего ответа для тех, кто рассматривает этот вопрос позже - поскольку это был бит, который я искал!
2010 г.

4
Пожалуйста, прочитайте android-developers.blogspot.com/2009/12/… для рекомендуемого способа обработки задней клавиши.
hackbod

1
@bdls в теории ваша фоновая активность может быть уничтожена системой, если у нее мало ресурсов, поэтому для безопасности она должна быть в любом случае способна воссоздать себя. Я взглянул на исходный код приложения Android Music и не вижу никакой специальной обработки кнопки «Назад».
Мирко Н.

46

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

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

23

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

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

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

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



14

если это помогает кому-то еще, у меня было действие с двумя макетами, которые я включал и выключал для наглядности, пытаясь эмулировать некую структуру 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
    }

}

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


10

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

Убедитесь, что не вызываете 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


0

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

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

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

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

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


0

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

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

0

Я перепробовал все вышеперечисленные решения, но ни одно из них не помогло мне. Следующий код помог мне при попытке вернуться к 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);
  }

-1

Я использую @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);

Спасибо.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.