1. 概述
在本 Codelab 中,您将学习如何在通知栏的“对话”部分显示通知。您还将学习如何将这些通知显示为“浮动通知气泡”。
对话是两人或多人之间的双向实时通信。这些对话会显示在系统通知栏的专属区域中。它们也可以提升为浮动通知气泡。浮动通知气泡是圆形图标,浮动在其他应用内容的顶部,并且随用户移动。浮动通知气泡非常适合显示用户想要轻松访问的正在进行的事件和操作。
浮动通知气泡是通知用户重要持续信息的好方法。但是,您应该注意何时使用和何时不使用浮动通知气泡。它们会占用屏幕空间并覆盖其他应用内容。仅当重要到足以引起用户注意时才使用它们。请记住,用户可以轻松选择退出浮动通知气泡并使用普通通知代替。
本 Codelab 以一个概念验证聊天应用作为起点。该应用会显示新的传入消息,在本 Codelab 中,我们假设用户会希望记下这些消息一段时间。
|
|
我们将学到什么
- 如何显示对话式通知。
- 如何支持浮动通知气泡。
- 如何在应用在前台运行时显示浮动通知气泡。
前提条件
- 基本的 Kotlin 知识(本 Codelab 使用 Kotlin)
- 基本的通知知识。您可以在此处以及通过学习使用 Android 通知 Codelab 了解更多关于通知的信息。
- 运行 Android 11 Beta 1 或更高版本的设备或模拟器。
- Android Studio 4.0.0 或更高版本。
2. 获取示例代码
下载 Codelab 代码
$ git clone https://github.com/android/codelab-android-people.git
在 Android Studio 中导入项目。

Gradle 将开始同步。根据您的互联网连接速度和最近打开的其他项目,这可能需要几分钟时间。
该项目包含多个模块
app-start是此 Codelab 的起始状态。app是完成此 Codelab 后的最终状态。
确保运行配置的下拉框中选择了 app-start。

3. 查看应用目前的工作方式
我们将要开发的应用程序是一个聊天应用程序。从 Android Studio 运行该应用程序,您将看到您可以与之聊天的联系人列表。

选择其中一个联系人并尝试发送消息。您将在 5 秒内收到回复。如果聊天屏幕不在前台,回复将显示为通知。尝试发送消息并快速导航到主屏幕。

4. 对话式通知
既然您已经了解了应用的工作方式,接下来我们将开始在通知栏的“对话”部分显示我们的通知。
为了让系统将通知视为对话,它必须满足以下条件
- 它使用
MessagingStyle。 - 它与对话快捷方式相关联。对话快捷方式是 共享快捷方式,它用作直接共享目标,并且是长久存在的。
MessagingStyle
- 打开
NotificationHelper.kt。它位于data/NotificationHelper.kt。方法showNotification是应用显示所有通知的地方。通知目前使用简单的setContentText调用来设置通知内容。找到 TODO 1 并将其替换为 MessagingStyle。
.setStyle(
Notification.MessagingStyle(user)
.apply {
val lastId = chat.messages.last().id
for (message in chat.messages) {
val m = Notification.MessagingStyle.Message(
message.text,
message.timestamp,
if (message.isIncoming) person else null
).apply {
if (message.photoUri != null) {
setData(message.photoMimeType, message.photoUri)
}
}
if (message.id < lastId) {
addHistoricMessage(m)
} else {
addMessage(m)
}
}
}
.setGroupConversation(false)
)
.setWhen(chat.messages.last().timestamp)
对话快捷方式
- 在同一个
NotificationHelper.kt中,有一个名为updateShortcuts的方法。每当显示新通知时,都会调用此方法。我们将创建动态快捷方式并将其注册到ShortcutManager。找到 TODO 2 并添加此实现。
var shortcuts = Contact.CONTACTS.map { contact ->
val icon = Icon.createWithAdaptiveBitmap(
context.resources.assets.open(contact.icon).use { input ->
BitmapFactory.decodeStream(input)
}
)
ShortcutInfo.Builder(context, contact.shortcutId)
.setLocusId(LocusId(contact.shortcutId))
.setActivity(ComponentName(context, MainActivity::class.java))
.setShortLabel(contact.name)
.setIcon(icon)
.setLongLived(true)
.setCategories(setOf("com.example.android.bubbles.category.TEXT_SHARE_TARGET"))
.setIntent(
Intent(context, MainActivity::class.java)
.setAction(Intent.ACTION_VIEW)
.setData(
Uri.parse(
"https://android.example.com/chat/${contact.id}"
)
)
)
.setPerson(
Person.Builder()
.setName(contact.name)
.setIcon(icon)
.build()
)
.build()
}
if (importantContact != null) {
shortcuts = shortcuts.sortedByDescending { it.id == importantContact.shortcutId }
}
val maxCount = shortcutManager.maxShortcutCountPerActivity
if (shortcuts.size > maxCount) {
shortcuts = shortcuts.take(maxCount)
}
shortcutManager.addDynamicShortcuts(shortcuts)
在此实现中,我们将所有联系人转换为 ShortcutInfo,并在最后调用 addDynamicShortcuts 将它们设置为我们的动态快捷方式。
这些快捷方式的类别是“com.example.android.bubbles.category.TEXT_SHARE_TARGET”。此类别在 res/xml/shortcuts.xml 中定义,并用作我们的直接共享目标。
- 如果您查看
MainActivity.kt,您会发现它已经可以处理联系人的ACTION_SENDIntent。我们想指定此 Activity 应该处理来自直接共享的 Intent。在AndroidManifest.xml中找到 TODO 3 并在 MainActivity 中添加以下元素。这将 Activity 与我们上面创建的动态快捷方式关联起来。
<activity
android:name="com.example.android.people.MainActivity"
...>
<!-- ... -->
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity>
- 本节的最后一步是将通知与我们刚刚创建的动态快捷方式关联起来。在
NotificationHelper.kt中找到 TODO 4 并将以下配置添加到Notification.Builder中。
// ...
.setCategory(Notification.CATEGORY_MESSAGE)
.setShortcutId(chat.contact.shortcutId)
.setLocusId(LocusId(chat.contact.shortcutId))
通过此 setShortcutId,系统可以知道此通知对应于指定的动态快捷方式。还建议您设置 LocusId,以便系统可以根据应用使用情况准确地对对话进行排序。
|
|
5. 显示浮动通知气泡
通知必须发送到通知渠道。此应用使用一个通知渠道。请注意,在 setUpNotificationChannels 方法中,重要性被设置为 IMPORTANCE_HIGH。为了将通知显示为浮动通知气泡,通知渠道需要设置为 IMPORTANCE_HIGH。
通过向通知添加 BubbleMetadata,可以将其显示为浮动通知气泡。这可以通过调用 Notification.Builder#setBubbleMetadata 来完成。
- 将
showNotification方法中的 TODO 5 替换为以下代码
NotificationHelper.kt > showNotification()
.setBubbleMetadata(
Notification.BubbleMetadata
.Builder(
PendingIntent.getActivity(
context,
REQUEST_BUBBLE,
Intent(context, BubbleActivity::class.java)
.setAction(Intent.ACTION_VIEW)
.setData(contentUri),
PendingIntent.FLAG_UPDATE_CURRENT
),
icon
)
.setDesiredHeightResId(R.dimen.bubble_height)
.build()
)
在上面的代码中,setIcon 设置了浮动通知气泡的图标。
setIntent 指定了要作为“展开的浮动通知气泡”启动的 Activity。当用户点击浮动通知气泡时,展开的浮动通知气泡会打开并在当前屏幕上方显示相应的聊天历史记录。我们使用 BubbleActivity 作为展开的浮动通知气泡。为了将 Activity 用作展开的浮动通知气泡,需要在清单文件中为其配置一些属性。
- 打开 AndroidManifest.xml 并找到带有 TODO 6 标记的
BubbleActivity定义。向该元素添加以下属性
AndroidManifest.xml > BubbleActivity
<activity
android:name="com.example.android.people.BubbleActivity"
android:allowEmbedded="true"
android:documentLaunchMode="always"
android:resizeableActivity="true">
...
</activity>
这 3 个属性是必需的
allowEmbedded="true"- 展开的浮动通知气泡嵌入到系统界面中。resizeableActivity="true"- 展开的浮动通知气泡由系统界面调整大小。documentLaunchMode="always"- 系统界面需要此属性,以便它可以创建此 Activity 的多个实例。
- 现在从 Android Studio 运行该应用。向其中一个联系人发送消息并快速关闭应用。您现在应该会在右下角看到带有浮动通知气泡图标的通知。

带有浮动通知气泡图标的通知
点击浮动通知气泡图标,您应该能够看到显示为浮动通知气泡的通知。点击一次后,来自同一联系人的通知将自动显示为浮动通知气泡。点击浮动通知气泡,它应该会显示展开的浮动通知气泡。
|
|
6. 显示前台浮动通知气泡
应用有时可能想在前台运行时显示浮动通知气泡。在此应用中,我们希望将聊天屏幕“弹出”为浮动通知气泡,以便用户可以暂时固定他们想要记住的聊天。我们已经在聊天屏幕上为此设置了一个菜单按钮。

再次打开 NotificationHelper.kt。点击菜单按钮会调用 showNotification 方法,并将参数 fromUser 设置为 true。那时我们想要将此通知显示为前台浮动通知气泡。
将以下行添加到我们在上一节中添加的 BubbleMetadata 中
NotificationHelper.kt > showNotification()
Notification.BubbleMetadata
// ...
.setDesiredHeightResId(R.dimen.bubble_height)
.apply {
if (fromUser) {
setAutoExpandBubble(true)
setSuppressNotification(true)
}
}
.build()
setAutoExpandBubble 使浮动通知气泡默认以其展开状态显示。我们还希望通过调用 setSuppressNotification 来抑制初始通知。这些标志仅在您的应用在前台运行时有效。

7. 恭喜!
恭喜!您现在知道如何显示对话式通知和浮动通知气泡了。

浮动通知气泡
动态快捷方式
对话式通知
浮动通知气泡
展开的浮动通知气泡