本文档旨在说明如何在现有的 Live Updates 通知基础上,为小米手机(HyperOS 3 及更高版本)适配“焦点通知”功能,即“超级岛(Super Island)”。
在调用 LiveUpdateManager.showLiveUpdateNotification 时,如果检测到设备运行小米 HyperOS 3,则在原生 Android 16 实时更新通知的基础上,附加小米专有的“超级岛”参数。
小米焦点通知通过在 Notification 的 extras 中添加一个 JSON 字符串(Key 为 miui.focus.param)以及一些 Bundle 数据来实现。
{
"param_v2": {
"protocol": 1,
"business": "pickup_service",
"enableFloat": true,
"updatable": true,
"ticker": "取件码通知",
"aodTitle": "取件码: {code}",
"param_island": {
"islandProperty": 1,
"bigIslandArea": {
"imageTextInfoLeft": {
"type": 1,
"textInfo": {
"frontTitle": "实时状态",
"title": "{status}",
"content": "{content}",
"useHighLight": true
}
}
},
"smallIslandArea": {
"picInfo": {
"type": 1,
"pic": "miui.focus.pic_island_icon"
}
}
},
"baseInfo": {
"title": "{title}",
"content": "{content}",
"type": 2
}
}
}需要检测是否支持 HyperOS 3 及以上版本:
Settings.System.getInt(contentResolver, "notification_focus_protocol", 0)返回3表示支持 HyperOS 3 超级岛。persist.sys.feature.island系统属性为true。
小米焦点通知有独立的权限开关。通过 ContentProvider 查询:
content://miui.statusbar.notification.public 的 canShowFocus 操作。
实现对小米 HyperOS 版本的检测及权限检查:
private fun isHyperOS3(): Boolean {
val protocolVersion = Settings.System.getInt(
context.contentResolver, "notification_focus_protocol", 0
)
return protocolVersion >= 3
}
private fun hasFocusPermission(): Boolean {
return try {
val uri = Uri.parse("content://miui.statusbar.notification.public")
val extras = Bundle().apply { putString("package", context.packageName) }
val bundle = context.contentResolver.call(uri, "canShowFocus", null, extras)
bundle?.getBoolean("canShowFocus", false) ?: false
} catch (e: Exception) {
false
}
}在 showLiveUpdateNotification 方法中注入参数:
fun showLiveUpdateNotification(title: String, content: String, status: String = "制作中") {
val builder = NotificationCompat.Builder(context, channelId)
// ... 原有配置 ...
.addExtras(Bundle().apply {
// 1. Android 16 Live Update 参数
putBoolean(EXTRA_REQUEST_PROMOTED_ONGOING, true)
putString(EXTRA_SHORT_CRITICAL_TEXT, status)
// 2. 小米 HyperOS 3 焦点通知参数
if (isHyperOS3() && hasFocusPermission()) {
val islandJson = buildIslandJson(title, content, status)
putString("miui.focus.param", islandJson)
// 设置图片 Bundle
val pics = Bundle().apply {
putParcelable("miui.focus.pic_island_icon", Icon.createWithResource(context, R.mipmap.ic_launcher))
}
putBundle("miui.focus.pics", pics)
}
})
notificationManager.notify(notificationId, builder.build())
}- 大岛 (Expand State): 显示详细的取件码信息、取件地点和倒计时(如有)。
- 小岛 (Summary State): 显示应用图标及简短状态(如“取件码已就绪”)。
- AOD: 息屏时显示最关键的取件码数字。
- 模板选择: 小米提供了多种模板(打车、外卖、通用等),本项目建议使用 通用信息模板。
- 资源准备: 确保应用内有 1:1 比例的透明背景图标,用于小岛展示。
- 动态更新: 调用
notify时,使用相同的notificationId并递增sequence参数,可以实现岛上信息的平滑滚动更新。