1

 哈喽,各位盆友们!我是你们亲爱的学徒小z,今天给大家分享一篇有关鸿蒙开发中公共事件和后台代理提醒的文章,发车!

一、公共事件与通知的异同对比

特性/机制公共事件(Common Event)通知(Notification)
定义应用程序间通信机制,用于订阅和发布系统或应用事件。应用程序向用户发送重要信息或提醒的机制。
通信目标系统或其他应用程序终端用户
数据传递事件数据在应用程序间传递,用于响应特定事件。信息直接展示给用户,通常不涉及数据的直接传递。
触发源可以是系统、其他应用程序或本应用程序。仅由本应用程序触发。
接收方式应用程序通过订阅机制接收事件。用户在设备的通知栏直接看到通知。
处理方式应用程序内部处理事件,可能触发UI更新或执行特定任务。用户可直接与通知交互,如打开应用、滑动清除等。
示例用途应用间同步状态、响应系统事件(如网络变化)。提醒用户查看信息、完成任务或参与活动。

二、公共事件

1. 简介

  • CES(公共事件服务)为应用程序提供订阅、发布、退订公共事件的能力
  • 从系统角度分类:系统公共事件和自定义公共事件

    • 系统公共事件:CES内部定义的公共事件,例如HAP安装、更新、卸载等
    • 自定义公共事件:应用定义的公共事件、可用于实现跨进程的事件通信能力
  • 公共事件按发送方式可分为:无序、有序、粘性

    • 有序:按照订阅者设置的优先级,多个订阅者具有相同的优先级,曾他们将随机接收到公共事件
    • 粘性公共事件:能够让订阅者收到在订阅前已经发送的公共事件就是粘性公共事件。普通的公共事件只能在订阅后发送才能被接收到。发送粘性事件必须是系统应用或系统服务,粘性事件发送后会一直存在系统中,且发送者需要申请ohos.permission.COMMONEVENT_STICKY权限

2. 一般步骤

  • 导入模块

    import { commonEventManager } from '@kit.BasicServicesKit';
  • 创建订阅者信息

    let subscriber:commonEventManager.CommonEventSubscriber; //用于保存创建成功的订阅者对象,后续使用其完成订阅及退订的动
    //订阅者信息
    let subscribeInfo:commonEventManager.CommonEventSubscribeInfo = {
        events: ["event"]
    };
  • 创建订阅者

    也可以将createSubscriber函数中的第二个参数直接写为箭头函数,而不必去创建一个回调函数,或使用Promise返回方式

    //创建订阅者回调
    function createCB(err: BusinessError, commonEventSubscriber:commonEventManager.CommonEventSubscriber) {
      if(!err) {
        console.info("createSubscriber");
        subscriber = commonEventSubscriber;
      } else {
        console.error(`createSubscriber failed, code is ${err.code}, message is ${err.message}`);
      }
    }
    ​
    //创建订阅者
    //回调形式
    try {
      commonEventManager.createSubscriber(subscribeInfo, createCB)
    } catch (error) {
      let err: BusinessError = error as BusinessError;
      console.error(`createSubscriber failed, code is ${err.code}, message is ${err.message}`);
    }
    ​
    // Promise形式
    commonEventManager.createSubscriber(subscribeInfo).then((commonEventSubscriber:commonEventManager.CommonEventSubscriber) => {
        console.info("createSubscriber");
        subscriber = commonEventSubscriber;
    }).catch((err: BusinessError) => {
        console.error(`createSubscriber failed, code is ${err.code}, message is ${err.message}`);
    });
  • 订阅公共事件

    • subscribe(subscriber: CommonEventSubscriber, callback: AsyncCallback<CommonEventData>): void 第二个参数为回调函数
    • 订阅公共事件前要先创建订阅者,然后才可以完成订阅

    在订阅者(Subscriber)的 createSubscriber 回调函数中订阅公共事件,是因为 createSubscriber 回调函数是订阅者实例化后的第一个回调函数,它通常用于初始化订阅者并执行一些初始化操作。在这个回调函数中订阅公共事件,可以确保在订阅者实例化后立即响应公共事件,从而提高应用的响应性。

    //创建订阅者回调
    function createCB(err: BusinessError, commonEventSubscriber:commonEventManager.CommonEventSubscriber) {
      if(!err) {
        console.info("createSubscriber");
        subscriber = commonEventSubscriber;
        //订阅公共事件
        try {
          commonEventManager.subscribe(subscriber, SubscribeCB);
        } catch (error) {
          let err: BusinessError = error as BusinessError;
          console.error(`subscribe failed, code is ${err.code}, message is ${err.message}`);
        }
      } else {
        console.error(`createSubscriber failed, code is ${err.code}, message is ${err.message}`);
      }
    }
  • 取消订阅公共事件

    • unsubscribe(subscriber: CommonEventSubscriber, callback?: AsyncCallback<void>): void
    //取消订阅公共事件回调
    function unsubscribeCB(err: BusinessError) {
        if (err) {
            console.error(`unsubscribe failed, code is ${err.code}, message is ${err.message}`);
        } else {
            console.info("unsubscribe");
        }
    }
    ​
    //取消订阅公共事件
    //等待异步接口subscribe执行完毕,开发者根据实际业务选择是否需要添加setTimeout
    setTimeout(() => {
      try {
        commonEventManager.unsubscribe(subscriber, unsubscribeCB);
      } catch (error) {
        let err: BusinessError = error as BusinessError;
        console.error(`unsubscribe failed, code is ${err.code}, message is ${err.message}`);
      }a
    }, 500);
  • 发布公共事件

    • 发布公共事件通常由系统服务或应用程序发起,用来向其他系统组件广播信息或者通知。而订阅公共事件则允许系统服务或应用程序注册对特定事件的兴趣,以便在事件发生时能够接收通知并作出响应。
    • publish(event: string, options: CommonEventPublishData, callback: AsyncCallback<void>): void
    • publish(event: string, callback: AsyncCallback<void>): void
    import { BusinessError } from '@kit.BasicServicesKit';
    ​
    //公共事件相关信息
    let options:commonEventManager.CommonEventPublishData = {
        code: 0,             //公共事件的初始代码
        data: "initial data",//公共事件的初始数据
        isOrdered: true     //有序公共事件
    }
    ​
    //发布公共事件回调
    function publishCB(err: BusinessError) {
        if (err) {
            console.error(`publish failed, code is ${err.code}, message is ${err.message}`);
        } else {
            console.info("publish");
        }
    }
    ​
    //发布公共事件
    try {
        commonEventManager.publish("event", options, publishCB);
    } catch (error) {
        let err: BusinessError = error as BusinessError;
        console.error(`publish failed, code is ${err.code}, message is ${err.message}`);
    }

三、后台代理提醒

1.简介

  • 除了应用程序可以发布通知,后台系统服务也可以发布提醒类通知。有Timer、Calender、 Alarm共三种提醒类型。当用户在应用程序中设置了定时提醒时,该应用可以被冻结或退出,有后台系统服务来代理计时功能和弹出提醒。
  • 后台代理提醒接口主要包括RemiderRequest类和reminderAgentManager模块,分别用来创建提醒实例的信息、发布提醒各取消提醒
  • ReminderRequest

    • 代理提醒对象,用于设置提醒类型、响铃时长等具体信息。

    系统能力:SystemCapability.Notification.ReminderAgent

    名称类型必填说明
    reminderTypeReminderType指明代理提醒类型。
    actionButton[ActionButton?, ActionButton?, ActionButton?]弹出的提醒通知中显示的按钮。-普通应用:最多支持两个按钮。-系统应用:API9最多支持两个按钮,在API10开始最多支持三个按钮。
    wantAgentWantAgent点击通知后需要跳转的目标ability信息。
    maxScreenWantAgentMaxScreenWantAgent提醒到达时,全屏显示自动拉起目标的ability信息。如果设备正在使用中,则弹出一个通知横幅框。说明:该接口为预留接口,暂不支持使用。
    ringDurationnumber指明响铃时长(单位:秒),默认1秒。
    snoozeTimesnumber指明延迟提醒次数,默认0次(不适用于倒计时提醒类型)。
    timeIntervalnumber执行延迟提醒间隔(单位:秒),最少5分钟(不适用于倒计时提醒类型)。
    titlestring指明提醒标题。
    contentstring指明提醒内容。
    expiredContentstring指明提醒过期后需要显示的内容。
    snoozeContentstring指明延迟提醒时需要显示的内容(不适用于倒计时提醒类型)。
    notificationIdnumber指明提醒使用的通知的id号,需开发者传入,相同id号的提醒会覆盖。
  • 鸿蒙开发中 @ohos.reminderAgentManager 常用接口

    接口名称描述参数返回值权限要求使用场景
    publishReminder发布后台代理提醒ReminderRequest, AsyncCallback<number>Promise<number>返回提醒的 reminderIdohos.permission.PUBLISH_AGENT_REMINDER创建倒计时、日历、闹钟等提醒
    cancelReminder取消指定 reminderId 的提醒number, AsyncCallback<void>Promise<void>--取消已设置的提醒
    getValidReminders获取当前应用已设置的所有有效(未过期)的提醒AsyncCallback<Array<ReminderRequest>>Promise<Array<ReminderRequest>>返回有效提醒的数组-检查当前应用设置的提醒状态
    addNotificationSlot添加通知渠道NotificationSlot, AsyncCallback<void>Promise<void>-ohos.permission.SET_NOTIFICATION_SLOT管理通知的显示优先级和分组

2.使用代理提醒步骤

当使用后台代理提醒进行开发时,需要先定义一个提醒实例,然后发布提醒

  • 导入支持模块

    import { reminderAgentManager } from '@kit.BackgroundTasksKit';
  • 定义一个一个倒计时提醒实例ReminderRequestTimer
  • publishReminder需要ohos.permission.PUBLISH_AGENT_REMINDER 权限,在modules.json5中声明

    import reminderAgentManager from '@ohos.reminderAgentManager';
    ​
    let timer: reminderAgentManager.ReminderRequestTimer = {
      reminderType: reminderAgentManager.ReminderType.REMINDER_TYPE_TIMER,
      triggerTimeInSeconds: 5,
      actionButton:[
        {
          title: "关闭",
          type: reminderAgentManager.ActionButtonType.ACTION_BUTTON_TYPE_CLOSE
        }
      ],
      title: "我的标题",
      content: "这里通知的内容,可以自定义",
      expiredContent: "更多",
      notificationId: 100
    }
    ​
    //导出发布函数
    export default function pubReminder(){
      //发布代理提醒
        //publishReminder需要ohos.permission.PUBLISH_AGENT_REMINDER 权限,在modules.json5中声明
      reminderAgentManager.publishReminder(timer, (err, reminderId) => {
        console.info(JSON.stringify(err))
        console.info("reminderId: " + reminderId)
      })
    }

四、简单案例 

1.图片展示

image.png

image.png

2.完整代码

//ReminderPage.ets
import { BusinessError, commonEventManager } from '@kit.BasicServicesKit'
import { promptAction } from '@kit.ArkUI'
import pubReminder from '../common/components/reminder'

@Entry
@Component
struct ReminderPage {
  @State result: string = 'nothing' //显示的数据
  @State isCheck: boolean = false // 订阅或取消的状态
  subscriber?:commonEventManager.CommonEventSubscriber

  createSubscriber(){
    //订阅信息
    let subscribeInfo:commonEventManager.CommonEventSubscribeInfo = {
      events: ["some"]
    };

    commonEventManager.createSubscriber(subscribeInfo, (err:BusinessError, subscriber) => {
      if( err){
        console.log("提示: 创建订阅者错误 err=" + JSON.stringify(err))
      }else{
        this.subscriber = subscriber
        this.result = "创建订阅者成功"
      }
    })
  }

  subscribe() {
    //订阅
    if (this.subscriber != null) {
      commonEventManager.subscribe(this.subscriber, (err, data) => {
        if (err) {
          console.log('提示: 处理公共事件 data = ' + JSON.stringify(err))
        } else {
          console.log("提示: 处理公共事件 data = " + JSON.stringify(data))
          //接受数据后可以进行处理,这里仅进行了显示
          this.result = `接受内容: event=${data.event} `
          this.result += `code=${data.code},data=${data.data}`
        }
      })
      this.result = '订阅成功'
    } else {
      promptAction.showToast({
        message: "提示,请首先创建订阅者", duration: 3000
      })
    }
  }

  unsubscribe(){
  //取消订阅
    if( this.subscriber != null){
      commonEventManager.unsubscribe(this.subscriber, (err) => {
        if( err){
          console.log('提示: 取消订阅错误 err = ' + JSON.stringify(err))
        } else {
          console.log('提示:已取消订阅')
          this.result = '取消订阅成功'
        }
      })
    }
  }

  publish(){
  //指定的公共事件相关信息
    let options: commonEventManager.CommonEventPublishData = {
      code: 1, //公共事件初始代码
      data: '发送的公共事件数据', //公共事件的初始数量
      // 可以设置更多相关信息
    }

    //发布带options参数的公共事件, 订阅了some事件的才能收到
    commonEventManager.publish('some', options, (err) => {
      if( err){
        console.log("提示: 公共事件发布错误 err= " + JSON.stringify(err))
      } else {
        console.log("提升:公共事件发布成功")
      }
    })
  }

  build() {
    Row(){
      Column(){
        Button('创建订阅者')
          .fontSize(39)
          .margin(20)
          .width('75%')
          .onClick( () => {
            this.createSubscriber()
          })
        Row(){
          Checkbox({name: 'checkbox', group: 'checkboxGroup'})
            .select(this.isCheck)
            .width(40)
            .height(40)
            .onChange( (value: boolean) => {
              console.log("提示:Checkbox value= " + value)
              this.isCheck = value
              if( value){
                this.subscribe()
              } else {
                this.unsubscribe()
              }
            })
          Text("订阅/取消订阅")
            .fontSize(30)
        }

        Button("发布公共事件")
          .fontSize(39)
          .margin(20)
          .width("75%")
          .onClick( () => {
            this.publish()
          })

        Button("发布代理提醒")
          .fontSize(39)
          .margin(20)
          .width('75%')
          .onClick( () => {
            pubReminder()
          })

        Text(this.result)
          .fontSize(30)
          .backgroundColor("#EEEEEE")
      }
      .width("100%")
    }
    .height("100%")
  }
}
//reminder.ets
import reminderAgentManager from '@ohos.reminderAgentManager';

let timer: reminderAgentManager.ReminderRequestTimer = {
  reminderType: reminderAgentManager.ReminderType.REMINDER_TYPE_TIMER,
  triggerTimeInSeconds: 5,
  actionButton:[
    {
      title: "关闭",
      type: reminderAgentManager.ActionButtonType.ACTION_BUTTON_TYPE_CLOSE
    }
  ],
  title: "我的标题",
  content: "这里通知的内容,可以自定义",
  expiredContent: "更多", //提醒过期后需要展示的内容
  notificationId: 100
}

//导出发布函数
export default function pubReminder(){
  //发布代理提醒
  reminderAgentManager.publishReminder(timer, (err, reminderId) => {
    console.info(JSON.stringify(err))
    console.info("reminderId: " + reminderId)
  })
}

拥有一颗学徒的心
1 声望0 粉丝