Когда вы запускаете действие из уведомления, вы должны сохранить ожидаемые возможности навигации пользователя. Нажатие кнопки «Назад» должно вернуть пользователя через обычный рабочий процесс приложения на главный экран, а при открытии экрана «Недавние» действие должно отображаться как отдельная задача. Чтобы сохранить этот опыт навигации, запустите действие в новой задаче.
Основной подход к настройке поведения касания для вашего уведомления описан в разделе «Создание базового уведомления» . На этой странице описано, как настроить 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());
Дополнительные сведения о различных параметрах задач и о том, как работает задний стек, см. в разделе Задачи и задний стек .