Android 11 (R) Bubble 气泡

Android 11 / R 上自家的短信息应用 Messages , 又如FaceBook的 Messager以及Telegram 应用等等。它们实现了Bubble气泡,也都属于聊天讯息功能应用

本文介绍 Android 11 / R DP1 Bubble 气泡


上一次写气泡是 Android Q ,本节内容我们来看看 Android 11 / R 上的气泡又有哪些变化 ?

  • Notification.BubbleMetadata.Builder 差异报告
添加方法
Builder createIntentBubble (PendingIntent, Icon)
Builder createShortcutBubble (String)
变更方法 状态
Builder setIcon (Icon) Now deprecated.
Builder setIntent (PendingIntent) Now deprecated.
  • Notification.BubbleMetadata 差异报告
添加方法
Icon getBubbleIcon ()
PendingIntent getBubbleIntent ()
String getShortcutId ()
变更方法 状态
Icon getIcon () Now deprecated.
PendingInten getIntent() Now deprecated.

前言

我们先来看看,默认Android 短信应用的气泡效果,当通知栏收到一条短信通知

android-r-bubble-1.png

[长按] 这条通知 , 能看到有show as BubblefavoriteSmoozeMute 等选项

android-r-bubble-2.png

然后 [ 点击 show as Bubble ] 通知栏的消息会作为Bubble气泡显示,悬浮在屏幕上

android-r-bubble-3.png

[ 点击 ] 悬浮气泡 ,气泡会被展开,触发BubbleActivity , 查看完整的对话或者发生新对话内容

android-r-bubble-4.png

[ 长按 ] 气泡拖到底部 移除

android-r-bubble-5.png

这就是Android 11 / R 上的气泡效果,那么,接下来就来实现这样的气泡效果

示例

首先创建一个BubbleActivity

用于展示气泡展开后的窗口布局

[ BubbleActivity.kt ]

1
2
3
4
5
6
7
8
class BubbleActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_bubble)

// 具体的逻辑代码
}
}

[ activity_bubble.xml ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_gravity="center"
android:gravity="center"
android:textSize="20sp"
android:text="这里是聊天对话窗口 .."
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

[ style.xml ]

1
2
3
4
5
6
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>

[ AndroidManifest.xml ]

1
2
3
4
5
6
<activity android:name=".BubbleActivity"
android:theme="@style/AppTheme.NoActionBar"
android:label="气泡"
android:allowEmbedded="true"
android:documentLaunchMode="always"
android:resizeableActivity="true"/>

创建一个Notification公共类

[ MyNotification.kt ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package com.shoewann.androidrtest

import android.app.*
import android.content.Context
import android.content.Intent
import android.graphics.drawable.Icon
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi

class MyNotification(context: Context) {

private var notificationManager: NotificationManager? = null
private var context: Context? = null

companion object {
private const val TAG = "MyNotification"
private const val REQUEST_CONTENT = 1
private const val REQUEST_BUBBLE = 2

}

init {
this.context = context
notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
}

@RequiresApi(Build.VERSION_CODES.R)
fun showBubble() {
Log.d(TAG, "show bubble")

//创建通知渠道
val channel =
NotificationChannel("通知渠道ID", "通知渠道名称", NotificationManager.IMPORTANCE_HIGH)
notificationManager!!.createNotificationChannel(channel)
//
val icon = Icon.createWithResource(context, R.mipmap.ic_launcher_round)

// 添加聊天人员 A
val person = Person.Builder()
.setName("Shoewann")
.setIcon(icon)
.build()
// 添加聊天人员 B
val person2 = Person.Builder()
.setName("Bobozai")
.setIcon(icon)
.build()

// 创建一个模拟的短信对话内容
val style: Notification.MessagingStyle = Notification.MessagingStyle(person)
.addMessage(
"你好,我叫Shoewann,请问你叫什么名字? ",
1583837786,
person
)
.addMessage(
"我叫Bobozai",
1583837851,
person2
).setGroupConversation(true)

val contentIntent = PendingIntent.getActivity(
context, REQUEST_CONTENT,
Intent(context, MainActivity::class.java), PendingIntent.FLAG_UPDATE_CURRENT
)

val bubbleIntent = PendingIntent.getActivity(
context,
REQUEST_BUBBLE,
Intent(context, BubbleActivity::class.java),
PendingIntent.FLAG_UPDATE_CURRENT
)

val bubbleMetadata = Notification.BubbleMetadata.Builder()
.setDesiredHeight(400)
//.setIcon(icon) // 已废弃
.createShortcutBubble("Android R 测试")
.createIntentBubble(bubbleIntent, icon)
.setAutoExpandBubble(true)
//.setIntent(bubbleIntent) // 已废弃
.build()

val builder = Notification.Builder(context, "通知渠道ID")
.setContentTitle("Bubble")
.setContentText("测试Android R Bubble")
.setContentIntent(contentIntent)
.setSmallIcon(icon)
.setBubbleMetadata(bubbleMetadata)
.setStyle(style)
.addPerson(person)
.setShowWhen(true)
notificationManager!!.notify(0, builder.build());
}

fun canBubble(): Boolean {
val channel = notificationManager!!.getNotificationChannel("通知渠道ID")
return notificationManager!!.areBubblesAllowed() && channel.canBubble()
}

MainActivity 调用

[MainActivity.kt]

1
2
3
4
val canBubble = MyNotification(this).canBubble()
if (canBubble)
Log.d(TAG, "onClick() called with: canBubble = $canBubble")
MyNotification(this).showBubble()

效果图

android-r-bubble-6.png
android-r-bubble-7.png
android-r-bubble-8.png
android-r-bubble-9.png
android-r-bubble-10.png

气泡什么时候会出现?

官方文档 为了减少用户的打扰次数,只有满足以下一个或多个条件,气泡才会出现:

  • 通知使用 MessagingStyle,并且有一个 Person 被添加
  • 该通知来自对 Service.startForeground 的调用,有一个CATEGORY_CALL类别,并且有一个 Person 被添加
  • 发送通知时,应用程序处于前台。

本示例只演示了以上第一个类别,其他情况请自行验证

以上就是本文的全部内容,感谢您的阅读

本文基于Android R DP1 , 如有不足,欢迎指正

0%