当您从通知启动活动时,必须保留用户预期的导航体验。点击“返回”按钮必须将用户带回应用的正常工作流程到主屏幕,并且打开“最近使用的应用”屏幕必须将活动显示为单独的任务。为了保留此导航体验,请在新任务中启动活动。
在创建基本通知中描述了为通知设置点击行为的基本方法。此页面介绍了如何为通知的操作设置PendingIntent
,以便它创建一个新的任务和返回堆栈。如何执行此操作取决于您要启动的活动类型。
- 常规活动
- 这是作为应用正常 UX 流程的一部分存在的活动。当用户从通知到达活动时,新任务必须包含完整的返回堆栈,允许用户点击“返回”按钮以向上导航应用层次结构。
- 特殊活动
- 只有从通知启动时,用户才能看到此活动。从某种意义上说,此活动通过提供难以在通知本身中显示的信息来扩展通知 UI。此活动不需要返回堆栈。
设置常规活动 PendingIntent
要从通知启动常规活动,请使用TaskStackBuilder
设置PendingIntent
,以便它创建新的返回堆栈,如下所示。
定义应用的活动层次结构
通过将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
。
Kotlin
// 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) }
Java
// 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);
如有必要,您可以通过调用TaskStackBuilder.editIntentAt()
向堆栈中的Intent
对象添加参数。这有时是必要的,以确保当用户导航到返回堆栈中的活动时,该活动显示有意义的数据。
然后,您可以照常将PendingIntent
传递给通知
Kotlin
val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply { setContentIntent(resultPendingIntent) ... } with(NotificationManagerCompat.from(this)) { notify(NOTIFICATION_ID, builder.build()) }
Java
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID); builder.setContentIntent(resultPendingIntent); ... NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(NOTIFICATION_ID, builder.build());
设置特殊活动 PendingIntent
由于从通知启动的特殊活动不需要返回堆栈,因此您可以通过调用getActivity()
创建PendingIntent
。但是,请在清单中定义适当的任务选项。
- 在您的清单中,将以下属性添加到
<activity>
元素。-
android:taskAffinity=""
- 结合您在代码中使用的
FLAG_ACTIVITY_NEW_TASK
标志,将此属性设置为空以确保此活动不会进入应用的默认任务。具有应用默认关联性的任何现有任务都不会受到影响。 -
android:excludeFromRecents="true"
- 从“最近使用的应用”屏幕中排除新任务,以便用户不会意外导航回该任务。
这在以下示例中显示
<activity android:name=".ResultActivity" android:launchMode="singleTask" android:taskAffinity="" android:excludeFromRecents="true"> </activity>
-
- 构建并发出通知
- 创建一个启动
Activity
的Intent
。 - 通过使用
FLAG_ACTIVITY_NEW_TASK
和FLAG_ACTIVITY_CLEAR_TASK
标志调用setFlags()
,将Activity
设置为在新空任务中启动。 - 通过调用
getActivity()
创建PendingIntent
。
这在以下示例中显示
Kotlin
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 )
Java
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
传递给通知Kotlin
val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply { setContentIntent(notifyPendingIntent) ... } with(NotificationManagerCompat.from(this)) { notify(NOTIFICATION_ID, builder.build()) }
Java
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID); builder.setContentIntent(notifyPendingIntent); ... NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(NOTIFICATION_ID, builder.build());
有关各种任务选项以及返回堆栈如何工作的更多信息,请参阅任务和返回堆栈。