vivo原子岛功能当前处于公测阶段,如您在接入过程中遇到任何问题,请及时通过工单或技术支持渠道反馈,我们将跟进处理。建议您先在测试环境中充分验证后再用于生产环境。
准备工作
在开始使用vivo原子岛功能之前,您需要完成以下准备工作:
已参考Android SDK接入与vivo厂商通道集成完成SDK和vivo厂商通道的接入。
已参考原子通知接入指导申请原子岛接入权限。
已参考原子通知规范依据样式模板设计您的原子岛样式。
核心概念
原子岛作为一种通知形态,通过场景细分和视觉处理,使用可视化的方式更轻盈地呈现重要信息。
产品形态
原子岛可以在熄屏、锁屏、状态栏、通知中心、桌面组件上显示。

适用场景
用户对于接收事件的实时变化信息有明确的预期,通常为用户主动行为触发。
用户在特定时段内非常关注该事件,且需要实时查看或快捷操作。
该事件有明确的开始和结束时间。
如:外卖进度、打车进度等。
原子岛样式模板
原子岛的样式模板可分为普通胶囊、原子岛胶囊、大卡、小卡、Origin锁屏样式。
胶囊模板
在支持原子岛的机型上,状态栏显示原子胶囊。在不支持原子岛的机型上,以及上下折叠屏外屏,状态栏显示为普通胶囊。
普通胶囊模板

原子胶囊模板

大卡模板
根据不同的适用场景,大卡分为强调信息模板、进度可视化模板、左右布局模板、基础模板、导航模板。

小卡模板
显示位置:熄屏、桌面组件、上下折外屏锁屏。

Origin锁屏样式
显示位置:Origin锁屏。

客户端本地创建/更新/结束原子岛
应用进程活跃时,可以通过Android原生通知API在客户端本地操作原子岛。具体参数请参考核心参数,demo项目请参考Demo代码,其中notification.superx.operation参数设置为0/1/2时分别对应原子岛的创建/更新/结束操作。
示例代码
// 获取NotificationManager对象
Context context = getApplicationContext();
String channelId = "test_channel";
int notificationId = 1;
NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
// 创建通知通道,若已有通知通道可直接复用,无需重复创建
NotificationChannel channel = new NotificationChannel(channelId, "test_channel_name", NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(channel);
Bundle b = new Bundle();
b.putInt("notification.superx.operation", 0);
b.putBoolean("notification.superx.showNotify", true);
b.putInt("notification.superx.template", 1);
b.putParcelable("notification.superx.clickResp", mPendingIntent);
b.putString("notification.superx.scene", "HEALTH_REGISTER");
Bundle baseInfo = new Bundle();
// icon
baseInfo.putParcelable("notification.superx.baseInfos.icon", icon);
// title & content
baseInfo.putCharSequence("notification.superx.baseInfos.title", title);
baseInfo.putCharSequence("notification.superx.baseInfos.content", content);
b.putBundle("notification.superx.baseInfos", baseInfo);
Notification notification = new NotificationCompat.Builder(context, channelId)
.setContentTitle(context.getText(R.string.traditional_notification_title))
.setContentText(traditionalNotificationContent)
.setSmallIcon(R.mipmap.ic_launcher)
.setExtras(b)
.build();
// 创建原子岛
notificationManager.notify(notificationId, notification);通过移动推送接口远程创建/更新/结束原子岛
移动推送支持通过Push接口或MassPush接口远程更新/结束原子岛。
参数设置
调用接口时注意以下关键参数:
PushType(必填): 推送实况窗时固定设置为
NOTICE。AndroidNotificationNotifyId(必填): 每条消息在通知显示时的唯一标识。原子通知消息则为本地创建时指定的notificationId。
AndroidPopupTitle(必填): 通知标题(用于通知栏消息) 最大20个汉字(一个汉字等于两个英文字符,即最大不超过40个英文字符)。
AndroidPopupBody(必填): 通知内容(用于通知栏消息) 最大50个汉字(一个汉字等于两个英文字符,即最大不超过100个英文字符)。
AndroidPopupActivity(必填): 点击跳转activity,此activity需要参考辅助弹窗接入完成接入。
AndroidVivoPushMode(可选): 推送模式。0为正式推送,1为测试推送,不填默认为0(测试推送,只能给vivo web界面录入的测试用户推送;审核中应用,只能用测试推送)。
AndroidVivoLiveMessage(必填):原子通知结构对象liveMessage的JSON字符串,其中
operation在创建/更新/结束时分别设置为0/1/2。
AndroidVivoLiveMessage的结构如下表所示:
参数 | 是否必选 | 参数类型 | 描述 |
operation | 是 | int | 0:原子通知远程创建 1:原子通知远程更新 2:原子通知远程结束 |
scene | 是 | string | 原子通知的场景:
等 |
keepDuration | 否 | int | 原子通知结束的存档时间,单位s。最长存档显示时间1h。表示原子通知结束后,还需要保留显示多久,默认不存档,仅在operation设置为结束时才有效。 |
showNotify | 否 | boolean | 原子通知展示失败时是否展示普通通知 |
templateType | 是 | int | 大卡模板类型: 1:强调信息模板 2:进度可视化模板 4:基础模板(基础模板的辅助信息区-subInfo为必填项) |
changeRecord | 否 | int | 更新的顺序,若后续到达设备的更新信息此值小于当前值,则丢弃 |
templateData | 是 | JSON Object | 卡片模板的数据对象,详细结构请参考templateData |
capsuleData | 否 | JSON Object | 普通胶囊模板的数据对象,详细结构请参考capsuleData |
islandData | 是 | JSON Object | 原子岛胶囊模板的数据对象,详细结构请参考islandData |
customSuperx | 否 | string | 原子通知部分特殊场景下的扩展信息,需与vivo线下对齐并确定协议内容 |
displays | 否 | int | 参数含义如下: 如果不传,默认触点【4*2卡片默认是全触点, 4*1卡片默认 通知&状态栏】,例:传0x111 显示 【通知&锁屏&状态栏】 全触点包括:通知/锁屏/状态栏/桌面组件/熄屏/魔盒 0x001 : 通知 0x010 : 锁屏 0x100 : 状态栏 0x1000 : 桌面组件 0x10000 : 熄屏 0x100000 : 魔盒 0x1000000 : 小v建议 |
示例代码
远程创建原子岛
PushRequest pushRequest = new PushRequest();
// 基础参数
pushRequest.setAppKey(appKey);
pushRequest.setPushType("NOTICE");
pushRequest.setDeviceType("ANDROID");
pushRequest.setTarget(target);
pushRequest.setTargetValue(targetValue);
// 设置远程更新原子岛的参数
pushRequest.setAndroidNotificationNotifyId(1);
pushRequest.setAndroidPopupTitle("通知标题");
pushRequest.setAndroidPopupBody("通知内容");
// 点击跳转activty,需要接入辅助弹窗
pushRequest.setAndroidPopupActivity("xx.YourAndroidPopupActivity");
pushRequest.setAndroidVivoPushMode(1);
String startLiveMessage = """
{
"operation": 0,
"scene": "HEALTH_REGISTER",
"templateType": 1,
"keepDuration": 0,
"showNotify": true,
"changeRecord": 999,
"capsuleData": {
"bgColor": "#32d4d4",
"content": "胶囊信息",
"contentColor": "#222222",
"icon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"newNode": 1,
"state": 1
},
"islandData": {
"leftTemplate": 1,
"rightTemplate": 4,
"leftInfo": {
"icon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"text": "左岛文本",
"textColor": "#FFFFFF"
},
"rightInfo": {
"waveColor": [
"#FFFFFF"
],
"waveState": 2,
"icon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"text": "右岛文本",
"textColor": "#FFFFFF",
"bgColor": "#32d4d4",
"skipContent": "https://www.vivo.com",
"skipType": 2,
"progress": 100,
"progressColor": "#FFFFFF",
"progressBgColor": "#FFFFFF",
"progressState": 1,
"loadingColor": "#FFFFFF"
},
"forceShow": true,
"forceShowCard": true,
"clickType": 1,
"showTime": 180
},
"templateData": {
"baseInfo": {
"icon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"mainText": [
{
"text": "主文本",
"textColor": "#FFFFFF"
},
{
"text": "1",
"textColor": "#00FFFF"
}
],
"subText": [
{
"text": "副文本",
"textColor": "#FFFFFF"
},
{
"text": "1",
"textColor": "#00FFFF"
}
]
},
"priorityInfo": {
"image": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg",
"imgUri": "https://xxxxx"
},
"mainText": "强调信息",
"skipContent": "https://www.vivo.com",
"skipType": 2,
"subText": "辅助信息"
},
"progressInfo": {
"nodeIcon": [
{
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
{
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
}
],
"indicatorIcon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"indicatorLoc": 1,
"progress": 30,
"progressColor": "#00FFFF",
"bgColor": "#0A00FFFF"
},
"shortInfo": {
"lockIcon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"icon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"image": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg",
"imgUri": "https://xxxxx"
},
"mainText": "小卡基础信息",
"subText": "小卡辅助信息",
"skipContent": "https://www.vivo.com",
"skipType": 2
},
"subInfo": {
"bgColor": "#32d4d4",
"image": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg",
"imgUri": "https://xxxxx"
},
"skipContent": "https://www.vivo.com",
"skipType": 2,
"text": "辅助",
"textColor": "#222222",
"type": 2
}
}
}
""";
pushRequest.setAndroidVivoLiveMessage(startLiveMessage);
// 发送推送
PushResponse pushResponse = client.getAcsResponse(pushRequest);
System.out.printf("RequestId: %s, MessageId: %s\n",
pushResponse.getRequestId(), pushResponse.getMessageId());远程更新原子岛
PushRequest pushRequest = new PushRequest();
// 基础参数
pushRequest.setAppKey(appKey);
pushRequest.setPushType("NOTICE");
pushRequest.setDeviceType("ANDROID");
pushRequest.setTarget(target);
pushRequest.setTargetValue(targetValue);
// 设置远程更新原子岛的参数
pushRequest.setAndroidNotificationNotifyId(1);
pushRequest.setAndroidPopupTitle("通知标题");
pushRequest.setAndroidPopupBody("通知内容");
// 点击跳转activty,需要接入辅助弹窗
pushRequest.setAndroidPopupActivity("xx.YourAndroidPopupActivity");
pushRequest.setAndroidVivoPushMode(1);
String updateLiveMessage = """
{
"operation": 1,
"scene": "HEALTH_REGISTER",
"templateType": 1,
"keepDuration": 0,
"showNotify": true,
"changeRecord": 999,
"capsuleData": {
"bgColor": "#32d4d4",
"content": "胶囊信息",
"contentColor": "#222222",
"icon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"newNode": 1,
"state": 1
},
"islandData": {
"leftTemplate": 1,
"rightTemplate": 4,
"leftInfo": {
"icon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"text": "左岛文本",
"textColor": "#FFFFFF"
},
"rightInfo": {
"waveColor": [
"#FFFFFF"
],
"waveState": 2,
"icon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"text": "右岛文本",
"textColor": "#FFFFFF",
"bgColor": "#32d4d4",
"skipContent": "https://www.vivo.com",
"skipType": 2,
"progress": 100,
"progressColor": "#FFFFFF",
"progressBgColor": "#FFFFFF",
"progressState": 1,
"loadingColor": "#FFFFFF"
},
"forceShow": true,
"forceShowCard": true,
"clickType": 1,
"showTime": 180
},
"templateData": {
"baseInfo": {
"icon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"mainText": [
{
"text": "主文本",
"textColor": "#FFFFFF"
},
{
"text": "1",
"textColor": "#00FFFF"
}
],
"subText": [
{
"text": "副文本",
"textColor": "#FFFFFF"
},
{
"text": "1",
"textColor": "#00FFFF"
}
]
},
"priorityInfo": {
"image": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg",
"imgUri": "https://xxxxx"
},
"mainText": "强调信息",
"skipContent": "https://www.vivo.com",
"skipType": 2,
"subText": "辅助信息"
},
"progressInfo": {
"nodeIcon": [
{
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
{
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
}
],
"indicatorIcon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"indicatorLoc": 1,
"progress": 30,
"progressColor": "#00FFFF",
"bgColor": "#0A00FFFF"
},
"shortInfo": {
"lockIcon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"icon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"image": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg",
"imgUri": "https://xxxxx"
},
"mainText": "小卡基础信息",
"subText": "小卡辅助信息",
"skipContent": "https://www.vivo.com",
"skipType": 2
},
"subInfo": {
"bgColor": "#32d4d4",
"image": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg",
"imgUri": "https://xxxxx"
},
"skipContent": "https://www.vivo.com",
"skipType": 2,
"text": "辅助",
"textColor": "#222222",
"type": 2
}
}
}
""";
pushRequest.setAndroidVivoLiveMessage(updateLiveMessage);
// 发送推送
PushResponse pushResponse = client.getAcsResponse(pushRequest);
System.out.printf("RequestId: %s, MessageId: %s\n",
pushResponse.getRequestId(), pushResponse.getMessageId());远程结束原子岛
PushRequest pushRequest = new PushRequest();
// 基础参数
pushRequest.setAppKey(appKey);
pushRequest.setPushType("NOTICE");
pushRequest.setDeviceType("ANDROID");
pushRequest.setTarget(target);
pushRequest.setTargetValue(targetValue);
// 设置远程更新原子岛的参数
pushRequest.setAndroidNotificationNotifyId(1);
pushRequest.setAndroidPopupTitle("通知标题");
pushRequest.setAndroidPopupBody("通知内容");
// 点击跳转activty,需要接入辅助弹窗
pushRequest.setAndroidPopupActivity("xx.YourAndroidPopupActivity");
pushRequest.setAndroidVivoPushMode(1);
String stopLiveMessage = """
{
"operation": 2,
"scene": "HEALTH_REGISTER",
"templateType": 1,
"keepDuration": 0,
"showNotify": true,
"changeRecord": 999,
"capsuleData": {
"bgColor": "#32d4d4",
"content": "胶囊信息",
"contentColor": "#222222",
"icon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"newNode": 1,
"state": 1
},
"islandData": {
"leftTemplate": 1,
"rightTemplate": 4,
"leftInfo": {
"icon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"text": "左岛文本",
"textColor": "#FFFFFF"
},
"rightInfo": {
"waveColor": [
"#FFFFFF"
],
"waveState": 2,
"icon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"text": "右岛文本",
"textColor": "#FFFFFF",
"bgColor": "#32d4d4",
"skipContent": "https://www.vivo.com",
"skipType": 2,
"progress": 100,
"progressColor": "#FFFFFF",
"progressBgColor": "#FFFFFF",
"progressState": 1,
"loadingColor": "#FFFFFF"
},
"forceShow": true,
"forceShowCard": true,
"clickType": 1,
"showTime": 180
},
"templateData": {
"baseInfo": {
"icon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"mainText": [
{
"text": "主文本",
"textColor": "#FFFFFF"
},
{
"text": "1",
"textColor": "#00FFFF"
}
],
"subText": [
{
"text": "副文本",
"textColor": "#FFFFFF"
},
{
"text": "1",
"textColor": "#00FFFF"
}
]
},
"priorityInfo": {
"image": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg",
"imgUri": "https://xxxxx"
},
"mainText": "强调信息",
"skipContent": "https://www.vivo.com",
"skipType": 2,
"subText": "辅助信息"
},
"progressInfo": {
"nodeIcon": [
{
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
{
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
}
],
"indicatorIcon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"indicatorLoc": 1,
"progress": 30,
"progressColor": "#00FFFF",
"bgColor": "#0A00FFFF"
},
"shortInfo": {
"lockIcon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"icon": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg"
},
"image": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg",
"imgUri": "https://xxxxx"
},
"mainText": "小卡基础信息",
"subText": "小卡辅助信息",
"skipContent": "https://www.vivo.com",
"skipType": 2
},
"subInfo": {
"bgColor": "#32d4d4",
"image": {
"path": "res/drawable-hdpi/vivo_push_icon.jpg",
"imgUri": "https://xxxxx"
},
"skipContent": "https://www.vivo.com",
"skipType": 2,
"text": "辅助",
"textColor": "#222222",
"type": 2
}
}
}
""";
pushRequest.setAndroidVivoLiveMessage(stopLiveMessage);
// 发送推送
PushResponse pushResponse = client.getAcsResponse(pushRequest);
System.out.printf("RequestId: %s, MessageId: %s\n",
pushResponse.getRequestId(), pushResponse.getMessageId());原子岛限制
针对同一信息,如果以原子通知形式发送,则不要再以普通通知形式发送。当原子通知发送异常或者系统不支持原子通知时,业务方可选择是否转为普通通知显示。
通过原子通知形式发送时,单个活动最多支持10s/次的刷新频次,超过这个频次的部分将被丢弃,不再下发。
单个活动,当超过2小时不更新,此条原子通知则会被系统清除。
单个活动,最长显示时长为8小时,超过8小时,此条原子通知则会被系统清除。
当用户手动删除通知中心/锁屏的原子通知后,本次活动不再显示原子通知。删除状态栏原子通知,不影响其他触点的显示。
其余注意事项请见重要说明。
问题排查
创建原子岛失败
检查是否已向vivo发邮件获得接入权限。
使用getSceneStatus方法检查客户端对应原子岛场景状态开关是否已经打开。
根据消息ID与设备ID在移动推送控制台的排查工具->排查消息页面检查原子岛推送链路。
更新/结束原子岛失败
检查
AndroidNotificationNotifyId参数是否与客户端创建原子岛的notificationId相同。根据消息ID与设备ID在移动推送控制台的排查工具->排查消息页面检查原子岛推送链路。