气泡让用户更容易查看和参与对话。
气泡内置于通知系统中。它们浮动在其他应用内容的上方,并跟随用户到任何地方。用户可以展开气泡以显示并与应用内容交互,并在不使用时收起气泡。
当设备锁定时或常亮显示处于活动状态时,气泡会像普通通知一样显示。
气泡是一项用户可以选择停用的功能。当应用第一次显示气泡时,会显示一个权限对话框,提供两个选项:
- 阻止应用的所有气泡。通知不会被阻止,但它们永远不会显示为气泡。
- 允许应用的所有气泡。所有使用
BubbleMetaData
发送的通知都显示为气泡。
气泡 API
气泡是使用通知 API 创建的,因此请像往常一样发送通知。如果您希望通知显示为气泡,请向其附加额外数据。
气泡的展开视图由您选择的 activity 创建。配置 activity 以正确显示为气泡。activity 必须是可调整大小和可嵌入的。如果缺少其中任何一个要求,它将显示为通知。
以下代码演示了如何实现气泡:
<activity
android:name=".bubbles.BubbleActivity"
android:theme="@style/AppTheme.NoActionBar"
android:label="@string/title_activity_bubble"
android:allowEmbedded="true"
android:resizeableActivity="true"
/>
如果您的应用显示多个相同类型的气泡,例如与不同联系人的多个聊天对话,activity 必须能够启动多个实例。在运行 Android 10 及更低版本的设备上,除非您明确将 documentLaunchMode
设置为 "always"
,否则通知不会显示为气泡。从 Android 11 开始,您无需明确设置此值,因为系统会自动将所有对话的 documentLaunchMode
设置为 "always"
。
要发送气泡,请按照以下步骤操作:
- 像往常一样创建通知。
- 调用
BubbleMetadata.Builder(PendingIntent, Icon)
或BubbleMetadata.Builder(String)
以创建BubbleMetadata
对象。 - 使用
setBubbleMetadata()
将元数据添加到通知中。 - 如果目标平台是 Android 11 或更高版本,请确保气泡元数据或通知引用了共享快捷方式。
- 修改您的应用,使其不取消显示为气泡的通知。要检查通知 activity 是否作为气泡启动,请调用
Activity#isLaunchedFromBubble()
。取消通知会从屏幕上移除气泡。打开气泡会自动隐藏与之关联的通知。
以下示例演示了这些步骤:
Kotlin
// Create a bubble intent. val target = Intent(context, BubbleActivity::class.java) val bubbleIntent = PendingIntent.getActivity(context, 0, target, 0 /* flags */) val category = "com.example.category.IMG_SHARE_TARGET" val chatPartner = Person.Builder() .setName("Chat partner") .setImportant(true) .build() // Create a sharing shortcut. val shortcutId = generateShortcutId() val shortcut = ShortcutInfo.Builder(mContext, shortcutId) .setCategories(setOf(category)) .setIntent(Intent(Intent.ACTION_DEFAULT)) .setLongLived(true) .setShortLabel(chatPartner.name) .build() // Create a bubble metadata. val bubbleData = Notification.BubbleMetadata.Builder(bubbleIntent, Icon.createWithResource(context, R.drawable.icon)) .setDesiredHeight(600) .build() // Create a notification, referencing the sharing shortcut. val builder = Notification.Builder(context, CHANNEL_ID) .setContentIntent(contentIntent) .setSmallIcon(smallIcon) .setBubbleMetadata(bubbleData) .setShortcutId(shortcutId) .addPerson(chatPartner)
Java
// Create a bubble intent. Intent target = new Intent(mContext, BubbleActivity.class); PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, target, 0 /* flags */); private val CATEGORY_TEXT_SHARE_TARGET = "com.example.category.IMG_SHARE_TARGET" Person chatPartner = new Person.Builder() .setName("Chat partner") .setImportant(true) .build(); // Create a sharing shortcut. private String shortcutId = generateShortcutId(); ShortcutInfo shortcut = new ShortcutInfo.Builder(mContext, shortcutId) .setCategories(Collections.singleton(CATEGORY_TEXT_SHARE_TARGET)) .setIntent(Intent(Intent.ACTION_DEFAULT)) .setLongLived(true) .setShortLabel(chatPartner.getName()) .build(); // Create a bubble metadata. Notification.BubbleMetadata bubbleData = new Notification.BubbleMetadata.Builder(bubbleIntent, Icon.createWithResource(context, R.drawable.icon)) .setDesiredHeight(600) .build(); // Create a notification, referencing the sharing shortcut. Notification.Builder builder = new Notification.Builder(mContext, CHANNEL_ID) .setContentIntent(contentIntent) .setSmallIcon(smallIcon) .setBubbleMetadata(bubbleData) .setShortcutId(shortcutId) .addPerson(chatPartner);
如果您的应用在发送气泡时处于前台,重要性将被忽略,您的气泡将始终显示,除非用户阻止了您的应用的气泡或通知。
创建展开的气泡
您可以配置气泡以自动以展开状态显示。我们建议仅在用户执行导致气泡的操作时使用此功能,例如点击按钮开始新的聊天。在这种情况下,同时抑制创建气泡时发送的初始通知也是有意义的。
您可以使用一些方法来设置启用这些行为的标志:setAutoExpandBubble()
和 setSuppressNotification()
。
以下示例展示了如何配置气泡以自动以展开状态显示:
Kotlin
val bubbleMetadata = Notification.BubbleMetadata.Builder() .setDesiredHeight(600) .setIntent(bubbleIntent) .setAutoExpandBubble(true) .setSuppressNotification(true) .build()
Java
Notification.BubbleMetadata bubbleData = new Notification.BubbleMetadata.Builder() .setDesiredHeight(600) .setIntent(bubbleIntent) .setAutoExpandBubble(true) .setSuppressNotification(true) .build();
气泡内容生命周期
当气泡展开时,内容 activity 会经历正常的进程生命周期,导致应用成为前台进程(如果尚未成为前台进程)。
当气泡收起或关闭时,activity 会被销毁。这可能会导致进程被缓存并在稍后被终止,具体取决于应用是否正在运行其他前台组件。
气泡何时出现
为了减少对用户的干扰,气泡仅在特定情况下出现。
如果应用的目标平台是 Android 11 或更高版本,则通知仅在符合对话要求时才会显示为气泡。如果应用的目标平台是 Android 10 或更低版本,则通知仅在满足以下一个或多个条件时才会显示为气泡:
- 通知使用
MessagingStyle
并添加了Person
。 - 通知是调用
Service.startForeground
产生的,具有category
为CATEGORY_CALL
,并且添加了Person
。 - 发送通知时应用处于前台。
如果这些条件都不满足,则会显示通知而不是气泡。
从气泡启动 activity
当气泡启动新的 activity 时,新的 activity 将在同一任务和同一气泡窗口内启动,或在一个新的全屏任务中启动,并收起启动它的气泡。
要在与气泡相同的任务中启动新的 activity:1. 启动 intents 时使用 activity 上下文,activity.startActivity(intent)
,以及 1. 不要在 intent 上设置 FLAG_ACTIVITY_NEW_TASK
标志。
否则,新的 activity 将在新的任务中启动,并且气泡将被收起。
请记住,气泡代表特定的对话,因此在气泡内启动的 activity 应与该对话相关。此外,在气泡内启动 activity 会增加气泡的任务堆栈,并可能使用户体验复杂化,尤其是在导航方面。
最佳实践
- 仅当通知很重要时才将其作为气泡发送,例如它是持续通信的一部分或用户明确请求气泡显示内容时。气泡会占用屏幕空间并覆盖其他应用内容。
- 确保您的气泡通知也可以作为普通通知工作。当用户禁用气泡时,气泡通知会显示为普通通知。
- 在气泡 activity 中重写
onBackPressed
时,请调用super.onBackPressed
。否则,您的气泡可能无法正常工作。
当收起的气泡收到更新消息时,气泡会显示一个徽章图标以指示未读消息。当用户在关联的应用中打开消息时,请按照以下步骤操作:
- 更新
BubbleMetadata
以抑制通知。调用BubbleMetadata.Builder.setSuppressNotification()
。这将移除徽章图标,表明用户已与消息互动。 - 将
Notification.Builder.setOnlyAlertOnce()
设置为true
,以抑制伴随BubbleMetadata
更新的声音或振动。
示例应用
SociaLite 示例应用是一个使用气泡的对话应用。为了演示目的,此应用使用了聊天机器人。在实际应用中,请将气泡用于人与人之间的消息。