[Huawei Developers] Mike-mei:
With the proliferation of mobile Internet, push messaging has become a very effective way for mobile apps to achieve business success because it improves user engagement and stickiness by allowing developers to send messages to a wide range of users in a wide range of scenarios, such as when taking the subway or bus, having a meal in a restaurant, chatting with friends, and many more. No matter what the scenario is, a push message is always a great way for you to directly "talk" to your users, and for your users to obtain useful information.

The messaging method, however, may vary depending on the mobile device operating system, such as HarmonyOS, Android, and iOS. For this article, we'll be focusing on HarmonyOS. Is there a product or service that can be used to push messages to HarmonyOS apps effectively?

The answer, of course, is yes. After a little bit of research, I decided that HMS Core Push Kit for HarmonyOS (Java) is the best solution for me. This kit empowers HarmonyOS apps to send notification and data messages to mobile phones and tablets based on push tokens. A maximum of 1000 push tokens can be entered at a time to send messages.

Data messages are processed by apps on user devices. After a device receives a message containing data or instructions from the Push Kit server, the device passes the message to the target app instead of directly displaying it. The app then parses the message and triggers the required action (for example, going to a web page or an in-app page). Data messages are generally used in scenarios such as VoIP calls, voice broadcasts, and when interacting with friends. You can also customize the display style of such messages to improve their efficacy. Note that the data message delivery rate for your app may be affected by system restrictions and whether your app is running in the background.

In the next part of this article, I'll demonstrate how to use the kit's abilities to send messages. Let's begin with implementation.

Development Preparations​

You can click here to learn about how to prepare for the development. I won't be going into the details in this article.

App Development​

Obtaining a Push Token​

A push token uniquely identifies your app on a device. Your app calls the getToken method to obtain a push token from the Push Kit server. Then you can send messages to the app based on the obtained push token. If no push token is returned by getToken, you can use the onNewToken method to obtain one.

You are advised to upload push tokens to your app server as a list and update the list periodically. With the push token list, you can call the downlink message sending API of the Push Kit server to send messages to users in batches.

The detailed procedure is as follows:

1. Create a thread and call the getToken method to obtain a push token. (It is recommended that the getToken method be called in the first Ability after app startup.)

public class TokenAbilitySlice extends AbilitySlice {
private static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0xD001234,
"TokenAbilitySlice");
private void getToken() {
// Create a thread.
new Thread("getToken") {
@Override
public void run() {
try {
// Obtain the value of client/app_id from the agconnect-services.json file.
String appId = "your APP_ID";
// Set tokenScope to HCM.
String tokenScope = "HCM";
// Obtain a push token.
String token = HmsInstanceId.getInstance(getAbility().getAbilityPackage(), TokenAbilitySlice.this).getToken(appId, tokenScope);
} catch (ApiException e) {
// An error code is recorded when the push token fails to be obtained.
HiLog.error(LABEL_LOG, "get token failed, the error code is %{public}d", e.getStatusCode());
}
}
}.start();
}
}

2. Override the onNewToken method in your service (extended HmsMessageService). When the push token changes, the new push token can be returned through the onNewToken method.

public class DemoHmsMessageServiceAbility extends HmsMessageService {
private static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0xD001234, "DemoHmsMessageServiceAbility");

@Override
// Obtain a token.
public void onNewToken(String token) {
HiLog.info(LABEL_LOG, "onNewToken called, token:%{public}s", token);
}

@Override
// Record an error code if the token fails to be obtained.
public void onTokenError(Exception exception) {
HiLog.error(LABEL_LOG, "get onNewtoken error, error code is %{public}d", ((ZBaseException)exception).getErrorCode());
}
}

Obtaining Data Message Content​

Override the onMessageReceived method in your service (extended HmsMessageService). Then you can obtain the content of a data message as long as you send the data message to user devices.

public class DemoHmsMessageServiceAbility extends HmsMessageService {
private static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0xD001234,
"DemoHmsMessageServiceAbility");
@Override
public void onMessageReceived(ZRemoteMessage message) {
// Print the content field of the data message.
HiLog.info(LABEL_LOG, "get token, %{public}s", message.getToken());
HiLog.info(LABEL_LOG, "get data, %{public}s", message.getData());

ZRemoteMessage.Notification notification = message.getNotification();
if (notification != null) {
HiLog.info(LABEL_LOG, "get title, %{public}s", notification.getTitle());
HiLog.info(LABEL_LOG, "get body, %{public}s", notification.getBody());
}
}
}

Sending Messages​

You can send messages in either of the following ways:

Sign in to AppGallery Connect to send messages. You can click here for details about how to send messages using this method.

Call the Push Kit server API to send messages. Below, I'll explain how to send messages using this method.

1. Call the

https://oauth-login.cloud.huawei.com/oauth2/v3/token

API of the Account Kit server to obtain an access token.

Below is the request sample code:

POST /oauth2/v3/token HTTP/1.1
Host: oauth-login.cloud.huawei.com
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=<Client ID>&client_secret=<Client secret>

Below is the response sample code:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store

{
"access_token": "<Returned access token>",
"expires_in": 3600,
"token_type": "Bearer"
}

2. Call the Push Kit server API to send messages. Below is the request sample code:

The following is the URL for calling the API using HTTPS POST:

POST https://push-api.cloud.huawei.com/v1/clientid/messages:send

The request header looks like this:

Content-Type: application/json; charset=UTF-8
Authorization: Bearer CF3Xl2XV6jMK************************DgAPuzvNm3WccUIaDg==

The request body (of a notification message) looks like this:

{
"validate_only": false,
"message": {
"android": {
"notification": {
"title": "test title",
"body": "test body",
"click_action": {
"type": 3
}
}
},
"token": ["pushtoken1"]
}
}

Customizing Actions to Be Triggered upon Message Tapping​

You can customize the action triggered when a user taps the message, for example, opening the app home page, a website URL, or a specific page within an app.

Opening the App Home Page​

You can sign in to AppGallery Connect to send messages and specify to open the app home page when users tap the sent messages.

You can also call the Push Kit server API to send messages, as well as carry the click_action field in the message body and set type to 3 (indicating to open the app home page when users tap the sent messages).

{
"validate_only": false,
"message": {
"android": {
"notification": {
"title": "test title",
"body": "test body",
"click_action": {
"type": 3
}
}
},
"token": ["pushtoken1"]
}
}

Opening a Web Page​

You can sign in to AppGallery Connect to send messages and specify to open a web page when users tap the sent messages.

You can also call the Push Kit server API to send messages, as well as carry the click_action field in the message body and set type to 2 (indicating to open a web page when users tap the sent messages).

{
"validate_only": false,
"message": {
"android": {
"notification": {
"title": "test title",
"body": "test body",
"click_action": {
"type": 2,
"url":"https://www.huawei.com"
}
}
},
"token": ["pushtoken1"]
}
}

Opening a Specified App Page​

Create a custom page in your app. Taking MyActionAbility as an example, add the skills field of the ability to the config.json file in the entry/src/main directory of your project. In the file, the entities field has a fixed value of entity.system.default, and the value (for example, com.test.myaction) of actions can be changed as needed.

{
"orientation": "unspecified",
"name": "com.test.java.MyActionAbility",
"icon": "$media:icon",
"description": "$string:myactionability_description",
"label": "$string:entry_MyActionAbility",
"type": "page",
"launchType": "standard",
"skills": [
{
"entities": ["entity.system.default"],
"actions": ["com.test.myaction"]
}
]
}

Sign in to AppGallery Connect to send messages and specify to open the specified app page when users tap the sent messages. (The value of action should be that of actions defined in the previous step.)

You can also call the Push Kit server API to send messages, as well as carry the click_action and action fields in the message body and set type to 1 (indicating to open the specified app page when users tap the sent messages). The value of action should be that of actions defined in the previous step.

{
"validate_only": false,
"message": {
"android": {
"notification": {
"title": "test title",
"body": "test body",
"click_action": {
"type": 1,
"action":"com.test.myaction"
}
}
},
"token": ["pushtoken1"]
}
}

Transferring Data​

When sending a message, you can carry the data field in the message. When a user taps the message, data in the data field will be transferred to the app in the specified way.

1. Carry the data field in the message to be sent. You can do this in either of the following ways:

Sign in to AppGallery Connect to send the message, as well as carry the data field in the message body and set the key-value pair in the field.

Call the Push Kit server API to send the message and carry the data field in the message body.

{
"validate_only": false,
"message": {
"android": {
"notification": {
"title": "test title",
"body": "test body",
"click_action": {
"type": 1,
"action":"com.test.myaction"
}
},
"data": "{'key_data':'value_data'}"
},
"token": ["pushtoken1"]
}
}

2. Implement the app page displayed after message tapping to obtain the data field. Here, we assume that the app home page (MainAbilitySlice) is displayed after message tapping.

public class MainAbilitySlice extends AbilitySlice {
private static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0xD001234, "myDemo");
@Override
public void onStart(Intent intent) {
HiLog.info(LABEL_LOG, "MainAbilitySlice get started...");
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
// Call the parsing method.
parseIntent(intent);
}

private void parseIntent(Intent intent){
if (intent == null){return;}
IntentParams intentParams = intent.getParams();
if (intentParams == null) {return;}
// Obtain the key-value pair in the data field.
String key = "key_data";
Object obj = intentParams.getParam(key);
try{
// Print the key-value pair in the data field.
HiLog.info(LABEL_LOG, "my key: %{public}s, my value: %{public}s", key, obj);
}catch (Exception e){
HiLog.info(LABEL_LOG, "catch exception : " + e.getMessage());
}
}
}

Conclusion​

Today's highly-developed mobile Internet has made push messaging an important and effective way for mobile apps to improve user engagement and stickiness.

In this article, I demonstrated how to use HMS Core Push Kit to send messages to HarmonyOS apps based on push tokens. As demonstrated, the whole implementation process is both straightforward and cost-effective, and results in a better messaging effect for push messages.