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_SEND
意图。我们要指定此活动应处理来自直接共享的意图。在AndroidManifest.xml
中找到TODO 3,并在 MainActivity 中添加以下元素。这将活动与我们上面创建的动态快捷方式相关联。
<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
指定要作为“展开的气泡”启动的活动。当用户点击气泡时,展开的气泡将打开,并在当前屏幕顶部显示相应的聊天记录。我们将 BubbleActivity
用作展开的气泡。为了将活动用作展开的气泡,必须在清单文件中对其进行一些属性配置。
- 打开 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"
- 展开的气泡嵌入在系统 UI 中。resizeableActivity="true"
- 系统 UI 会调整展开的气泡的大小。documentLaunchMode="always"
- 系统 UI 需要此属性才能创建此活动的多个实例。
- 现在从 Android Studio 运行应用程序。向其中一个联系人发送一条消息,然后快速关闭应用程序。现在您应该在右下角看到一个带有气泡图标的通知。
带有气泡图标的通知
点击气泡图标,您应该能够看到通知作为气泡显示。点击它一次后,来自同一联系人的通知将自动显示为气泡。点击气泡,它应该显示展开的气泡。
气泡 | 展开的气泡 |
6. 显示前台气泡
应用程序有时可能希望在其处于前台时显示气泡。在此应用程序中,我们希望将聊天屏幕“弹出”为气泡,以便用户可以将他们想要记住的聊天固定一段时间。我们已经在聊天屏幕上为此提供了一个菜单按钮。
再次打开 NotificationHelper.kt
。点击菜单按钮会调用参数为 fromUser
设置为 true 的 showNotification
方法。这就是我们希望将此通知显示为前台气泡的时候。
在上一节中添加的 BubbleMetadata 中添加以下几行
NotificationHelper.kt
> showNotification()
Notification.BubbleMetadata // ... .setDesiredHeightResId(R.dimen.bubble_height) .apply { if (fromUser) { setAutoExpandBubble(true) setSuppressNotification(true) } } .build()
setAutoExpandBubble
会导致气泡默认以展开状态显示。我们还想通过调用 setSuppressNotification
来抑制初始通知。这些标志仅在您的应用程序处于前台时有效。
7. 恭喜!
恭喜!您现在了解了如何显示对话通知和气泡。