FLAG_ACTIVITY_NEW_TASK не работает должным образом при использовании в PendingIntent

Хорошо, терпите меня здесь

Мое приложение состоит из действия заставки (A) и основного действия (B). Когда приложение запускается, (A) немного отображается, а затем запускается (B). После этого (A) закончено. Это прекрасно работает в "нормальных" условиях. Вот код для запуска (B)

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        Intent mainIntent = new Intent(A.this, B.class);
        startActivity(mainIntent);
        finish();
    }
}, SPLASH_DELAY);

Когда приходит уведомление, и пользователь нажимает на него. Я начинаю (A) с помощью PendingIntent:

Intent mIntent = new Intent(this, A.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, mIntent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this).setSmallIcon()... //build the whole notification
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(0, mBuilder.build());

Это начинается (A), а затем (B) и все хорошо.

Тем не мение...

Как только приложение отображается на экране и приходит второе уведомление (A) не запускается снова, и я не получаю никакого обратного вызова в (B)

Читая документацию по адресу http://developer.android.com/guide/components/tasks-and-back-stack.html, я пришел к выводу, что начинать (A) следует с набора FLAG_ACTIVITY_NEW_TASK (чтобы он запускал новую задачу). только если (A) еще не запущен), и я также должен начать (B) с флагом FLAG_ACTIVITY_SINGLE_TOP (чтобы я мог получить обратный вызов B.onNewIntent (), потому что B будет работать). Так я и сделал

...
mainIntent.setFlags(FLAG_ACTIVITY_NEW_TASK);
....

mIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
....

но увы нет. Поведение, кажется, не меняется вообще.

Я что-то упустил из документов? Мне кажется, что FLAG_ACTIVITY_NEW_TASK должен запускаться (A) каждый раз в моем случае, потому что к тому времени, когда приходит второе уведомление. (A) уже закончил, но он ничего не делает.

Можете ли вы дать мне несколько советов о том, как получить любой обратный вызов, чтобы я мог отображать правильную информацию для пользователя?

Спасибо

1 ответ

Решение

Для уведомления вы создали PendingIntent для корневого действия ("запуска" деятельности) вашей задачи, и вы установили FLAG_ACTIVITY_NEW_TASK, Это сделает следующее:

  • Если ваше приложение не запущено, оно создаст новое задание и запустит действие A внутрь

  • Если ваше приложение уже запущено (то есть: уже есть активная задача, которая была запущена при запуске действия A, даже если активность A больше не существует), она выведет эту задачу на передний план в любом состоянии, в котором она находилась. Это не создаст никаких новых действий и не вызовет onNewIntent() на любую существующую деятельность. Это просто "сокращение" для "вывести мою задачу на передний план", аналогично тому, что происходит, когда пользователь выбирает ваше приложение из "списка недавних задач".

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

  • Используйте отдельное действие, которое вы запускаете из уведомления. Это действие не должно быть корневым (то есть: "запускать" действие вашего приложения. Это действие будет запущено, когда пользователь выберет уведомление. Если ваше приложение уже запущено, это действие будет запущено в существующей задаче вашего приложения). Приложение может определить, запущено ли уже приложение (используйте Activity.isTaskRoot() определить это) и сделать что-то подходящее (например, запустить действие root, если приложение еще не запущено).

  • Используйте следующую комбинацию флагов при запуске вашей корневой активности из уведомления: FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP, Это удалит любые другие действия из задачи поверх корневого действия и вызовет onNewIntent() на корневой активности. Это ваш "обратный звонок". ПРИМЕЧАНИЕ: это будет работать, только если ваша корневая активность (всплеск активности) еще не завершена! Это означает, что когда действие A начинает действие B, оно не должно вызыватьfinish()

Другие вопросы по тегам