使用 SDK

初始化与接入 SDK

前置条件

  • 已在华为的应用平台上开通 App 的推送服务,详情请参考 华为的 Push 服务

  • 添加消息推送 SDK 前,请确保已经接入工程到 mPaaS。更多信息请参见 接入 mPaaS 能力

组件接入

  1. 需在 AbilityonCreate 方法中设置调用。

    代码如下:

    import { MpaasPushServiceImpl, MPPush, CallResp } from '@mpaas/push';
    
    let tokenGet: CallResp
    try {
    	tokenGet = await MPPush.init()	
    	console.info("CallResp="+tokenGet)
    	if (tokenGet.success) {
    		this.tokenVal = tokenGet.msg
    	} else {
    		console.info("MPPush.init failed=" + tokenGet.msg)
    	}
    } catch (e) {
    	console.info("MPPush.init err=" + e.message)
    }

    该方法会初始化 Push 的服务组件,同时会获取一个鸿蒙推送的 token,然后将其上报到服务器。

    • 如果成功,则该方法会返回 token 值。

    • 如果失败,则会返回空字符串,并且打印日志。

  2. 编写一个承接 MPS 组件的 Ability,继承 MpaasNcAbility

    代码如下:

    export default class MpaasBridgeMsgAbility extends MpaasNcAbility {
      static tag: string = "MpaasBridgeMsgAbility"
      onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
        hilog.info(0x0000, MpaasBridgeMsgAbility.tag, "start MpaasBridgeMsgAbility onCreate")
        super.onCreate(want, launchParam)
      }
    
      onForeground() {
        console.log('MpaasBridgeMsgAbility onBackground');
      }
    
    }

    注意:

    • 升级后的 SDK(基线版本大于等于 10.2.3.13)NcAbility内部做了配置页面的销毁动作,无需用户自行实现。

    • 如果基线版本小于 10.2.3.13,需要 开发者在配置页面中onForeground加入this.context.terminateSelf代码,配置示例如下:

      import { MpaasNcAbility } from '@mpaas/push'
      
      export default class MpaasBridgeMsgAbility extends MpaasNcAbility {
       static tag: string = "MpaasBridgeMsgAbility"
       onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
       hilog.info(0x0000, MpaasBridgeMsgAbility.tag, "start MpaasBridgeMsgAbility onCreate")
       super.onCreate(want, launchParam)
       }
      
        onForeground() {
          console.log('MpaasBridgeMsgAbility onBackground');
            try {
              // 销毁掉中间过渡的 Ability
              this.context.terminateSelf((err: BusinessError) => {
                if (err.code) {
                  // 处理业务逻辑错误
                  console.error(`terminateSelf failed, code is ${err.code}, message is ${err.message}`);
                  return;
                }
                // 执行正常业务
                console.info('terminateSelf succeed');
              });
            } catch (err) {
              // 捕获同步的参数错误
              let code = (err as BusinessError).code;
              let message = (err as BusinessError).message;
              console.error(`terminateSelf failed, code is ${code}, message is ${message}`);
            }
        }
      }
      重要

      如果升级客户端组件之后(10.2.3.13 及其以上版本),没有删除上述销毁的代码,那么跳转动作会失败。

  3. module.json5 文件中,描述 MpaasBridgeMsgAbility

    代码如下:

    {
     "name": "MpaasBridgeMsgAbility",
     "srcEntry": "./ets/pushability/MpaasBridgeMsgAbility.ets",
     "description": "$string:EntryAbility_desc",
     "icon": "$media:icon",
     "label": "$string:BridgeAbility_label",
     "startWindowIcon": "$media:startIcon",
     "startWindowBackground": "$color:start_window_background",
     "exported": true,
     "removeMissionAfterTerminate": true,
     "skills": [
     {
     "actions": ["com.mpaas.harmony.push"]
     }
     ]
    }
    说明
    • actions 必须和代码中的描述保持一致。

    • removeMissionAfterTerminate 字段必须设置为 true,否则 MpaasBridgeMsgAbility 不会被彻底销毁,从而造成应用中有一个多余且无效的 UIAbility

使用 SDK

说明

在使用 SDK 之前,请确保设置了框架层的 userId

用户后续的 token 绑定、解绑与推送,设置代码参考如下:

MPFramework.instance.userId = "mpaas_push"

绑定/解绑 token

用户调用绑定接口,将 App 的用户 ID 和 token 发送到后端即可进行绑定,解绑即为取消绑定。

  • 绑定接口如下:

    import { MpaasPushServiceImpl, MPPush, CallResp } from '@mpaas/push';
    
    // 第一个入参: 手机号,若没有手机号,则填 "",必填
    // 第二个入参: token,即 init 方法返回的 token 值,必填
    // 第三个入参: userid,非必填,若不填,则采用 MPFramework 框架层设置的 userId
    let res: CallResp = await MpaasPushServiceImpl.getInstance().bind("12345678900", this.tokenVal, "push_userid")
    console.log("bind res="+res.msg)
    if (res.success) {
    	this.bindState = "bind state: " + "binded"
    }

    返回值 res.success 表示绑定是否成功。

  • 解绑接口如下:

    import { MpaasPushServiceImpl, MPPush, CallResp } from '@mpaas/push';
    
    // 第一个入参: token,即 init 方法返回的 token 值,必填
    // 第二个入参: userid,非必填,若不填,则采用 MPFramework 框架层设置的 userId
    let res: CallResp = await MpaasPushServiceImpl.getInstance().unbind(this.tokenVal)
    console.log("unbind res="+res.msg)
    if (res.success) {
    	this.bindState = "bind state: " + "unbind"
    }

    返回值 res.success 表示解绑是否成功。

配置跳转消息 Ability

在客户端的 module.json5 文件中配置目标应用内的 Ability,例如下面的 PushLandingAbility

{
 "name": "PushLandingAbility",
 "srcEntry": "./ets/pushability/PushLandingAbility.ets",
 "description": "$string:EntryAbility_desc",
 "icon": "$media:icon",
 "label": "$string:LandingAbility_label",
 "startWindowIcon": "$media:startIcon",
 "startWindowBackground": "$color:start_window_background",
 "exported": true,
 "skills": [
 {
 "actions": [""],
 "uris": [
 {
 "scheme": "jump",
 "host": "com.mpaas.harmony.push",
 "path": "landing"
 }
 ]
 }
 ]
}

在控制台推送消息时,需要填入跳转的 URI 为 jump://com.mpaas.harmony.push/landing,和上述代码中的 uris 对应。在控制台推送消息结束之后,可以点击客户端的通知栏,即可跳转至配置好的 PushLandingAbility 所对应的页面。

重要

服务端大于等于 1.35.0 版本,且客户端基线大于等于 10.2.3.13 版本时,将不支持点击通知栏直接跳转浏览器去打开 HTTP 链接,仅支持自定义跳转链接,需用户自行实现网页跳转。

配置落地页面的 Ability 示例代码

import { MPPushMsg,PushMsgHandler,msgOutput,MpaasPushServiceImpl } from '@mpaas/push';
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import window from '@ohos.window';
import hilog from '@ohos.hilog';
import pushService from '@hms.core.push.pushService';
import { BusinessError } from '@ohos.base';

export class PushLandingAbility extends UIAbility {
  private TAG: string = "PushLandingAbility"
  public para: Record<string,string> = { 'msg_id': "default", 'msg_data': "default"};
  public storageData: LocalStorage = new LocalStorage(this.para);
  landingWindowStage: window.WindowStage | undefined = undefined;

  async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
    super.onCreate(want, launchParam)

    // 客户端基线版本大于等于 10.2.3.13、且服务端 mps 版本大于等于 1.35.0 时
    // 才可使用 PushMsgHandler.parsePushMsg 工具解析消息
    let msg: msgOutput | undefined = PushMsgHandler.parsePushMsg(want)
    let msg_id: string | undefined = msg?.msg_id
    let msg_data: MPPushMsg | undefined = msg?.msg_data
    
    if (msg) {
      if (msg_id) {
        k = msg_id
        hilog.info(0x0000, PushLandingAbility.TAG, 'onCreate k: %{public}s', k);
      } else {
        hilog.warn(0x0000, PushLandingAbility.TAG, 'msg_id is undefined');
      }
      if (msg_data) {
        v = msg_data
        hilog.info(0x0000, PushLandingAbility.TAG, 'onCreate v: %{public}s', k);
      } else {
        hilog.warn(0x0000, PushLandingAbility.TAG, 'msg_data is undefined');
      }
    } else {
      hilog.warn(0x0000, PushLandingAbility.TAG, 'msg is undefined');
    }
    
    this.storageData.set('msg_id', k)
    this.storageData.set('msg_data', JSON.stringify(v))
    hilog.info(0x0000, PushLandingAbility.TAG, 'onCreate push_msgkey: %{public}s', k);
    hilog.info(0x0000, PushLandingAbility.TAG, 'onCreate push_msgdata: %{public}s', JSON.stringify(v));
  }
  
  async onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
    hilog.info(0x0000, PushLandingAbility.TAG, 'PushLandingAbility onNewWant. Data: %{public}s', JSON.stringify(want.parameters) ?? '');
    let k: string = ""
    let v: object = JSON.parse("{}")

    // 客户端基线版本大于等于 10.2.3.13、且服务端 mps 版本大于等于 1.35.0 时
    // 才可使用 PushMsgHandler.parsePushMsg 工具解析消息
    let msg: msgOutput | undefined = PushMsgHandler.parsePushMsg(want)
    let msg_id: string | undefined = msg?.msg_id
    let msg_data: MPPushMsg | undefined = msg?.msg_data

    if (msg) {
      if (msg_id) {
        k = msg_id
        hilog.info(0x0000, PushLandingAbility.TAG, 'onCreate k: %{public}s', k);
      } else {
        hilog.warn(0x0000, PushLandingAbility.TAG, 'msg_id is undefined');
      }
      if (msg_data) {
        v = msg_data
        hilog.info(0x0000, PushLandingAbility.TAG, 'onCreate v: %{public}s', k);
      } else {
        hilog.warn(0x0000, PushLandingAbility.TAG, 'msg_data is undefined');
      }
    } else {
      hilog.warn(0x0000, PushLandingAbility.TAG, 'msg is undefined');
    }

    // this.para = { 'msg_key': this.pushKey, 'msg_data':  JSON.stringify(this.pushData)};
    this.storageData.set('msg_id', k)
    this.storageData.set('msg_data', JSON.stringify(v))

    hilog.info(0x0000, PushLandingAbility.TAG, 'onNewWant push_msgkey: %{public}s', this.storageData.get("msg_id"));
    hilog.info(0x0000, PushLandingAbility.TAG, 'onNewWant push_msgdata: %{public}s', JSON.stringify(this.storageData.get("msg_data")));
    if (this.landingWindowStage != null) {
      hilog.info(0x0000, PushLandingAbility.TAG, 'start landingWindowStage.loadContent');
      await this.landingWindowStage.loadContent('pushpages/pushLandingPage', this.storageData)
    }

  }

  onDestroy(): void {
    hilog.info(0x0000, PushLandingAbility.TAG, '%{public}s', 'Ability onDestroy');
  }

  async onWindowStageCreate(windowStage: window.WindowStage): Promise<void> {
    // Main window is created, set main page for this ability
    // 创建新实例并使用给定对象初始化
    this.landingWindowStage = windowStage
    hilog.info(0x0000, PushLandingAbility.TAG, 'this.pushKey= %{public}s',this.storageData.get("msg_id"));
    hilog.info(0x0000, PushLandingAbility.TAG, 'this.pushData= %{public}s',this.storageData.get("msg_data"));
    try {
      hilog.info(0x0000, PushLandingAbility.TAG, 'this.storageData. Key: %{public}s, this.storageData Data: %{public}s',this.storageData.get("msg_id"), this.storageData.get("msg_data"));
      await windowStage.loadContent('pushpages/pushLandingPage', this.storageData)
      hilog.info(0x0000, PushLandingAbility.TAG, 'Succeeded in loading the content. Key: %{public}s, Data: %{public}s',this.storageData.get("msg_id"), JSON.stringify(this.storageData.get("msg_data")) ?? '');
    } catch (e) {
      console.log("err msg="+e.message)
      return
    }
  }

  onWindowStageDestroy(): void {
    // Main window is destroyed, release UI related resources
    hilog.info(0x0000, PushLandingAbility.TAG, '%{public}s', 'Ability onWindowStageDestroy');
  }

  onForeground(): void {
    // Ability has brought to foreground
    hilog.info(0x0000, PushLandingAbility.TAG, '%{public}s', 'Ability onForeground');
  }

  onBackground(): void {
    // Ability has back to background
    hilog.info(0x0000, PushLandingAbility.TAG, '%{public}s', 'Ability onBackground');
  }
}
重要
  • 上述消息解析方式,需要升级服务端基线与客户端 MPS 版本,需要确保:服务端 MPS 版本大于等于 1.35.0 且客户端基线版本大于等于 10.2.3.13。

  • msg_id 对应消息 ID,msg_data 对应具体的消息数据。

注意:

不满足上述版本条件的,请继续采用原有消息解析方式。

import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import window from '@ohos.window';
import hilog from '@ohos.hilog';
import { MpaasPushServiceImpl } from '@mpaas/push';
import pushService from '@hms.core.push.pushService';
import { BusinessError } from '@ohos.base';

export class PushLandingAbility extends UIAbility {
  private static TAG: string = "PushLandingAbility"

  private pushData: object = JSON.parse("{}");
  private pushKey: string = "";
  public  para: Record<string,string> = { 'msg_id': "default", 'msg_data': "default"};
  public storageData: LocalStorage = new LocalStorage(this.para);
  landingWindowStage: window.WindowStage | undefined = undefined;

  async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
    hilog.info(0x0000, PushLandingAbility.TAG, 'PushLandingAbility create. Data: %{public}s', JSON.stringify(want.parameters) ?? '');
    let k: string = ""
    let v: object = JSON.parse("{}")
    if (want.parameters) {
      if (want.parameters["msg_id"]) {
        k = want.parameters["msg_id"] as string
        hilog.info(0x0000, PushLandingAbility.TAG, 'onNewWant k: %{public}s', k);
      }
      if (want.parameters["msg_data"]) {
        v = want.parameters["msg_data"]
        hilog.info(0x0000, PushLandingAbility.TAG, 'onNewWant k: %{public}s', v);
      }
    }

    this.storageData.set('msg_id', k)
    this.storageData.set('msg_data', JSON.stringify(v))
    hilog.info(0x0000, PushLandingAbility.TAG, 'onCreate push_msgkey from storage: %{public}s', this.storageData.get("msg_id"));
    hilog.info(0x0000, PushLandingAbility.TAG, 'onCreate push_msgdata from storage: %{public}s', JSON.stringify(this.storageData.get("msg_data")));
  }

  async onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
    let k: string = ""
    let v: object = JSON.parse("{}")
    if (want.parameters) {
      if (want.parameters["msg_id"]) {
        k = want.parameters["msg_id"] as string
        hilog.info(0x0000, PushLandingAbility.TAG, 'onNewWant k: %{public}s', k);
      }
      if (want.parameters["msg_data"]) {
        v = want.parameters["msg_data"]
        hilog.info(0x0000, PushLandingAbility.TAG, 'onNewWant k: %{public}s', v);
      }
    }
    this.storageData.set('msg_id', k)
    this.storageData.set('msg_data', JSON.stringify(v))

    hilog.info(0x0000, PushLandingAbility.TAG, 'onNewWant push_msgkey: %{public}s', this.storageData.get("msg_id"));
    hilog.info(0x0000, PushLandingAbility.TAG, 'onNewWant push_msgdata: %{public}s', JSON.stringify(this.storageData.get("msg_data")));
    
		// 进入该阶段需要手动加载一下页面
		if (this.landingWindowStage != null) {
      await this.landingWindowStage.loadContent('pushpages/pushLandingPage', this.storageData)
    }

  }

  onDestroy(): void {
    hilog.info(0x0000, PushLandingAbility.TAG, '%{public}s', 'Ability onDestroy');
  }

  async onWindowStageCreate(windowStage: window.WindowStage): Promise<void> {
    // Main window is created, set main page for this ability
    // 创建新实例并使用给定对象初始化
    this.landingWindowStage = windowStage
    hilog.info(0x0000, PushLandingAbility.TAG, 'this.pushKey= %{public}s',this.storageData.get("msg_id"));
    hilog.info(0x0000, PushLandingAbility.TAG, 'this.pushData= %{public}s', JSON.stringify(this.storageData.get("msg_data")));

    try {
      await windowStage.loadContent('pushpages/pushLandingPage', this.storageData)
      hilog.info(0x0000, PushLandingAbility.TAG, 'Succeeded in loading the content. Key: %{public}s, Data: %{public}s',this.storageData.get("msg_id"), JSON.stringify(this.storageData.get("msg_data")) ?? '');
    } catch (e) {
      console.log("err msg="+e.message)
      return
    }
  }

  onWindowStageDestroy(): void {
    hilog.info(0x0000, PushLandingAbility.TAG, '%{public}s', 'Ability onWindowStageDestroy');
  }

  onForeground(): void {
    hilog.info(0x0000, PushLandingAbility.TAG, '%{public}s', 'Ability onForeground');
  }

  onBackground(): void {
    hilog.info(0x0000, PushLandingAbility.TAG, '%{public}s', 'Ability onBackground');
  }
}

配置透传消息 Ability

后端可以向客户端推送 App 的后台消息,而不展示通知栏。但开发者仍然可以通过特定的方法获取推送的数据。MPS 已经实现了不拉起应用子进程的后台消息。

  1. 开发者需继承 MpaasExtDefaultNcAbility 类实现自己的 Ability,如下所示:

    import { MpaasExtDefaultNcAbility } from '@mpaas/push';
    
    export default class MpaasBridgeExtMsgAbility extends MpaasExtDefaultNcAbility {
    
      async onCreate(): Promise<void> {
        // 收到eventId为9999的事件后执行回调函数
        emitter.on(innerEvent, (data) => {
          if (data.data != null) {
            console.log("onCreate receivedMsg="+JSON.stringify(data.data["receivedMsg"]))
          } else  {
            console.log("onCreate receivedMsg="+data.data)
          }
    
        });
        await super.onCreate()
      }
    
    }

    onCreate() 方法中执行 super.onCreate(),之后即可通过 MpaasExtDefaultNcAbility.getReceivedMsg() 获取后台推送的消息。

  2. 需要在 module.json5 文件中配置 MpaasBridgeExtMsgAbility,如下所示:

    {
     "name": "MpaasBridgeExtMsgAbility",
     "srcEntry": "./ets/pushability/MpaasBridgeExtDeMsgAbility.ets",
     "launchType": "singleton",
     "startWindowIcon": "$media:icon",
     "startWindowBackground": "$color:start_window_background",
     "skills": [
     {
     "actions": [
     "action.ohos.push.listener"
     ]
     }
     ]
    }

    其中,skills 里配置 actions 内容为 action.ohos.push.listener

    重要

    有且只能有一个 ability 定义该 action,若同时添加 uris 参数,则 uris 内容需为空。

角标清理

可以调用 MPS 提供的方法,实现在打开 App 的时候将应用的角标数字清理掉,方法如下所示:

BadgeUtil.clearBadge()