人员:对话和气泡

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 中的项目。

cb493f79df0aabe2.png

Gradle 将开始同步。这可能需要几分钟,具体取决于互联网连接速度以及您最近打开的其他项目。

该项目包含多个模块

  • app-start 是 Codelab 的初始状态。
  • app 是完成本 Codelab 后应用程序的最终状态。

确保在运行配置的组合框中选择了app-start

96dd1af453ea4c79.png

3. 查看应用程序当前的工作方式

我们将要使用的应用程序是一个聊天应用程序。从 Android Studio 运行应用程序,您将看到一个可以与之聊天的聊天联系人列表。

d5604d7c486c8426.png

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

20b5d79d16fd03e0.png

4. 对话通知

现在您已经了解了应用程序的工作方式,让我们从在通知栏的“对话”部分显示我们的通知开始。

为了使系统将通知视为对话,它必须满足以下条件

  • 它使用MessagingStyle.
  • 它与对话快捷方式相关联。对话快捷方式是共享快捷方式,它充当直接共享目标,并且是长期存在的。

MessagingStyle

  1. 打开 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)

对话快捷方式

  1. 在同一个 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 中定义,用作我们的直接共享目标。

  1. 如果您查看 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>
  1. 本节的最后一步是将通知与我们刚刚创建的动态快捷方式相关联。在 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 来完成。

  1. 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 用作展开的气泡。为了将活动用作展开的气泡,必须在清单文件中对其进行一些属性配置。

  1. 打开 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 需要此属性才能创建此活动的多个实例。
  1. 现在从 Android Studio 运行应用程序。向其中一个联系人发送一条消息,然后快速关闭应用程序。现在您应该在右下角看到一个带有气泡图标的通知。

edee048016da3145.png

带有气泡图标的通知

点击气泡图标,您应该能够看到通知作为气泡显示。点击它一次后,来自同一联系人的通知将自动显示为气泡。点击气泡,它应该显示展开的气泡。

气泡

展开的气泡

6. 显示前台气泡

应用程序有时可能希望在其处于前台时显示气泡。在此应用程序中,我们希望将聊天屏幕“弹出”为气泡,以便用户可以将他们想要记住的聊天固定一段时间。我们已经在聊天屏幕上为此提供了一个菜单按钮。

d039a867009642f9.png

再次打开 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 来抑制初始通知。这些标志仅在您的应用程序处于前台时有效。

f676f5332aaa50ee.png

7. 恭喜!

恭喜!您现在了解了如何显示对话通知和气泡。

要了解更多信息,请参阅 对话气泡