HarmonyOS SDK接入

本章节介绍了HarmonyOS SDK的接入方法。

前言

本SDK基于HarmonyOS API 12 Release开发,compileSdkVersion 为 5.0.0(12)。

准备工作

  1. 请参考HarmonyOS应用开发文档准备HarmonyOS应用开发环境。

  2. 请参考Native应用开发流程创建鸿蒙应用,在应用设置中查看AppKey和AppSecret。

  3. 请参考HarmonyOS Push Kit开发准备,配置应用,获取鸿蒙Push Token。

  4. 请参考请求通知授权实现应用请求授权逻辑。

  5. 如需推送通知扩展消息,请参考发送通知扩展消息申请相关权益。

第一步:安装SDK

在HarmonyOS应用根目录执行以下命令来安装SDK:

ohpm install @aliyun/push

ohpm工具及更多关于OpenHarmony安装第三方SDK的信息请参考OpenHarmony三方库中心仓说明

SDK的最新版本及更新记录请参考SDK信息更新记录

第二步:初始化SDK

在Ability onCreate生命周期回调中执行以下代码初始化配置SDK:

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { aliyunPush } from '@aliyun/push';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {

    // ************* 初始化配置 begin *************
    aliyunPush.init({
      appKey: '请填入在准备工作中查询的应用AppKey',
      appSecret: '请填入在准备工作中查询的应用AppSecret',
      context: this.context,
    })
    // ************* 初始化配置 end *************
  }

  // 省略其它代码
}

其中appKey,appSecret请配置为在准备工作中获取的AppKey和AppSecret。

第三步:设置推送回调接口

在UIAbility的onCreate回调方法中并且在初始化SDK之后设置推送回调接口,用于接收推送数据。示例代码如下:

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { aliyunPush, ExtensionNotification, IPushListener, PushMessage, PushNotification } from '@aliyun/push';

// ************* IPushListener接口实现 begin *************
/**
 * 推送回调接口实现,用于接收推送数据
 */
class MyPushListener implements IPushListener {

  onReceiveNotification(data: PushNotification | ExtensionNotification): boolean {
    // 处理推送通知
    // 返回false 表示不定制通知。返回true,表示定制通知。
    return false;
  }

  onShowNotification(data: PushNotification | ExtensionNotification): void {
    // 处理通知展示事件
  }

  onReceiveMessage(data: PushMessage): void {
    // 处理推送消息
  }
}
// ************* IPushListener接口实现 end *************

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {

    aliyunPush.init({
      appKey: '请填入在SDK接入准备工作中查询的应用AppKey',
      appSecret: '请填入在SDK接入准备工作中查询的应用AppSecret',
      context: this.context,
    })

    // ************* 注册IPushListener接口 begin *************
    aliyunPush.setPushListener(new MyPushListener());
    // ************* 注册IPushListener接口 end *************
  }

  // 省略其它代码

  onDestroy(): void {
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    // Main window is created, set main page for this ability

    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        return;
      }
    });
  }

  onWindowStageDestroy(): void {
    // Main window is destroyed, release UI related resources
  }

  onForeground(): void {
    // Ability has brought to foreground
  }

  onBackground(): void {
    // Ability has back to background
  }
}

关于推送回调接口的详细说明,请参考接收推送通知/消息

第四步:调用推送通知点击处理接口

调用SDK的handleClickNotification方法,用于处理用户点击通知的行为,获取推送的数据。调用的位置有两处:

  1. 在UIAbility的onCreate回调方法中并且在初始化SDK之后

  2. 在UIAbility的onNewWant回调方法中

示例代码如下:

import { aliyunPush, Channel,
  ExtensionNotification,
  PushMessage, PushNotification, PushNotificationHandler } from '@aliyun/push';
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';

// ************* 自定义推送数据的处理类 begin *************
class MyPushNotificationHandler implements PushNotificationHandler {
  onClickNotification(data: PushNotification | PushMessage | ExtensionNotification, from: Channel): void {
    // 根据业务处理推送的数据
  }

  noPushData(): void {
    // 没有推送数据,不是用户点击推送通知拉起的界面
  }
}
// ************* 自定义推送数据的处理类 end *************

// 点击通知要打开的Ability
export class TargetAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {

    // ************* 初始化Push begin *************
    aliyunPush.init({
      appKey: '请填入在准备工作中查询的应用AppKey',
      appSecret: '请填入在准备工作中查询的应用AppSecret',
      context: this.context,
    })
    // ************* 初始化Push end *************

    // ************* 处理推送数据 begin *************
    aliyunPush.handleClickNotification(want, new MyPushNotificationHandler())
    // ************* 处理推送数据 end *************

  }

  onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    // 页面已经启动的场景
    // ************* 处理推送数据 begin *************
    aliyunPush.handleClickNotification(want, new MyPushNotificationHandler())
    // ************* 处理推送数据 end *************
  }

  // 省略其它代码
}

关于handleClickNotification方法的详细说明,请参考从通知中获取推送数据

第五步:注册设备获取设备ID

在UIAbility的onCreate回调方法中,初始化SDK之后,需要调用SDK的register方法注册设备。

注册设备是推送的必要步骤,在成功注册设备之后,才可以请求注册鸿蒙PushToken,绑定账号、添加别名、绑定标签等等一系列API。

示例代码如下:

import { aliyunPush } from '@aliyun/push';

aliyunPush.register((err) => {
  if (err) {
    console.error(`注册设备失败,错误码:${err.code} 错误信息${err.message}`);
    return;
  }
  console.info(`注册设备成功,设备ID为${aliyunPush.getDeviceId()}`);
});

设备注册成功后,SDK会和服务端建立长连接,此时就可以调用getDeviceId方法获取设备ID,通过控制台或者OpenAPI按终端向应用推送。

第六步:注册鸿蒙PushToken(可选)

要使用鸿蒙厂商通道,需要通过SDK把鸿蒙的PushToken注册到移动推送平台。需要在注册设备成功之后调用。示例代码如下:

import { aliyunPush } from '@aliyun/push';
import { pushService } from '@kit.PushKit';
import { BusinessError } from '@kit.BasicServicesKit';

pushService.getToken().then((pushToken) => {
  // ************* 注册PushToken begin *************
  aliyunPush.registerThirdToken(pushToken, (error) => {
    if (error) {
      console.error(`注册PushToken失败,错误码:${error.code} 错误信息${error.message}`);
      return;
    }
    console.info(`注册PushToken成功`);
  })
  // ************* 注册PushToken end *************
}).catch((error: BusinessError) => {
  console.error(`获取PushToken失败,错误码:${error.code} 错误信息${error.message}`);
})

关于鸿蒙厂商通道,请参考厂商通道

第七步:实现鸿蒙厂商通道的通知扩展消息接收(可选)

如果接入了鸿蒙厂商通道,同时要推送通知扩展消息,需要在接收到通知扩展消息时,调用SDK接口解析获取推送数据,进行下一步操作。

RemoteNotificationExtensionAbility接收通知扩展消息的处理代码示例如下:

import { pushCommon, RemoteNotificationExtensionAbility } from '@kit.PushKit';
import { aliyunPush, ExtensionNotification } from '@aliyun/push';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { common } from '@kit.AbilityKit';

export default class SampleRemoteNotification extends RemoteNotificationExtensionAbility {
  async onReceiveMessage(remoteNotificationInfo: pushCommon.RemoteNotificationInfo):
    Promise<pushCommon.RemoteNotificationContent> {
    // ************* 通知扩展消息处理 begin *************
    // 初始化推送参数,用于解析推送数据
    aliyunPush.init({
      appKey: '请填入在准备工作中查询的应用AppKey',
      appSecret: '请填入在准备工作中查询的应用AppSecret',
      context: this.context as common.Context,
    })

    // 调用parseExtensionPushData解析推送的参数
    const notification: ExtensionNotification = await aliyunPush.parseExtensionPushData(remoteNotificationInfo);

    // 这里可以获取通知扩展消息的参数进行业务处理

    // SDK提供辅助方法getRemoteNotificationContent构建返回值, 传参EntryAbility是本次通知点击要打开的Ability名称
    const result = aliyunPush.getPushHelper().getRemoteNotificationContent('EntryAbility', notification);
    return result;
    // 如果要修改通知的内容,可以返回想要修改的内容,wantAgent建议还是保留。如果不保留,后续就无法在用户点击时识别推送的参数,会丢失通知的点击数据
    // return {
    //   // 省略其它修改的字段,wantAgent建议还是使用getRemoteNotificationContent方法构造的参数。
    //   wantAgent: result.wantAgent
    // }
    // ************* 通知扩展消息处理 end *************
  }
}

pushService.receiveMessage接收通知扩展消息的处理代码示例如下:

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {

    // ************* 初始化SDK begin *************
    aliyunPush.init({
      appKey: '请填入在准备工作中查询的应用AppKey',
      appSecret: '请填入在准备工作中查询的应用AppSecret',
      context: this.context,
    })
    // ************* 初始化SDK end *************

    // 省略其它初始化配置方法

    // ************* 设置应用在前台时鸿蒙厂商通道的通知扩展消息接收接口 begin *************
    pushService.receiveMessage("IM", this, async (data: pushCommon.PushPayload) => {
      // 解析推送参数
      const extensionNotification: ExtensionNotification = await aliyunPush.parseExtensionPushData(data);
      // 这里根据获取的通知扩展消息参数进行业务处理
    })
    // ************* 设置应用在前台时鸿蒙厂商通道的通知扩展消息接收接口 end *************
  }
  // 省略其它代码
}

关于RemoteNotificationExtensionAbility和pushService.receiveMessage的改动请参考通知扩展消息的开发步骤说明

关于如何使用阿里云推送平台推送通知扩展消息,请参考通知扩展消息

第八步:发起推送

通过控制台的推送通知推送消息或者OpenAPI的推送相关接口,使用按设备推送,即可发起推送,SDK在接收到推送之后,会回调第三步:设置推送回调接口中设置的回调接口。

对于推送的通知,SDK在接收到之后,会回调onReceiveNotification方法,告知应用收到通知。SDK创建并发布通知之后,会回调onShowNotification方法,告知应用通知已发布。

对于推送的消息,SDK在接收到之后,会回调onReceiveMessage方法,告知应用收到消息。

关于合规使用和延迟初始化

SDK使用的权限如下:

权限名称

权限说明

使用目的

权限申请时机

ohos.permission.INTERNET

允许使用Internet网络

在建立推送通道时,用于访问网络数据

安装应用时,系统自动授权

ohos.permission.GET_NETWORK_INFO

允许应用获取数据网络信息

在管理推送通道时,用于监听网络变化,在网络恢复时,即时恢复推送通道

安装应用时,系统自动授权

以上权限由系统在安装时自动授权,所以SDK并不需要主动向用户申请权限。

对于通知授权,请参考请求通知授权实现应用请求授权逻辑,SDK默认不会向用户申请通知授权。

对于SDK信息及隐私政策,请参考SDK信息

在用户同意使用SDK及同意通知授权之前,应用需要考虑延迟初始化SDK,我们的建议如下:

示例代码请参考SDK接入完整代码示例

SDK接入完整代码示例

为了方便理解SDK接入过程中的代码执行顺序,请参考以下代码:

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import {
  aliyunPush,
  Channel,
  ExtensionNotification,
  IPushListener,
  PushDataType,
  PushMessage,
  PushNotification,
  PushNotificationHandler
} from '@aliyun/push';
import { pushCommon, pushService } from '@kit.PushKit';
import { hilog } from '@kit.PerformanceAnalysisKit';

/**
 * 自定义的推送回调接口实现
 */
class MyPushListener implements IPushListener {
  onReceiveNotification(data: PushNotification | ExtensionNotification): boolean {
    if (data.type === PushDataType.Notification) {
      // 处理推送通知
    } else if (data.type === PushDataType.ExtensionNotification) {
      // 处理通知扩展消息
    }
    return false;
  }

  onShowNotification(data: PushNotification | ExtensionNotification): void {
    // 处理通知展示事件
  }

  onReceiveMessage(data: PushMessage): void {
    // 处理推送消息
  }
}

/**
 * 自定义推送数据的处理类
 */
class MyPushNotificationHandler implements PushNotificationHandler {
  onClickNotification(data: PushNotification | PushMessage | ExtensionNotification, from: Channel): void {
    // 由用户点击通知拉起的页面,获取推送数据,处理业务逻辑
  }

  noPushData(): void {
    // 不是由用户点击通知拉的页面, 或者不是阿里云推送的数据
  }
}

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {

    // ************* 初始化SDK begin *************
    aliyunPush.init({
      appKey: '请填入在准备工作中查询的应用AppKey',
      appSecret: '请填入在准备工作中查询的应用AppSecret',
      context: this.context,
    })
    // ************* 初始化SDK end *************

    // ************* 设置推送回调接口 begin *************
    aliyunPush.setPushListener(new MyPushListener());
    // ************* 设置推送回调接口 end *************

    // ************* 调用推送通知点击处理接口 begin *************
    aliyunPush.handleClickNotification(want, new MyPushNotificationHandler())
    // ************* 调用推送通知点击处理接口 end *************

    // 这里需要应用获取用户是否已经同意使用SDK的标记
    const userAgreed = false;
    if(userAgreed) {
      // 用户同意使用再初始化注册推送
      this.registerPush();
    }

    // ************* 设置应用在前台时鸿蒙厂商通道的通知扩展消息接收接口 begin *************
    pushService.receiveMessage("IM", this, async (data: pushCommon.PushPayload) => {
      // 解析推送参数
      const extensionNotification: ExtensionNotification = await aliyunPush.parseExtensionPushData(data);
      // 这里根据获取的通知扩展消息参数进行业务处理
    })
    // ************* 设置应用在前台时鸿蒙厂商通道的通知扩展消息接收接口 end *************
  }

  /**
   * 此方法可以延迟到用户同意使用SDK之后再执行
   */
  private async registerPush() {
    // ************* 注册设备获取设备ID begin *************
    await aliyunPush.register();
    const deviceId = aliyunPush.getDeviceId();
    // ************* 注册设备获取设备ID end *************

    const pushToken = await pushService.getToken();
    // ************* 注册鸿蒙PushToken begin *************
    await aliyunPush.registerThirdToken(pushToken);
    // ************* 注册鸿蒙PushToken end *************
  }

  onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    // ************* 调用推送通知点击处理接口 begin *************
    aliyunPush.handleClickNotification(want, new MyPushNotificationHandler())
    // ************* 调用推送通知点击处理接口 end *************
  }

  // 省略其它代码

  onDestroy(): void {
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    // Main window is created, set main page for this ability

    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        return;
      }
    });
  }

  onWindowStageDestroy(): void {
    // Main window is destroyed, release UI related resources
  }

  onForeground(): void {
    // Ability has brought to foreground
  }

  onBackground(): void {
    // Ability has back to background
  }
}

后续步骤

如果要通过别名、标签等方式推送,或者定制通知的样式等等功能,可以参考HarmonyOS SDK API