Как предотвратить возвращение к предыдущей активности?

210

Когда на телефоне нажата кнопка НАЗАД, я хочу предотвратить возврат определенной активности к предыдущей.

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

Я пытался использовать Intent.FLAG_ACTIVITY_NO_HISTORY, но поскольку приложение имеет интеграцию с Facebook, когда используется «Войти через Facebook», Facebook должен вернуться к начальному экрану входа в систему, поэтому я должен хранить историю этих действий.

Я думал о переопределении поведения кнопки НАЗАД HomeScreenдля непосредственного завершения приложения, когда кнопка нажата, и я использовал

@Override
public void onBackPressed() {
    finish();
}

но это также не работает.

ECEM
источник
1
Просто чтобы уточнить, вы пытаетесь отследить поведение всех, кроме фейсбука?
havexz
2
В некотором смысле да, но на самом деле я хочу, чтобы после успешного входа в систему и открытия HomeScreen пользователь не мог вернуться к экрану входа, нажав кнопку BACK. Так же, как Twitter или Foursquare, например, после входа в эти приложения мы не видим страницу входа, пока не выйдем из системы (даже если мы нажмем BACK после входа в систему).
ECEM

Ответы:

345

Я предлагаю закончить действие, к которому вы не хотите, чтобы пользователи возвращались. Например, во время входа в систему сразу после звонка startActivityпозвоните finish(). Когда пользователи нажимают кнопку «Назад», они не могут перейти к действию входа в систему, поскольку оно было удалено из стека.

кодировщик
источник
2
Что если я хотел бы, чтобы поток в предыдущем действии продолжал выполняться?
AlleyOOP
2
Вы не хотели бы пойти с моим подходом тогда. Вызов Finish () убивает активность. Не могли бы вы начать процесс, который вы хотите запустить в деятельности, которую вы собираетесь?
кодер
7
Примечание: если вы звоните finishво время совместного перехода, вы можете получить доступ к предыдущей активности. например, если у вас есть HomeActivity-> IntermediateActivity-> FinalActivity, и вы звоните finish()в IntermediateActivityсразу же после запуска FinalActivityвы увидите HomeActivityна короткое время.
Дэвид Мердок
101

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

Чтобы свернуть приложение, а не возвращаться к предыдущему действию, вы можете переопределить его onBackPressed()так:

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

moveTaskToBack(boolean nonRoot)оставляет ваш задний стек как есть, просто помещает вашу задачу (все действия) в фоновый режим. То же самое, как если бы пользователь нажал кнопку «Домой» .

Параметр boolean nonRoot- если false, то это работает, только если действие является корнем задачи; если true, это будет работать для любой активности в задаче.

Марсель Бро
источник
3
Идеально подходит для экрана входа в систему, потому что он сохраняет историю нетронутой.
Хэкмодфорд
Спасибо, я пытался найти это около трех дней. Из-за android: noHistory = "true" флаг для Activity не работает должным образом (флаг noHistory воссоздает активность после минимизации), а finish () иногда не работает для меня, но почему я до сих пор не понял.
Деншов
37

Я не уверен, что именно вы хотите, но звучит так, как будто это возможно, и звучит так, будто вы уже на правильном пути.

Вот несколько ссылок, которые могут помочь:

Отключить кнопку назад в Android

  MyActivity.java =>
    @Override
    public void onBackPressed() {

       return;
    }

Как я могу отключить «вернуться» к какой-либо деятельности?

  AndroidManifest.xml =>
<activity android:name=".SplashActivity" android:noHistory="true"/>
paulsm4
источник
1
Я не могу использовать опцию noHistory из-за проблемы Facebook, которую я пытался объяснить в своем вопросе, а также в одном из комментариев. Но дело с кнопкой BACK не в том, чтобы отключить ее, а в том, чтобы заставить ее выйти из всего приложения, как System.exit(0)это называется (я знаю, что это не самая лучшая практика, но я просто хотел привести пример).
ECEM
Спасибо, это отлично сработало. Единственное предложение, которое я сделал бы здесь, - нет необходимости возвращаться. Просто удалите super.onBackPressed () и оставьте метод пустым. Это тоже хорошо работает
hyperCoder
20

Для вашего случая есть два решения: операция A запускает операцию B, но вы не хотите возвращаться к операции A в операции B.

1. Удалено предыдущее действие A из заднего стека.

    Intent intent = new Intent(activityA.this, activityB.class);
    startActivity(intent);
    finish(); // Destroy activity A and not exist in Back stack

2. Отключено действие кнопки возврата в действии B.

Есть два способа предотвратить возврат события, как показано ниже,

1) Рекомендовать подход

@Override
public void onBackPressed() {
}

2) переопределить метод onKeyDown

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode==KeyEvent.KEYCODE_BACK) {
        return false;
    }
    return super.onKeyDown(keyCode, event);
}

Надеюсь, что это полезно, но все же зависит от ваших ситуаций.

Луна Конг
источник
3
Разве это не плохо для пользователя, чтобы отключить onBackPressed ()?
С. Скьердал
Это полностью зависит от того, что вы пытаетесь сделать, в функциональности приложения это необходимо, а затем пойти на это.
user3099225
Удивительно, как я полностью забыл о первом использовании метода finish(). Излишне продуман с nohistoryатрибутом, флагами намерений, родительскими тегами манифеста активности и т. Д.! Глупо, спасибо за ответ!
Варун
8

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

Как пропустить возвращение к предыдущему занятию?

Удалить предыдущее действие из Backstack. просто

Как удалить предыдущую активность из Backstack?

finish()Метод вызова

Нормальный поток:

введите описание изображения здесь
Все действия хранятся в стеке, известном как Backstack.
Когда вы запускаете новый Activity ( startActivity(...)), то новый Activity помещается в верхнюю часть стека, а когда вы нажимаете кнопку «назад», Activity выталкивается из стека.
Один ключевой момент, на который следует обратить внимание, это то, что при нажатии кнопки «Назад» finish();метод вызывается изнутри. Это поведение по умолчанию метода onBackPressed ().

Итак, если вы хотите пропустить занятие B?

то есть A <--- C

Просто добавьте finish();метод после вашего startActvity(...)в упражнении B

Intent i = new Intent(this, C.class);
startActivity(i);
finish();

введите описание изображения здесь

Рохит Сингх
источник
6

finish()дает вам способ закрыть текущую активность, а не все приложение. И вам лучше не пытаться искать методы, чтобы убить приложение. Маленький совет.

Вы пробовали соединение Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_NO_HISTORY? Не забудьте использовать этот флаг в Intentначале деятельности!

cadavre
источник
2
FLAG_ACTIVITY_NO_HISTORYзапрещает моему LoginScreen захватывать обратный вызов Facebook, когда используется Login with Facebook. Потому что, как только фокус исчезает с экрана входа в систему, он не может быть возобновлен (так как нет истории). Но я не пробовал Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS, я проверю, спасибо!
ECEM
Также спасибо за finish()метод, я не знал об этом.
ECEM
4

Положить finish()сразу после

Intent i = new Intent(Summary1.this,MainActivity.class);
            startActivity(i);
finish();
Парам Триведи
источник
1
Это в основном то, что сказал принятый ответ за четыре года до этого.
TylerH
3

Ответ paulsm4 является правильным. Если onBackPressed()вы просто вернетесь, он отключит кнопку возврата. Тем не менее, я думаю, что лучший подход, учитывая ваш вариант использования, состоит в том, чтобы перевернуть логику активности, то есть сделать вашу домашнюю активность основной, проверить, выполнил ли пользователь там вход, если нет, запустить операцию входа. Причина в том, что если вы переопределите кнопку «Назад» в своей основной деятельности, большинство пользователей будут смущены, когда они нажимают назад, а ваше приложение ничего не делает.

DMON
источник
3

Этот метод работает нормально

Intent intent = new Intent(Profile.this, MainActivity.class); 
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);
pulak
источник
2

Просто переопределите метод onKeyDown и проверьте, была ли нажата кнопка «Назад».

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) 
{
    if (keyCode == KeyEvent.KEYCODE_BACK) 
    {
        //Back buttons was pressed, do whatever logic you want
    }

    return false;
}
Машинное Племя
источник
1
@Override
public void onBackPressed() {
}

Когда вы создаете onBackPressed()просто удалить, super.onBackPressed();и это должно работать

hyperCoder
источник
1

Ставить

finish();

сразу после ActivityStart, чтобы остановить действие, не позволяющее вернуться к нему. Затем добавьте

onCreate(){
    getActionBar().setDisplayHomeAsUpEnabled(false);
    ...
}

к деятельности, которую вы начинаете.

Брэндон Дайер
источник