从通知启动 activity 时,您必须保留用户预期的导航体验。点按返回按钮必须能让用户通过应用的正常工作流程返回到主屏幕,并且打开“最近使用的应用”屏幕必须能将该 activity 显示为单独的任务。为了保留这种导航体验,请在新任务中启动 activity。
创建基本通知中介绍了设置通知点按行为的基本方法。本页介绍了如何为通知的操作设置 PendingIntent,以便创建新的任务和返回堆栈。具体操作方法取决于您要启动的 activity 类型:
- 常规 activity:这是作为应用正常用户体验流程的一部分而存在的 activity。当用户通过通知进入 activity 时,新任务必须包含完整的返回堆栈,以便用户点按“返回”按钮即可在应用层次结构中向上导航。
- 特殊 activity:只有当用户从通知启动此 activity 时,才会看到此 activity。从某种意义上讲,此 activity 通过提供难以在通知本身中显示的信息来扩展通知界面。此 activity 不需要返回堆栈。
设置常规 Activity PendingIntent
如需从通知中启动常规 activity,请使用 TaskStackBuilder 设置 PendingIntent,以便它创建新的返回堆栈,如下所示。
定义应用的 Activity 层次结构
通过向应用清单文件中的每个 <activity> 元素添加 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
如需启动包含 activity 返回堆栈的 activity,请创建 TaskStackBuilder 的实例并调用 addNextIntentWithParentStack(),同时向其传递要启动的 activity 的 Intent。
只要您按照前面的说明为每个 activity 定义父 activity,就可以调用 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 ) }
如有必要,您可以通过调用 TaskStackBuilder.editIntentAt() 向堆栈中的 Intent 对象添加实参。有时,为了确保用户导航到返回堆栈中的 Activity 时,该 Activity 显示有意义的数据,需要执行此操作。
然后,您可以像往常一样将 PendingIntent 传递给通知:
val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply { setContentIntent(resultPendingIntent) // ... } with(NotificationManagerCompat.from(this)) { notify(NOTIFICATION_ID, builder.build()) }
设置特殊 Activity PendingIntent
由于从通知启动的特殊 activity 不需要返回堆栈,因此您可以通过调用 getActivity() 来创建 PendingIntent。不过,请在清单中定义适当的任务选项。
在清单中,将以下属性添加到
<activity>元素。android:taskAffinity=""- 结合您在代码中使用的
FLAG_ACTIVITY_NEW_TASK标志,将此属性设置为空白,以确保此 activity 不会进入应用的默认任务。具有应用默认亲和性的任何现有任务都不会受到影响。 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。
具体可见以下示例:
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 )
- 创建一个启动
照常将
PendingIntent传递给通知:val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply { setContentIntent(notifyPendingIntent) // ... } with(NotificationManagerCompat.from(this)) { notify(NOTIFICATION_ID, builder.build()) }
如需详细了解各种任务选项以及返回堆栈的运作方式,请参阅任务和返回堆栈。