Согласно этой теме на StackOverflow, «Android запоминает намерение, которое было использовано для его запуска». Описанная там проблема - это именно то, через что я прохожу:
Когда приложение запускается в первый раз с
Notification
, это может все испортить. Вы запускаете приложение изNotification
, и Android запоминаетIntent
использованный (изNotification
), когда вы позже запускаете приложение (снова сNotification
), Android сопоставляетIntent
вNotification
сIntent
использованным для первого запуска приложения время и думает, что вы хотите перенести существующую задачу приложения из фонового режима на передний план.
Проблема: я не понимаю, почему Android считает, что Intent один и тот же. Хотя действие одно и то же, намерение имеет совершенно разные дополнения.
Когда я добавляю флаги к намерению, я могу решить эту проблему. Например:
Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK
Но моя цель — сохранить задний стек, который, конечно, не использует эти флаги.
Это приложение для веб-просмотра с некоторыми дополнительными экранами.
Проблема существует только тогда, когда приложение запускается через уведомление. Когда я запускаю его сам и ставлю на фон, все работает так, как я хочу.
Сценарий
"openLink" =
https://something.com/one"openLink" =
https://something.com/twoЧто я хочу:
Как обстоят дела сейчас:
Мой код:
val pendingIntent = PendingIntent.getActivity(
baseContext,
notificationId,
newIntent,
PendingIntent.FLAG_IMMUTABLE
)
notificationBuilder = notificationBuilder.setContentIntent(pendingIntent)
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.notify(notificationId, notificationBuilder.build())
NotificationId уникален. дополнительные возможности newIntent уникальны. Я перепробовал все флаги, какие только есть. MainActivity (который имеет веб-просмотр) имеет режим запуска «singleTop», но, конечно, я пробовал без установки режима запуска.
Дальнейшие наблюдения:
TaskStackBuilder
, потому что это не сохраняет задний стек. Он просто позволяет вам создать свой собственный задний стек (невозможно с помощью веб-просмотра).Кроме того, если MainActivity
имеет режим запуска singleTop
и пользователь запускает MainActivity
из Notification
, а затем снова запускает MainActivity
из Notification
, это не создаст 2 экземпляра MainActivity
в стеке. Это может (а может и не быть) то, что вы хотите. Кажется, ваш пост указывает на то, что в этом случае вы ожидаете иметь 2 экземпляра MainActivity
в стеке.
Это действительно сработало, я не могу в это поверить. Большое спасибо! Вы только что сделали мой день программирования. Мне нужно бесконечное количество обоих действий, но только новые экземпляры MainActivity
в стеке, если новое намерение вызывает другое действие. Именно это и делает singleTop
, но спасибо за подсказку.
Это забавно, потому что это определенно не то, как вы должны использовать действия... Я чувствую, что Android должен как-то решить эту проблему.
Я создал ответ с дополнительной информацией/объяснениями. Надеюсь, теперь понятно, что произошло и почему это изменение работает. Вам нужно сделать Intent
«другими». Есть много способов сделать это, установка ДЕЙСТВИЯ — один из них.
@DavidWasser, какой еще способ изменить намерение? Мне любопытно. Спасибо!
Вы можете сделать Intent
уникальным, установив для ДЕЙСТВИЯ или ДАННЫХ уникальное значение. Вы также можете установить имя компонента (пакет, класс), но это приведет к запуску другого Activity
, поэтому это может не помочь.
Уникальное действие — это то, что позволяет Android различать намерения одного и того же действия:
newIntent.setAction(UUID.randomUUID().toString())
Большое спасибо @David Wasser за решение.
Ваша проблема в том, что когда пользователь нажимает not1, Android запускает приложение с помощью MainActivity
и запоминает, что приложение было запущено с помощью MainActivity
.
Когда пользователь нажимает not3, Intent
в Notification
имеет MainActivity
, что соответствует Intent
, который использовался для первоначального запуска приложения. (Примечание: Android не сравнивает «дополнительные элементы» при сравнении Intent
), поэтому Android думает, что вы хотите перенести существующую задачу, содержащую приложение, из фона, что он и делает. В этом случае он не создает новый экземпляр MainActivity
, не вызывает onNewIntent()
, он просто выводит существующую задачу (в каком бы состоянии она ни находилась) на передний план.
Это то же самое поведение, что и при запуске приложения: нажмите ДОМОЙ, снова нажмите значок этого приложения. Android думает, что вы хотите вернуться в приложение, поэтому просто выводит его из фона.
Решение:
Добавьте ДЕЙСТВИЕ к Intent
, который вы вставили в Notification
. Установите для ДЕЙСТВИЯ какую-нибудь случайную строку, чтобы она всегда была уникальной при каждом создании Notification
.
Это гарантирует, что всякий раз, когда пользователь нажимает Notification
для запуска приложения, Intent
не будет совпадать с Intent
, который использовался для первоначального запуска приложения. Затем Android выведет приложение из фонового режима (если оно находится в фоновом режиме), создаст новый экземпляр Activity
и поместит его в стек задач.
Только одно дополнение: в моем случае только приложение было открыто в последнем состоянии. Активность в намерении даже не была выведена на передний план.
Правильно. Он просто переводит приложение в любое состояние, в котором оно находилось, из фонового на передний план. Именно это происходит, когда вы выходите из приложения (нажимая ДОМОЙ, уведомление или что-то еще), а затем возвращаетесь к нему, выбирая приложение из ПОСЛЕДНИЕ или нажимая значок приложения на ГЛАВНОМ экране. Вы возвращаетесь в приложение точно в том же состоянии, в каком вы его покинули. Тот же Activity
, тот же Fragment
, те же данные и т. д.
Используйте только Intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
Не держит задний стек. На мой вопрос уже был дан ответ.
Ваш ответ можно улучшить, добавив дополнительную вспомогательную информацию. Пожалуйста, отредактируйте , добавив дополнительную информацию, например цитаты или документацию, чтобы другие могли подтвердить правильность вашего ответа. Более подробную информацию о том, как писать хорошие ответы, вы можете найти в справочном центре.
Интересная ситуация. Попробуйте следующее: добавьте ДЕЙСТВИЕ к
Intent
, который вы вставили вNotification
. Установите для ДЕЙСТВИЯ какую-нибудь случайную строку, чтобы она всегда была уникальной при каждом созданииNotification
. Дайте мне знать, если это поможет.