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
。点击菜单按钮会调用 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. 恭喜!
恭喜!您现在知道如何显示对话通知和气泡了。