Очистка задачи и переход к основному действию после нажатия на уведомление

У меня есть следующий сценарий, который я пытаюсь исправить:

  1. Приложение состоит из двух действий: Activity_A и Activity_B.
  2. В настоящее время пользователь находится в Activity_B
  3. Получено уведомление, которое приводит к Activity_A

ОДНАКО При нажатии клавиши «Назад» выход из приложения выглядит следующим образом: Activity_A (из уведомления) -> Activity_B-> Activity_A-> Приложение закрывается.

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

Я прошел множество ответов и вопросов, которые почти описывают один и тот же сценарий, и все попытки реализации ответов не решили мою проблему.

одна вещь, которая дала мне то, что я хотел, заключалась в том, что я установил в своем основном действии android:launchMode="singleInstance", но тогда каждый вызов действия выглядит так, как будто было запущено новое приложение.

Ниже вы можете найти код:

final Intent notificationIntent = new Intent(getApplicationContext(), MyDevices.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);

final PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent,0);
final Notification notification = new Notification.Builder(
        getApplicationContext())
        .setSmallIcon(R.drawable.ic_launcher)
        .setContentTitle(mNotificationTitle)
        .setOngoing(false)
        .setContentText(mNotificationMessage)
        .setContentIntent(pendingIntent)
        .setAutoCancel(true)
       .setDefaults(Notification.DEFAULT_ALL).build();

notificationManager.notify(1,notification); 

person user2145673    schedule 08.05.2015    source источник
comment
В отличие от форумов, мы не используем слова «Спасибо» или «Любая помощь приветствуется» или подписи на Stack Overflow. См. раздел Должен ли быть "Привет", "спасибо" слоганов и приветствий удалить из постов?. Кстати, это заранее спасибо, а не спасибо заранее.   -  person John Saunders    schedule 11.05.2015


Ответы (3)


Вы пытались установить singleTask вместо singleInstance? Также вы можете попытаться добиться onActivityResult, чтобы завершить действие B, когда оно вернется из действия A.

Если нет, я мог бы предложить вам проверить мою библиотеку для обработки навигации по активности: https://github.com/yayaa/TheActivityManager


Изменить:

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

Режимы «singleTask» и «singleInstance» также отличаются друг от друга только в одном отношении: действие «singleTask» позволяет другим действиям быть частью его задачи. Он всегда находится в корне своей задачи, но другие действия (обязательно «стандартные» и «singleTop» действия) могут быть запущены в этой задаче. С другой стороны, действие "singleInstance" не позволяет никаким другим действиям быть частью его задачи. Это единственное действие в задаче. Если он запускает другое действие, это действие назначается другой задаче — как если бы FLAG_ACTIVITY_NEW_TASK был в намерении

И единственное предупреждение, которое я вижу, это следующее, которое кажется мне не таким уж важным, если вы знаете, что делаете, и уверены в том, чего хотите.

singleTask и singleInstance — не подходят для большинства приложений, поскольку они приводят к модели взаимодействия, которая, вероятно, будет незнакома пользователям и сильно отличается от большинства других приложений.

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

person yahya    schedule 08.05.2015
comment
Что ж, кажется, что singleTask справился с задачей, трудно поверить, что это было так просто. относительно флагов, которые я установил на намерение. добавить что-то или оставить как есть? Кроме того, является ли singleTask лучшей практикой? согласно developer.android.com/guide/topics/manifest/ слишком много предупреждающих знаков об этих режимах запуска - person user2145673; 08.05.2015
comment
На самом деле, это не. Вы не должны отображать уведомление, если приложение уже запущено. Вы могли бы справиться с этим каким-то другим способом, хотя я не уверен, что это будет в вашем случае. - person yahya; 08.05.2015
comment
ну, большинство известных приложений показывают уведомления, когда вы находитесь в самом приложении, поэтому должно быть решение для обработки этого сценария без использования этих режимов запуска. у вас есть идеи, как я могу добиться того же поведения, как если бы я запускал singleTask? - person user2145673; 08.05.2015
comment
Я снова изучил ссылку, которую вы предоставили, и я думаю, что можно использовать singleTask, просто убедитесь, что вы проверили ее в большинстве случаев. И, пожалуйста, посмотрите мой обновленный ответ. - person yahya; 09.05.2015
comment
Спасибо за подробный ответ, я протестировал свое приложение с однозадачностью, и все работает как положено. В настоящее время это решение, с которым я пойду - person user2145673; 10.05.2015
comment
Я рад, что смог помочь :) - person yahya; 10.05.2015
comment
Использование специальных режимов запуска не является правильным способом решения этой проблемы. Как правило, использование специальных режимов запуска singleTask и singleInstance должно быть ограничено заменой экрана HOME и отдельными уведомлениями, которые не имеют ничего общего с остальной частью основного приложения. Пользователь должен использовать стандартные режимы запуска своего приложения. - person David Wasser; 15.05.2015

Ничего особенного, просто добавьте эту функцию в свой B_Activity. Просто завершайте действие всякий раз, когда вы его покидаете. Это хорошая практика.

protected void onUserLeaveHint() {
    try{
        super.onUserLeaveHint();
        finish();
    }catch(Exception ex){
        //Something went wrong.
    }
}
person Waheed Akhtar    schedule 08.05.2015
comment
То же самое с завершением активности onPause? - person yahya; 09.05.2015
comment
Нет, это другое. @yahya - person Waheed Akhtar; 10.05.2015

Принятый ответ не является хорошим. Использование специальных режимов запуска для такого поведения некорректно, хотя и может сработать в данном конкретном случае. В целом использование режимов запуска singleTask или singleInstance не является правильным подходом и обычно вызывает больше проблем, чем решает.

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

final Intent notificationIntent = new Intent(getApplicationContext(),
                      MyDevices.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK |
                            Intent.FLAG_ACTIVITY_NEW_TASK);

В документации для Intent.FLAG_ACTIVITY_CLEAR_TASK это также достаточно ясно. В нем говорится:

Если он установлен в намерении, переданном в Context.startActivity(), этот флаг приведет к тому, что любая существующая задача, которая будет связана с действием, будет очищена до запуска действия. То есть действие становится новым корнем пустой задачи, а все старые действия завершаются. Это можно использовать только в сочетании с FLAG_ACTIVITY_NEW_TASK.

person David Wasser    schedule 15.05.2015