Android 16 通知系统新 API 详解
Android 16 的通知系统经历了近年来最大的一次重构。Live Updates、Rich Ongoing 通知、Bubble API 升级……这些新特性不仅改变了用户感知通知的方式,也要求开发者重新思考通知策略。本文逐一拆解新 API 的用法和迁移注意事项。
适用场景:targetSdk 36(Android 16)的 App 开发,或计划支持 Android 16 新特性的应用。
一、Live Updates:实时动态通知
Live Updates 是 Android 16 最引人注目的通知新特性。它允许通知内容实时更新,并在锁屏和状态栏上显示持续变化的信息。
基本用法
// 创建 Live Update 通知
val liveUpdateBuilder = Notification.Builder(this, CHANNEL_ID)
.setContentTitle("打车进行中")
.setSmallIcon(R.drawable.ic_car)
.setLiveUpdate(true) // 标记为 Live Update
.setOngoing(true)
// 动态更新内容
val update = Notification.LiveUpdate()
.addText("距离目的地: 3.2km")
.addText("预计到达: 8分钟")
.addProgressBar(3200, currentDistance, false)
liveUpdateBuilder.setLiveUpdateContent(update)
notificationManager.notify(NOTIFICATION_ID, liveUpdateBuilder.build())
更新频率控制
// Live Updates 支持高频更新(相比普通通知有更高的更新限额)
// Android 16 放宽了通知更新频率限制
// 最多每 1 秒更新一次(普通通知限制为 5 秒)
val policy = Notification.UpdatePolicy(
minIntervalMs = 1000L,
maxUpdatesPerMinute = 30
)
liveUpdateBuilder.setUpdatePolicy(policy)
// 实时更新场景
lifecycleScope.launch {
locationFlow.collect { location ->
val update = Notification.LiveUpdate()
.addText("当前位置已更新")
.addProgressBar(100, location.accuracy.toInt(), false)
notificationManager.notify(
NOTIFICATION_ID,
liveUpdateBuilder
.setLiveUpdateContent(update)
.build()
)
}
}
注意:即使有更高的更新限额,也不应滥用 Live Updates。频繁更新会导致电池消耗增加。建议仅在用户明确关注的状态(导航、运动、下载进度)使用。
类型系统
| 类型 | 适用场景 | API |
|---|---|---|
| Progress | 下载、上传、渲染进度 | addProgressBar() |
| Counter | 计时器、倒计时 | addCounter() |
| Metric | 距离、速度、温度 | addMetric() |
| Text | 状态文本变化 | addText() |
// 计时器示例
val timerUpdate = Notification.LiveUpdate()
.addCounter("剩余时间", remainingSeconds)
.addText("番茄时钟工作中 🍅")
// 运动追踪示例
val workoutUpdate = Notification.LiveUpdate()
.addMetric("配速", "5:30", "/km")
.addMetric("心率", "142", "bpm")
.addProgressBar(10000, currentSteps, false)
二、Rich Ongoing:信息密度革命
Rich Ongoing 是 Android 16 为持续通知设计的全新模板,大幅提升了信息展示能力。
传统 Ongoing 的限制
// Android 15 及之前:只能显示简单的文本+进度条
// 信息密度低,用户无法在通知面板快速获取关键信息
val oldOngoing = Notification.Builder(this, CHANNEL_ID)
.setContentTitle("下载中")
.setContentText("进度: 45%")
.setProgress(100, 45, false)
.setOngoing(true)
.build()
Rich Ongoing 新模板
// Android 16:Rich Ongoing 支持结构化内容
val richOngoing = Notification.Builder(this, CHANNEL_ID)
.setContentTitle("音乐播放中")
.setSmallIcon(R.drawable.ic_music)
.setOngoing(true)
.setStyle(Notification.MediaStyle())
.setRichOngoing {
// 左侧:专辑封面
coverArt(albumCoverBitmap)
// 中间:元数据区域
metadata {
primary("月光曲") // 当前曲目
secondary("贝多芬") // 艺术家
tertiary("古典钢琴精选") // 专辑
}
// 底部:进度条
playbackProgress(currentPosition, duration)
// 操作按钮(最多 4 个)
actions(
Action(R.drawable.skip_prev, "上一首"),
Action(R.drawable.play_pause, "暂停"),
Action(R.drawable.skip_next, "下一首"),
Action(R.drawable.heart, "收藏")
)
}
.build()
信息展示区域划分
| 区域 | 内容 | 最大行数 |
|---|---|---|
| Header | App 图标、标题、时间戳 | 1 |
| Hero | 主图像/封面/地图预览 | 1 图片 |
| Metadata | 结构化文本(primary/secondary/tertiary) | 3 |
| Progress | 进度条 + 标签 | 1 |
| Actions | 操作按钮 | 4 |
| Footer | 次要信息、渠道名称 | 1 |
三、Bubble API 增强
Android 16 将 Bubble 从 Beta 提升为正式 API,并增加了新能力:
// Android 16 - Bubble 正式版 API
val bubbleData = Notification.BubbleMetadata.Builder()
.setDesiredHeight(600) // 支持自定义高度
.setShowAsBubble(true)
.setBubbleIcon(Icon.createWithResource(this, R.drawable.bubble_icon))
.setAutoExpandBubble(true)
.setSuppressNotification(true) // 不显示重复通知
.build()
// 新特性:浮动工具栏
bubbleData.setFloatingToolbar {
addAction("截图", screenshotIntent)
addAction("最小化", minimizeIntent)
}
// 新特性:多实例 Bubble
// 同一会话可以创建多个 Bubble 窗口
bubbleData.setAllowMultipleInstances(true)
四、通知优先级改革
Android 16 重新设计了通知优先级系统,引入了更细粒度的控制:
| 级别 | Android 15 | Android 16 |
|---|---|---|
| 紧急 | IMPORTANCE_HIGH | IMPORTANCE_CRITICAL(新增) |
| 高 | IMPORTANCE_HIGH | IMPORTANCE_HIGH |
| 默认 | IMPORTANCE_DEFAULT | IMPORTANCE_DEFAULT |
| 低 | IMPORTANCE_LOW | IMPORTANCE_LOW |
| 最小 | IMPORTANCE_MIN | IMPORTANCE_MIN |
// 新增:CRITICAL 级别(仅限特定类别使用)
// 适用于:医疗警报、安全警告、地震预警等
val criticalNotification = Notification.Builder(this, CHANNEL_ID)
.setContentTitle("🚨 地震预警")
.setContentText("预计震级 6.2,请立即避险")
.setImportance(NotificationManager.IMPORTANCE_CRITICAL)
.setCategory(Notification.CATEGORY_ALARM)
.setCriticalAlert(true) // 启用紧急警报行为
.setFullScreenIntent(pendingIntent, true) // 强制全屏
.build()
CRITICAL 级别限制:
- 仅限 ALARM、CALL、MEDICAL、SAFETY 类别
- 需要向 Google Play 声明用途并获得批准
- 用户可以在设置中禁用
- 滥用可能导致 Google Play 下架
五、Channel 管理最佳实践
// Android 16 推荐的 Channel 设计策略
class NotificationChannelManager(private val context: Context) {
fun createChannels() {
// 1. 渠道分类清晰
createChannel(
"messages", "私信消息",
"好友私信和群聊消息",
NotificationManager.IMPORTANCE_HIGH
)
createChannel(
"social", "社交动态",
"点赞、评论、关注通知",
NotificationManager.IMPORTANCE_DEFAULT
)
createChannel(
"system", "系统通知",
"版本更新、账号安全等",
NotificationManager.IMPORTANCE_LOW
)
// 2. 支持渠道分组
val msgGroup = NotificationChannelGroup("communication", "通讯")
notificationManager.createNotificationChannelGroup(msgGroup)
// 3. 优化优先级策略
getChannel("messages")?.let {
it.setAllowBubbles(true)
it.setShowBadge(true)
it.enableLights(true)
it.setLightColor(Color.RED)
}
}
private fun createChannel(
id: String, name: String, desc: String, importance: Int
) {
val channel = NotificationChannel(id, name, importance).apply {
description = desc
setShowBadge(importance >= NotificationManager.IMPORTANCE_DEFAULT)
}
notificationManager.createNotificationChannel(channel)
}
}
六、迁移指南:Android 15 → Android 16
| 变更项 | 旧 API | 新 API | 兼容性 |
|---|---|---|---|
| 持续通知 | setOngoing(true) | setRichOngoing {} | 可共存 |
| 实时更新 | 多次 notify() | LiveUpdate API | 推荐迁移 |
| 高优先级 | IMPORTANCE_HIGH | IMPORTANCE_CRITICAL | 部分迁移 |
| Bubble | 实验性 API | 正式 API | 需要迁移 |
| 通知分组 | setGroup() | setGroup() + 智能分组 | 自动升级 |
兼容性提醒:Android 16 的新通知 API 大部分是新增而非替换。调高 targetSdk 后调用新 API 会返回空操作,不会崩溃。可以逐步迁移。
七、性能与电量影响
- Live Updates:建议更新间隔 ≥ 1 秒,避免阻塞主线程
- Rich Ongoing:图片压缩到 480dp 宽度以内,减少渲染压力
- Bubble:每个 Bubble 约占用 30-50MB 额外内存
- CRITICAL:只在真正紧急时使用,滥用会影响用户信任