1. 准备工作
创建即时通讯应用并非易事。虽然整体用户体验具有主观性,但 Android 提供 Messaging API 和 People API,这可以改善和简化聊天体验。
在此 Codelab 中,您将学习如何使用这些 API 为 Android 上的聊天应用创建富有吸引力的生态系统。您将扩展 JetChat 应用,这是一个使用 Jetpack Compose 的无功能基本聊天应用。
前提条件
- 掌握 Android 开发方面的基础知识
- 具备通知方面的基础知识
构建内容
一个经过扩展的 JetChat 应用,用于执行以下操作:
- 在抽屉式通知栏的预留对话部分显示代表对话的通知。
- 在这些通知中,引用可用于分享目标,让您可以分享到应用的对话中。
- 实施创建这些对象的最佳做法,以利用系统提供的默认体验增强您的应用。
学习内容
- 如何在抽屉式通知栏的保留会话部分中显示与会话相关的通知。
- 如何理解 Messaging API 和 People API 启用的各种体验。
所需条件
- Git
- Android Studio
- GitHub 帐号
2. 进行设置
此开发平台基于 JetChat 应用。起始代码扩展了 JetChat 应用,以更好地展示 Messaging API 和 People API。
获取起始代码
如需获取此 Codelab 的起始代码,请按以下步骤操作:
- 通过命令行,克隆以下 GitHub 代码库:
git clone –branch starter-code \ https://github.com/android/people-messaging-codelab.git
- 在 Android Studio 中打开项目,然后点击 Run app(运行应用)。系统会显示 Emulator(模拟器)窗格和应用。
探索 JetChat 扩展应用
- 在该应用的 Message #composers(消息撰写器)文本框中,输入消息,然后点按发送。
- 离开应用。几秒钟后,您会收到推送通知,其中包含聊天参与者的回复。
3. 创建对话通知
Android 11 引入了 API,以允许聊天相关的通知出现在抽屉式通知栏的指定部分中,此功能仅用于对话。
通知必须是 Notification.MessagingStyle
类并引用长期有效的分享快捷方式。在本部分中,您将学习如何满足这些 API 要求,以呈现代表对话部分中对话的通知。
如需创建 NotificationCompat.MessagingStyle
类的通知,请按以下步骤操作:
- 在 Android Studio 的 Project(项目)标签页中,点击
app
>java
>com.example.compose.jetchat
>conversation
,然后双击ConversationFragment
。 - 在
ConversationFragment.kt
文件中,找到ConversationFragment
类,然后找到createNotification
函数的Notification
代码块,您将在其中创建通知。 - 将
setContentText
方法替换为setStyle
方法,该方法将通知的样式设为NotificationCompat.MessagingStyle
类。此辅助类会添加使用setContextText
方法设置的消息,以及与消息相关的其他上下文,例如发送时间和发送者。
ConversationFragment.kt
private fun createNotification(
notificationId: Int,
message: Message,
person: Person,
shortcut: ShortcutInfoCompat,
time: Long
): Notification? {
...
.setStyle(NotificationCompat.MessagingStyle(person).addMessage(
NotificationCompat.MessagingStyle.Message(
message.content,
time,
person
)
)
)
...
.build()
}
运行应用
- 运行应用。
- 在该应用的 Message #composers(消息撰写器)文本框中,输入消息,然后点按发送。
- 离开应用。您会再次收到一条推送通知,但其样式会有所不同。它包含头像和消息的不同样式。不过,在您显示通知之前,还有很多工作要做。
4. 创建对话的共享目标
您需要在通知中引用共享快捷方式或共享目标。共享目标在 shortcuts.xml
文件中定义,是处理以程序化方式定义的快捷方式的入口点。您创建的快捷方式代表应用中的对话,可让您共享对话中的内容。
定义共享目标
- 在 Project(项目)标签页中,右键点击
res
目录,然后选择 New(新建)> Directory(目录)。 - 在文本框中输入
xml
,然后按Enter
(在 macOS 上,按return
)。 - 右键点击
xml
目录,然后选择 File(文件)。 - 在文本框中输入
shortcuts.xml
,然后按Enter
(在 macOS 上,按return
)。 - 在
shortcuts.xml
文件中,声明用于处理text/plain
类型数据共享的共享目标:
shortcuts.xml
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<share-target android:targetClass="com.example.compose.jetchat.NavActivity">
<data android:mimeType="text/plain" />
<category android:name="com.example.compose.jetchat.share.TEXT_SHARE_TARGET" />
</share-target>
</shortcuts>
- 在 Project(项目)标签页中,点击
manifests
,然后双击AndroidManifest.xml
。 - 在
AndroidManifest.xml
文件中,定义shortcuts.xml
文件:
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.compose.jetchat">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.Jetchat.NoActionBar">
...
<meta-data android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</application>
</manifest>
- 在
AndroidManifest.xml
文件的activity
组件中,定义包含共享逻辑的 intent 过滤器:
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.compose.jetchat">
...
<activity
...
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
...
定义快捷方式
对于每条通知,您都需要关联相关的快捷方式。每个会话只能指定一个唯一的快捷方式,因为唯一的快捷方式表示要与之分享的联系人。
如需生成快捷方式,请按以下步骤操作:
- 在 Project(项目)标签页中,点击
app
>java
>com.example.compose.jetchat
>conversation
>util
,然后双击ConversationUtil
。 - 在
ConversationUtil.kt
文件中,添加generateShortcut
函数:
ConversationUtil.kt
import android.content.Intent
import androidx.core.content.pm.ShortcutInfoCompat
import com.example.compose.jetchat.NavActivity
class ConversationUtil {
companion object {
...
fun generateShortcut(context: Context, shortcutId: String): ShortcutInfoCompat {
return ShortcutInfoCompat.Builder(context, shortcutId)
.setCategories(setOf(CATEGORY_SHARE))
.setLongLived(true)
.setShortLabel(shortcutId)
.setLongLabel(shortcutId)
.setIntent(
Intent(context, NavActivity::class.java)
.setAction(Intent.ACTION_VIEW)
)
.build()
}
此函数包含对话所需的 setPerson
和 setLongLived
方法。用户是与快捷方式关联的联系人,将长期存在设置为 true
值可确保此快捷方式被系统缓存,并呈现在界面的不同部分中。
参考通知中的快捷方式
您需要引用通知中的分享快捷方式。不过,您必须先创建快捷方式,然后才能推送通知。
为此,请按以下步骤操作:
- 在
ConversationFragment.kt
文件中,找到ConversationFragment
类。 - 在调用
notification
变量之前,请创建一个引用ConversationUtil.generateShortcut
生成的快捷方式的shortcut
变量。 - 在
notification
变量的createNotification
方法中,将null
替换为shortcut
变量作为参数。
ConversationFragment.kt
private fun simulateResponseAsANotification() {
...
if (message.author != "me") {
...
val shortcut = ConversationUtil.generateShortcut(context!!, message.author)
val notification = createNotification(notificationId, message, person, shortcut, time)
...
}
}
- 在
createNotification
方法中,添加NotificationCompat.Builder#setShortcutInfo
方法,然后传入shortcut
变量作为参数。
ConversationFragment.kt
private fun createNotification(
notificatoinIf: Int,
messagin: Message,
person: Person,
shortcut: ShortcutInfoCompat?,
time: Long
): Notification {
...
return NotificationCompat.Builder(context!!, ConversationUtil.CHANNEL_MESSAGES)
...
.setShortcutInfo(shortcut)
.build()
}
发布快捷方式
- 如需发布快捷方式,请在
simulateResponseAsANotification
函数中的notificationManager.notify
方法前面,调用pushDynamicShortcut
方法:
ConversationFragment.kt
import androidx.core.content.pm.ShortcutManagerCompat
...private fun simulateResponseAsANotification() {
...
if (message.author != "me") {
...
ShortcutManagerCompat.pushDynamicShortcut(context!!, shortcut)
...
}
}
运行应用
- 运行应用。
- 在该应用的 Message #composers(消息撰写器)文本框中,输入消息,然后点按发送。
- 离开应用。您会再次收到一条推送通知,但通知的样式会显得与对话相关。头像图标更加显眼,且集成了应用图标。发送者、时间和文本也变得更加简洁。
5. 可选:启用对话泡
对话泡是在 Android 9 中引入的,经过改进和再利用,可在 Android 11 中的对话上下文中使用。对话泡是圆形叠加层(您的对话的头像)。它们显示在应用启动器中,让您可在展开的对话泡中轻松回复对话。即使已实现,但对话泡是可选的,具体取决于用户的偏好设置。
如需启用对话泡,请按以下步骤操作:
- 在
AndroidManifest.xml
文件中,添加allowEmbedded
和resizeableActivity
属性,然后将其分别设置为true
值:
AndroidManifest.xml
<activity
...
android:allowEmbedded="true"
android:resizeableActivity="true"
...
</activity>
- 在
ConversationUtil.kt
文件的ConversationUtil
类中,添加对话泡元数据:
ConversationUtil.kt
import androidx.core.app.NotificationCompat
import androidx.core.graphics.drawable.IconCompat
fun createBubbleMetadata(context: Context, icon: IconCompat): NotificationCompat.BubbleMetadata {
// Create bubble intent
val target = Intent(context, NavActivity::class.java)
val bubbleIntent = PendingIntent.getActivity(context, REQUEST_BUBBLE, target, flagUpdateCurrent(mutable = true))
// Create bubble metadata
return NotificationCompat.BubbleMetadata.Builder(bubbleIntent, icon)
.setDesiredHeight(400)
.setSuppressNotification(true)
.build()
}
- 在
ConversationFragment.kt
文件中,创建并引用通知上的对话泡元数据:
ConversationFragment.kt
private fun createNotification(
notificatoinIf: Int,
messagin: Message,
person: Person,
shortcut: ShortcutInfoCompat?,
time: Long
): Notification {
...
// Reference the bubble metadata in the notification.
return NotificationCompat.Builder(context!!, ConversationUtil.CHANNEL_MESSAGES)
...
.setBubbleMetadata(ConversationUtil.createBubbleMetadata(context!!, person.icon!!))
...
.build()
}
运行应用
- 运行应用。
- 在该应用的 Message #composers(消息撰写器)文本框中,输入消息,然后点按发送。
- 离开应用。几秒钟后,您会收到对话泡形式的聊天通知。
- 点按对话泡。对话会从对话泡中打开。
6. 可选:分享链接
您声明了共享目标,并在通知中引用了这些目标。启用共享目标后,您的联系人还可显示在 Sharesheet 中,即发送 ACTION
intent 时显示的自下而上的组件。共享目标位于 Sharesheet 的顶部,让您可以在对话中共享富媒体内容。
如需调用 Sharesheet,请按以下步骤操作:
- 在您的设备上,打开 Google Chrome,然后转到您选择的网页,例如 developer.android.com。
- 如有必要,请点击 More vert。
- 点击 Share(共享)。Sharesheet 会显示在屏幕底部。
- 如有可能,请点击 JetChat。系统会在聊天中分享该网址。
- 如果您没有看到 JetChat,请点击 展开以调用系统 Sharesheet,接着在 ShareSheet 上向上滑动,然后点击 JetChat。系统会在聊天对话中分享该网址。
这是一个简单的示例。有更丰富的内容类型可以分享。如需了解详情,请参阅从其他应用检索简单的数据。
7. 恭喜
恭喜!现在,您已经知道如何使用 Messaging API 和 People API 向 Android 应用添加与聊天相关的功能。希望您可以愉快地发送消息!