人员:对话和气泡

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。点击菜单按钮会调用 showNotification 方法,并将参数 fromUser 设置为 true。这就是我们希望将此通知显示为前台气泡的时候。

将以下几行添加到上一节中添加的 BubbleMetadata 中

NotificationHelper.kt > showNotification()

Notification.BubbleMetadata
    // ...
    .setDesiredHeightResId(R.dimen.bubble_height)
    .apply {
        if (fromUser) {
            setAutoExpandBubble(true)
            setSuppressNotification(true)
        }
    }
    .build()

setAutoExpandBubble 会导致气泡默认以展开状态显示。我们还希望通过调用 setSuppressNotification 来抑制初始通知。这些标志仅在您的应用程序处于前台时有效。

f676f5332aaa50ee.png

7. 恭喜!

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

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