vivo Atomic Island push

更新时间:
复制 MD 格式
Note

The vivo Atomic Island feature is currently in public beta. For integration issues, submit a ticket or contact our technical support. Fully test the feature in a testing environment before deploying it to a production environment.

Before you begin

To use the vivo Atomic Island feature, complete the following prerequisites:

  1. Integrate the SDK and the vivo third-party channel by following the instructions in Android SDK integration and vivo third-party channel integration.

  2. Apply for access to vivo Atomic Island by following the atomic notification integration guide.

  3. Design your vivo Atomic Island style based on the provided templates by following the atomic notification specifications.

Key concepts

vivo Atomic Island is a notification form factor that uses scenario-specific layouts and visual treatments to present important information in a lightweight and glanceable way.

Display locations

vivo Atomic Island can appear on the always-on display, lock screen, status bar, notification center, and as a widget.

image

Use cases

Users expect real-time updates for events they initiate.

The user is highly engaged with the event for a specific period and needs to view its progress or perform quick actions.

The event has a clear start and end time.

Examples: food delivery tracking, ride-hailing progress.

vivo Atomic Island style templates

vivo Atomic Island offers several style templates: the standard capsule, atomic capsule, large card, small card, and Origin lock screen style.

Capsule template

On devices that support vivo Atomic Island, an atomic capsule is displayed in the status bar. On unsupported devices or on the external screen of a vertically folding phone, a standard capsule is displayed in the status bar.

Standard capsule template

image

Atomic capsule template

image

Large card template

The large card template is available in several layouts for different use cases: highlighted information, progress visualization, side-by-side, basic, and navigation.

image

Small card template

Display locations: always-on display, widgets, and the lock screen on the external display of a vertically folding phone.

image

Origin lock screen style

Display location: Origin lock screen.

image

Manage an Atomic Island on the client

When the application process is active, you can use native Android notification APIs to locally operate on Atomic Island on the client. For specific parameters, see Core Parameters, and for a demo project, see Demo Code. Setting the notification.superx.operation parameter to 0, 1, and 2 corresponds to the create, update, and end operations for Atomic Island, respectively.

Sample code

// Get the NotificationManager object
Context context = getApplicationContext();
String channelId = "test_channel";
int notificationId = 1;
NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);

// Create a notification channel. If a channel already exists, you can reuse it without creating a new one.
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();
// Create the Atomic Island
notificationManager.notify(notificationId, notification);

Remote management with the Mobile Push API

Use the Push or MassPush API to remotely create, update, or end a vivo Atomic Island through Mobile Push.

Parameter settings

When calling the API, note the following key parameters:

  • PushType (Required): Set this parameter to NOTICE when you push a live activity.

  • AndroidNotificationNotifyId (Required): A unique identifier for the message when it is displayed as a notification. For an atomic notification, this must match the notificationId specified when the notification was created on the client.

  • AndroidPopupTitle (Required): The notification title for the notification bar. The maximum length is 40 characters. A full-width character, such as a Chinese character, counts as two.

  • AndroidPopupBody (Required): The notification content for the notification bar. The maximum length is 100 characters. A full-width character, such as a Chinese character, counts as two.

  • AndroidPopupActivity (Required): The activity to launch when the notification is tapped. This activity must be configured as described in Auxiliary pop-up integration.

  • AndroidVivoPushMode (Optional): The push mode. Set this parameter to 0 for production pushes or 1 for test pushes. The default is 0. A test push can be sent only to test users who are registered on the vivo developer portal. Apps that are under review can send only test pushes.

  • AndroidVivoLiveMessage (Required): The JSON string of the liveMessage atomic notification structure object, where operation is set to 0/1/2 for creation, update, or termination, respectively.

The following table describes the structure of AndroidVivoLiveMessage.

Parameter

Required

Type

Description

operation

Yes

int

0: Remotely create an atomic notification.

1: Remotely update an atomic notification.

2: Remotely end an atomic notification.

scene

Yes

string

The scene of the atomic notification. Valid values include:

  • MOVIE: Movie

  • HEALTH_REGISTER: Appointment registration

  • TAXI: Ride-hailing

  • TAKEOUT: Food delivery

  • DELIVERY: Package delivery

  • NAVIGATION: Navigation

  • CAR_STATE: In-vehicle status

  • MEETING: Meeting schedule

  • TRAIN: Train

  • FLIGHT: Flight

and more.

keepDuration

No

int

The duration, in seconds, to archive an ended notification. It remains visible for this duration after it ends. Maximum: 1 hour. Valid only when operation is 2. By default, notifications are not archived.

showNotify

No

boolean

Specifies whether to display a standard notification if the atomic notification fails to display.

templateType

Yes

int

The large card template type:

1: Highlighted information template

2: Progress visualization template

4: Basic template (The auxiliary information area subInfo is required for the basic template.)

changeRecord

No

int

The update sequence number. The device discards any subsequent update with a sequence number lower than the current one.

templateData

Yes

JSON Object

The data object for the card template. For details about the structure, see templateData.

capsuleData

No

JSON Object

The data object for the standard capsule template. For details about the structure, see capsuleData.

islandData

Yes

JSON Object

The data object for the atomic capsule template. For details about the structure, see islandData.

customSuperx

No

string

Extended information for special atomic notification scenarios. The protocol content must be confirmed with vivo offline.

displays

No

int

Description:

If this parameter is omitted, default display locations are used. For example, a 4x2 card defaults to all locations, and a 4x1 card defaults to the notification center and status bar. To display in the notification center, on the lock screen, and in the status bar, pass 0x111.

All locations include: notification center, lock screen, status bar, widget, always-on display, and Magic Box.

0x001: notification center

0x010: lock screen

0x100: status bar

0x1000: widget

0x10000: always-on display

0x100000: Magic Box

0x1000000: Jovi Suggestions

Sample code

Remote creation

PushRequest pushRequest = new PushRequest();
// Basic parameters
pushRequest.setAppKey(appKey);
pushRequest.setPushType("NOTICE");
pushRequest.setDeviceType("ANDROID");
pushRequest.setTarget(target);
pushRequest.setTargetValue(targetValue);

// Set parameters to remotely create the Atomic Island
pushRequest.setAndroidNotificationNotifyId(1);
pushRequest.setAndroidPopupTitle("Notification Title");
pushRequest.setAndroidPopupBody("Notification Body");
// The activity to launch on tap. Requires auxiliary pop-up integration.
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": "Capsule information",
        "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": "Left island text",
            "textColor": "#FFFFFF"
        },
        "rightInfo": {
            "waveColor": [
                "#FFFFFF"
            ],
            "waveState": 2,
            "icon": {
                "path": "res/drawable-hdpi/vivo_push_icon.jpg"
            },
            "text": "Right island 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": "Main text",
                    "textColor": "#FFFFFF"
                },
                {
                    "text": "1",
                    "textColor": "#00FFFF"
                }
            ],
            "subText": [
                {
                    "text": "Sub text",
                    "textColor": "#FFFFFF"
                },
                {
                    "text": "1",
                    "textColor": "#00FFFF"
                }
            ]
        },
        "priorityInfo": {
            "image": {
                "path": "res/drawable-hdpi/vivo_push_icon.jpg",
                "imgUri": "https://xxxxx"
            },
            "mainText": "Highlighted information",
            "skipContent": "https://www.vivo.com",
            "skipType": 2,
            "subText": "Auxiliary information"
        },
        "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": "Small card basic info",
            "subText": "Small card auxiliary info",
            "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": "Auxiliary",
            "textColor": "#222222",
            "type": 2
        }
    }
}
""";
pushRequest.setAndroidVivoLiveMessage(startLiveMessage);

// Send the push notification
PushResponse pushResponse = client.getAcsResponse(pushRequest);
System.out.printf("RequestId: %s, MessageId: %s\n", 
    pushResponse.getRequestId(), pushResponse.getMessageId());

Remote update

PushRequest pushRequest = new PushRequest();
// Basic parameters
pushRequest.setAppKey(appKey);
pushRequest.setPushType("NOTICE");
pushRequest.setDeviceType("ANDROID");
pushRequest.setTarget(target);
pushRequest.setTargetValue(targetValue);

// Set parameters to remotely update the Atomic Island
pushRequest.setAndroidNotificationNotifyId(1);
pushRequest.setAndroidPopupTitle("Notification Title");
pushRequest.setAndroidPopupBody("Notification Body");
// The activity to launch on tap. Requires auxiliary pop-up integration.
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": "Capsule information",
        "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": "Left island text",
            "textColor": "#FFFFFF"
        },
        "rightInfo": {
            "waveColor": [
                "#FFFFFF"
            ],
            "waveState": 2,
            "icon": {
                "path": "res/drawable-hdpi/vivo_push_icon.jpg"
            },
            "text": "Right island 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": "Main text",
                    "textColor": "#FFFFFF"
                },
                {
                    "text": "1",
                    "textColor": "#00FFFF"
                }
            ],
            "subText": [
                {
                    "text": "Sub text",
                    "textColor": "#FFFFFF"
                },
                {
                    "text": "1",
                    "textColor": "#00FFFF"
                }
            ]
        },
        "priorityInfo": {
            "image": {
                "path": "res/drawable-hdpi/vivo_push_icon.jpg",
                "imgUri": "https://xxxxx"
            },
            "mainText": "Highlighted information",
            "skipContent": "https://www.vivo.com",
            "skipType": 2,
            "subText": "Auxiliary information"
        },
        "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": "Small card basic info",
            "subText": "Small card auxiliary info",
            "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": "Auxiliary",
            "textColor": "#222222",
            "type": 2
        }
    }
}
""";
pushRequest.setAndroidVivoLiveMessage(updateLiveMessage);

// Send the push notification
PushResponse pushResponse = client.getAcsResponse(pushRequest);
System.out.printf("RequestId: %s, MessageId: %s\n", 
    pushResponse.getRequestId(), pushResponse.getMessageId());

Remote termination

PushRequest pushRequest = new PushRequest();
// Basic parameters
pushRequest.setAppKey(appKey);
pushRequest.setPushType("NOTICE");
pushRequest.setDeviceType("ANDROID");
pushRequest.setTarget(target);
pushRequest.setTargetValue(targetValue);

// Set parameters to remotely end the Atomic Island
pushRequest.setAndroidNotificationNotifyId(1);
pushRequest.setAndroidPopupTitle("Notification Title");
pushRequest.setAndroidPopupBody("Notification Body");
// The activity to launch on tap. Requires auxiliary pop-up integration.
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": "Capsule information",
        "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": "Left island text",
            "textColor": "#FFFFFF"
        },
        "rightInfo": {
            "waveColor": [
                "#FFFFFF"
            ],
            "waveState": 2,
            "icon": {
                "path": "res/drawable-hdpi/vivo_push_icon.jpg"
            },
            "text": "Right island 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": "Main text",
                    "textColor": "#FFFFFF"
                },
                {
                    "text": "1",
                    "textColor": "#00FFFF"
                }
            ],
            "subText": [
                {
                    "text": "Sub text",
                    "textColor": "#FFFFFF"
                },
                {
                    "text": "1",
                    "textColor": "#00FFFF"
                }
            ]
        },
        "priorityInfo": {
            "image": {
                "path": "res/drawable-hdpi/vivo_push_icon.jpg",
                "imgUri": "https://xxxxx"
            },
            "mainText": "Highlighted information",
            "skipContent": "https://www.vivo.com",
            "skipType": 2,
            "subText": "Auxiliary information"
        },
        "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": "Small card basic info",
            "subText": "Small card auxiliary info",
            "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": "Auxiliary",
            "textColor": "#222222",
            "type": 2
        }
    }
}
""";
pushRequest.setAndroidVivoLiveMessage(stopLiveMessage);

// Send the push notification
PushResponse pushResponse = client.getAcsResponse(pushRequest);
System.out.printf("RequestId: %s, MessageId: %s\n", 
    pushResponse.getRequestId(), pushResponse.getMessageId());

Limitations

  1. Do not send the same information as both an atomic notification and a standard notification. If an atomic notification fails to send or is not supported by the system, you can choose whether to fall back to displaying a standard notification.

  2. A single activity can be updated at a maximum frequency of once every 10 seconds. Updates that exceed this limit are discarded.

  3. If a single activity is not updated for more than 2 hours, the system clears the corresponding atomic notification.

  4. A single activity can be displayed for a maximum of 8 hours. After 8 hours, the system clears the corresponding atomic notification.

  5. If a user manually dismisses an atomic notification from the notification center or the lock screen, the system no longer displays the activity. Dismissing the atomic notification from the status bar does not affect its visibility in other locations.

For other important notes, see Important notes.

Troubleshooting

Creation failure

  1. Verify that you have obtained access permission from vivo by email.

  2. Use the getSceneStatus method to check if the switch for the corresponding vivo Atomic Island scene is enabled on the client.

  3. Use the message ID and device ID to check the push delivery path on the Troubleshoot Message page of the Mobile Push console's troubleshooting tool.

Update or end failure

  1. Check if the AndroidNotificationNotifyId parameter is the same as the notificationId used by the client to create the atomic island.

  2. Use the message ID and device ID to check the push delivery path on the Troubleshoot Message page of the Mobile Push console's troubleshooting tool.