Кнопка перезаписати назад, щоб діяти як кнопка будинку


253

Натискаючи кнопку "назад", я хотів би, щоб моя програма перейшла у стан, що зупинився, а не в зруйнований стан.

У документах Android зазначено:

... не всі дії мають поведінку, яку вони знищують, коли натискають кнопку BACK. Коли користувач починає відтворювати музику в програмі "Музика", а потім натискає кнопку BACK, програма переосмислює нормальну поведінку назад, запобігаючи руйнуванню активності плеєра, і продовжує відтворювати музику, навіть якщо її діяльність більше не видно

Як я повторюю цю функціональність у власному додатку?

Я думаю, що має бути три можливості ...

  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 / ...
Зар E Ahmer

Відповіді:


338

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

Більш простий підхід полягає в захопленні Backнатискання кнопки та виклику moveTaskToBack (правда) наступним чином:

// 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 (), здається, працює за бажанням. Які можуть бути недоліки використання цього методу? Чи бувають випадки, коли це може не спрацювати так, як очікувалося?
бдлс

1
Прочитавши докладніше його документ, я дійсно думаю, що він повинен працювати добре. (Я спочатку думав, що це стосується діяльності, але насправді в ній написано "завдання, що містить цю діяльність".) Але ви, звичайно, повинні перевірити це. :)
Мирко Н.

Дякую Мірко, метод, здається, працює добре. Це може бути здорово, якщо ви приділите більше уваги вашій редакції внизу вашої відповіді для тих, хто переглядає це питання пізніше - тому що це був біт, який я шукав!
бдлс

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.onBackPress ();

@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, цей зворотний виклик буде викликаний на А. B не створюватиметься, поки повернеться onPause () A, тому не забудьте enter code hereтут нічого не робити.

Цей зворотний виклик використовується в основному для збереження будь-якого постійного стану, який редагує активність, і гарантує, що нічого не втрачено, якщо не вистачить ресурсів для початку нової діяльності, не попередньо вбиваючи цю.

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


0

Перезавантажте onBackPress () після Android 2.0. Як от

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

0

Я спробував усі вищеперелічені рішення, але жодне з них не працювало на мене. Наступний код мені допоміг, коли я намагався повернутися до MainActivity таким чином, як onCreate викликає:

Намір.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. answser, використовуючи зроблений новий користувальницький 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.