Когда вы запускаете действие из уведомления, вы должны сохранить ожидаемые возможности навигации пользователя. Нажатие кнопки «Назад» должно вернуть пользователя через обычный рабочий процесс приложения на главный экран, а при открытии экрана «Недавние» действие должно отображаться как отдельная задача. Чтобы сохранить этот опыт навигации, запустите действие в новой задаче.
Основной подход к настройке поведения касания для вашего уведомления описан в разделе «Создание базового уведомления» . На этой странице описано, как настроить PendingIntent
для действия вашего уведомления, чтобы оно создавало новую задачу и обратный стек . Как вы это сделаете, зависит от того, какой вид деятельности вы начинаете:
- Регулярная деятельность
- Это действие, которое существует как часть обычного процесса UX вашего приложения. Когда пользователь переходит к действию из уведомления, новая задача должна включать полный задний стек, позволяя пользователю нажать кнопку «Назад» для перемещения вверх по иерархии приложения.
- Специальная деятельность
- Пользователь видит это действие, только если оно запущено из уведомления. В некотором смысле это действие расширяет пользовательский интерфейс уведомлений, предоставляя информацию, которую сложно отобразить в самом уведомлении. Для этого действия не требуется задний стек.
Настройте регулярное действие PendingIntent
Чтобы начать регулярное действие из вашего уведомления, настройте PendingIntent
с помощью TaskStackBuilder
, чтобы он создавал новый задний стек следующим образом.
Определите иерархию действий вашего приложения.
Определите естественную иерархию своих действий, добавив атрибут android:parentActivityName
к каждому элементу <activity>
в файле манифеста вашего приложения. См. следующий пример:
<activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- MainActivity is the parent for ResultActivity. --> <activity android:name=".ResultActivity" android:parentActivityName=".MainActivity" /> ... </activity>
Создайте PendingIntent с обратным стеком
Чтобы запустить действие, которое включает в себя задний стек действий, создайте экземпляр TaskStackBuilder
и вызовите addNextIntentWithParentStack()
, передав ему Intent
для действия, которое вы хотите запустить.
Если вы определили родительское действие для каждого действия, как описано ранее, вы можете вызвать getPendingIntent()
для получения PendingIntent
, включающего весь задний стек.
Котлин
// Create an Intent for the activity you want to start. val resultIntent = Intent(this, ResultActivity::class.java) // Create the TaskStackBuilder. val resultPendingIntent: PendingIntent? = TaskStackBuilder.create(this).run { // Add the intent, which inflates the back stack. addNextIntentWithParentStack(resultIntent) // Get the PendingIntent containing the entire back stack. getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) }
Ява
// Create an Intent for the activity you want to start. Intent resultIntent = new Intent(this, ResultActivity.class); // Create the TaskStackBuilder and add the intent, which inflates the back // stack. TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); stackBuilder.addNextIntentWithParentStack(resultIntent); // Get the PendingIntent containing the entire back stack. PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
При необходимости вы можете добавить аргументы к объектам Intent
в стеке, вызвав TaskStackBuilder.editIntentAt()
. Иногда это необходимо, чтобы гарантировать, что действие в заднем стеке отображает значимые данные, когда пользователь переходит к нему.
Затем вы можете передать PendingIntent
в уведомление как обычно:
Котлин
val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply { setContentIntent(resultPendingIntent) ... } with(NotificationManagerCompat.from(this)) { notify(NOTIFICATION_ID, builder.build()) }
Ява
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID); builder.setContentIntent(resultPendingIntent); ... NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(NOTIFICATION_ID, builder.build());
Настройте специальную активность PendingIntent.
Поскольку специальное действие, которое начинается с уведомления, не требует обратного стека, вы можете создать PendingIntent
, вызвав getActivity()
. Однако определите соответствующие параметры задачи в манифесте.
- В своем манифесте добавьте следующие атрибуты к элементу
<activity>
.-
android:taskAffinity =""
- В сочетании с флагом
FLAG_ACTIVITY_NEW_TASK
, который вы используете в коде, установите этот атрибут пустым, чтобы гарантировать, что это действие не входит в задачу приложения по умолчанию. Любые существующие задачи, имеющие сходство приложения по умолчанию, не будут затронуты. -
android:excludeFromRecents ="true"
- Исключает новую задачу с экрана «Последние», чтобы пользователь не мог случайно вернуться к ней.
Это показано в следующем примере:
<activity android:name=".ResultActivity" android:launchMode="singleTask" android:taskAffinity="" android:excludeFromRecents="true"> </activity>
-
- Создайте и выпустите уведомление:
- Создайте
Intent
, который запускаетActivity
. - Настройте запуск
Activity
в новой пустой задаче, вызвавsetFlags()
с флагамиFLAG_ACTIVITY_NEW_TASK
иFLAG_ACTIVITY_CLEAR_TASK
. - Создайте
PendingIntent
, вызвавgetActivity()
.
Это показано в следующем примере:
Котлин
val notifyIntent = Intent(this, ResultActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK } val notifyPendingIntent = PendingIntent.getActivity( this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE )
Ява
Intent notifyIntent = new Intent(this, ResultActivity.class); // Set the Activity to start in a new, empty task. notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); // Create the PendingIntent. PendingIntent notifyPendingIntent = PendingIntent.getActivity( this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE );
- Создайте
- Передайте
PendingIntent
в уведомление как обычно:Котлин
val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply { setContentIntent(notifyPendingIntent) ... } with(NotificationManagerCompat.from(this)) { notify(NOTIFICATION_ID, builder.build()) }
Ява
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID); builder.setContentIntent(notifyPendingIntent); ... NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(NOTIFICATION_ID, builder.build());
Дополнительные сведения о различных параметрах задач и о том, как работает задний стек, см. в разделе Задачи и задний стек .