鸿蒙OS 公共事件与通知

鸿蒙OS 公共事件与通知的概述

HarmonyOS 通过 CES(Common Event Service,公共事件服务)为应用程序提供订阅、发布、退订公共事件的能力,通过 ANS(Advanced Notification Service,即高级通知服务)系统服务来为应用程序提供发布通知的能力。

公共事件可分为系统公共事件和自定义公共事件。
系统公共事件:系统将收集到的事件信息,根据系统策略发送给订阅该事件的用户程序
IntentAgent 封装了一个指定行为的 Intent,可以通过 IntentAgent 启动 Ability 和发送公共事件。
应用如果需要接收公共事件,需要订阅相应的事件。

约束与限制
公共事件的约束与限制

目前公共事件仅支持动态订阅。部分系统事件需要具有指定的权限,具体的权限见API参考。
目前公共事件订阅不支持多用户。
ThreadMode 表示线程模型,目前仅支持 HANDLER 模式,即在当前 UI 线程上执行回调函数。
deviceId 用来指定订阅本地公共事件还是远端公共事件。deviceId 为 null、空字符串或本地设备 deviceId 时,表示订阅本地公共事件,否则表示订阅远端公共事件。

通知的约束与限制

通知目前支持六种样式:普通文本、长文本、图片、社交、多行文本和媒体样式。创建通知时必须包含一种样式。
通知支持快捷回复。
目前通知订阅不支持多用户。
通知的订阅目前仅支持系统应用,不支持第三方应用。

IntentAgent 的限制

使用 IntentAgent 启动 Ability 时,Intent 必须指定 Ability 的包名和类名

鸿蒙OS 公共事件开发指导

每个应用都可以订阅自己感兴趣的公共事件,订阅成功后且公共事件发布后,系统会把其发送给应用。这些公共事件可能来自系统、其他应用和应用自身。HarmonyOS 提供了一套完整的 API,支持用户订阅、发送和接收公共事件。发送公共事件需要借助 CommonEventData 对象,接收公共事件需要继承 CommonEventSubscriber 类并实现 onReceiveEvent 回调函数。

接口说明

公共事件相关基础类包含 CommonEventData、CommonEventPublishInfo、CommonEventSubscribeInfo、CommonEventSubscriber 和 CommonEventManager。基础类之间的关系如下图所示:

在这里插入图片描述

在这里插入图片描述

有序公共事件:主要场景是多个订阅者有依赖关系或者对处理顺序有要求,例如:高优先级订阅者可修改公共事件内容或处理结果,包括终止公共事件处理;或者低优先级订阅者依赖高优先级的处理结果等。

有序公共事件的订阅者可以通过 CommonEventSubscribeInfo.setPriority() 方法指定优先级,缺省为 0,优先级范围[-1000, 1000],值越大优先级越高。

粘性公共事件:指公共事件的订阅动作是在公共事件发布之后进行,订阅者也能收到的公共事件类型。主要场景是由公共事件服务记录某些系统状态,如蓝牙、WLAN、充电等事件和状态。不使用粘性公共事件机制时,应用可以通过直接访问系统服务获取该状态;在状态变化时,系统服务、硬件需要提供类似 observer 等方式通知应用。
发布粘性公共事件可以通过 setSticky() 方法设置, 发布粘性公共事件需要申请如下权限。

  "reqPermissions": [{
        "name": "ohos.permission.COMMONEVENT_STICKY",
        "reason": "get right",
        "usedScene": {
           "ability": [
            ".MainAbility"
           ],
           "when": "inuse"
        }
    }, {
    ...
    }]

接口名 描述
在这里插入图片描述

CommonEventSubscribeInfo 封装公共事件订阅相关信息,比如优先级、线程模式、事件范围等。

线程模式(ThreadMode):设置订阅者的回调方法执行的线程模式。ThreadMode 有 HANDLER,POST,ASYNC,BACKGROUND 四种模式,目前只支持 HANDLER 模式。

HANDLER:在 Ability 的主线程上执行。
POST:在事件分发线程执行。
ASYNC:在一个新创建的异步线程执行。
BACKGROUND:在后台线程执行。

在这里插入图片描述

在这里插入图片描述

发布无序的公共事件:构造 CommonEventData 对象,设置 Intent,通过构造operation 对象把需要发布的公共事件信息传入 intent 对象。然后调用 CommonEventManager.publishCommonEvent(CommonEventData) 接口发布公共事件。

try {
     Intent intent = new Intent();   
     Operation operation = new Intent.OperationBuilder()
             .withAction("com.my.test")
             .build();
     intent.setOperation(operation);
     CommonEventData eventData = new CommonEventData(intent);
     CommonEventManager.publishCommonEvent(eventData); 
} catch (RemoteException e) {
     HiLog.info(LABEL, "publishCommonEvent occur exception."); 
}

发布携带权限的公共事件:构造 CommonEventPublishInfo 对象,设置订阅者的权限。

 {
      "reqPermissions": [{
          "name": "com.example.MyApplication.permission",
          "reason": "get right",
          "usedScene": {
             "ability": [
              ".MainAbility"
             ],
             "when": "inuse"
          }
      }, {
      ...
      }]
  }

发布带权限的公共事件示例代码如下:

 Intent intent = new Intent();
  Operation operation = new Intent.OperationBuilder()
          .withAction("com.my.test")
          .build();
  intent.setOperation(operation);
  CommonEventData eventData = new CommonEventData(intent);
  CommonEventPublishInfo publishInfo = new CommonEventPublishInfo();
  String[] permissions = {"com.example.MyApplication.permission" };
  publishInfo.setSubscriberPermissions(permissions); // 设置权限
  try {   
       CommonEventManager.publishCommonEvent(eventData, publishInfo); 
  } catch (RemoteException e) {
       HiLog.info(LABEL, "publishCommoneEvent occur exception."); 
  }

发布有序的公共事件:构造 CommonEventPublishInfo 对象,通过 setOrdered(true) 指定公共事件属性为有序公共事件,也可以指定一个最后的公共事件接收者。

CommonEventSubscriber resultSubscriber = new MyCommonEventSubscriber();
CommonEventPublishInfo publishInfo = new CommonEventPublishInfo();
publishInfo.setOrdered(true); // 设置属性为有序公共事件
try {   
    CommonEventManager.publishCommonEvent(eventData, publishInfo, resultSubscriber); // 指定resultSubscriber为有序公

共事件最后一个接收者。

} catch (RemoteException e) {
    HiLog.info(LABEL, "publishCommoneEvent occur exception."); 
}

发布粘性公共事件:构造 CommonEventPublishInfo 对象,通过 setSticky(true)
指定公共事件属性为粘性公共事件。

发布者首先在 config.json 中申请发布粘性公共事件所需的权限,各字段含义详见权限申请字段说明。

{
       "reqPermissions": [{
           "name": "ohos.permission.COMMONEVENT_STICKY",
           "reason": "get right",
           "usedScene": {
              "ability": [
               ".MainAbility"
              ],
              "when": "inuse"
           }
       }, {
       ...
       }]
   }

布粘性公共事件。

 CommonEventPublishInfo publishInfo = new CommonEventPublishInfo();
   publishInfo.setSticky(true); // 设置属性为粘性公共事件
   try {   
       CommonEventManager.publishCommonEvent(eventData, publishInfo); 
   } catch (RemoteException e) {
       HiLog.info(LABEL, "publishCommoneEvent occur exception."); 
   }

订阅公共事件
创建 CommonEventSubscriber 派生类,在 onReceiveEvent() 回调函数中处理公共事件。
说明

 class MyCommonEventSubscriber extends CommonEventSubscriber { 
       MyCommonEventSubscriber(CommonEventSubscribeInfo info) { 
           super(info);   
       }
       @Override 
       public void onReceiveEvent(CommonEventData commonEventData) {
       } 
   }
构造 MyCommonEventSubscriber 对象,调用 CommonEventManager.subscribeCommonEvent() 接口进行订阅。
   String event = "com.my.test";
   MatchingSkills matchingSkills = new MatchingSkills();
   filter.addEvent(event); // 自定义事件
   filter.addEvent(CommonEventSupport.COMMON_EVENT_SCREEN_ON); // 亮屏事件
   CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);
   MyCommonEventSubscriber subscriber = new MyCommonEventSubscriber(subscribeInfo);
   try {
       CommonEventManager.subscribeCommonEvent(subscriber); 
   } catch (RemoteException e) {
       HiLog.info(LABEL, "subscribeCommonEvent occur exception."); 
   }
如果订阅拥有指定权限应用发布的公共事件,发布者需要在 config.json 中申请权限,各字段含义详见 权限申请字段说明。

   "reqPermissions": [
       {
           "name": "ohos.abilitydemo.permission.PROVIDER",
           "reason": "get right",
           "usedScene": {
               "ability": ["com.huawei.hmi.ivi.systemsetting.MainAbility"],
               "when": "inuse"
           }
       }
   ]

如果订阅的公共事件是有序的,可以调用 setPriority()指定优先级。

 String event = "com.my.test";
   MatchingSkills matchingSkills = new MatchingSkills();
   matchingSkills.addEvent(event ); // 自定义事件

    
   CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);
   subscribeInfo.setPriority(100); // 设置优先级,优先级取值范围[-1000,1000],值默认为0。
   MyCommonEventSubscriber subscriber = new MyCommonEventSubscriber(subscribeInfo);
   try {
        CommonEventManager.subscribeCommonEvent(subscriber); 
   } catch (RemoteException e) {
        HiLog.info(LABEL, "subscribeCommonEvent occur exception."); 
   }
针对在 onReceiveEvent 中不能执行耗时操作的限制,可以使用 CommonEventSubscriber 的 goAsyncCommonEvent() 来实现异步操作,函数返回后仍保持该公共事件活跃,且执行完成后必须调用 AsyncCommonEventResult .finishCommonEvent() 来结束。
   EventRunner runner = EventRunner.create(); //EventRunner 创建新线程,将耗时的操作放到新的线程上执行
   MyEventHandler myHandler = new MyEventHandler(runner); //MyEventHandler 为 EventHandler 的派生类,在不同线程间分发和处理事件和 Runnable 任务
   @Override
   public void onReceiveEvent(CommonEventData commonEventData){
       final AsyncCommonEventResult result = goAsyncCommonEvent();

    
       Runnable task = new Runnable() {
           @Override
           public void run() {
               ........         // 待执行的操作,由开发者定义
               result.finishCommonEvent(); // 调用finish结束异步操作
           }
       };
       myHandler.postTask(task);
   } 

退订公共事件
在 Ability的onStop() 中调用 CommonEventManager.unsubscribeCommonEvent() 方法来退订公共事件。调用后,之前订阅的所有公共事件均被退订。

try { 
    CommonEventManager.unsubscribeCommonEvent(subscriber);
 } catch (RemoteException e) {
    HiLog.info(LABEL, "unsubscribeCommonEvent occur exception.");
 }

鸿蒙OS 通知开发指导

HarmonyOS 提供了通知功能,即在一个应用的 UI 界面之外显示的消息,主要用来提醒用户有来自该应用中的信息。当应用向系统发出通知时,它将先以图标的形式显示在通知栏中,用户可以下拉通知栏查看通知的详细信息。常见的使用场景:
显示接收到短消息、即时消息等。
显示应用的推送消息,如广告、版本更新等。
显示当前正在进行的事件,如播放音乐、导航、下载等。

接口说明
通知相关基础类包含 [ NotificationSlot ]、[ NotificationRequest ]和[ NotificationHelper ]。基础类之间的关系如下所示:

通知基础类关系图

在这里插入图片描述

NotificationSlot 时,当前通知会使用默认的 NotificationSlot,默认的 NotificationSlot 优先级为 LEVEL_DEFAULT 。

在这里插入图片描述

NotificationSlot 的级别目前支持如下几种, 由低到高:

LEVEL_NONE: 表示通知不发布。
LEVEL_MIN:表示通知可以发布,但是不显示在通知栏,不自动弹出,无提示音;该级别不适用于前台服务的场景。
LEVEL_LOW:表示通知可以发布且显示在通知栏,不自动弹出,无提示音。
LEVEL_DEFAULT:表示通知发布后可在通知栏显示,不自动弹出,触发提示音。
LEVEL_HIGH:表示通知发布后可在通知栏显示,自动弹出,触发提示。
NotificationRequest

NotificationRequest 用于设置具体的通知对象,包括设置通知的属性,如:通知的分发时间、小图标、大图标、自动删除等参数,以及设置具体的通知类型,如普通文本、长文本等。

在这里插入图片描述

通知发布后,通知的设置不可修改。如果下次发布通知使用相同的 id,就会更新之前发布的通知。

NotificationHelper
NotificationHelper 封装了发布、更新、订阅、删除通知等静态方法。订阅通知、退订通知和查询系统中所有处于活跃状态的通知,有权限要求需为系统应用或具有订阅者权限。

在这里插入图片描述

开发步骤

通知的开发指导分为创建 NotificationSlot、发布通知和取消通知等开发场景。

创建NotificationSlot

NotificationSlot 可以设置公共通知的震动,锁屏模式,重要级别等,并通过调用 NotificationHelper.addNotificationSlot() 发布 NotificationSlot 对象。

NotificationSlot slot = new NotificationSlot("slot_001","slot_default", NotificationSlot.LEVEL_MIN); // 创建notificationSlot对象
slot.setDescription("NotificationSlotDescription");
slot.setEnableVibration(true); // 设置振动提醒
slot.setLockscreenVisibleness(NotificationRequest.VISIBLENESS_TYPE_PUBLIC);//设置锁屏模式
slot.setEnableLight(true); // 设置开启呼吸灯提醒
slot.setLedLightColor(Color.RED.getValue());// 设置呼吸灯的提醒颜色
try {
   NotificationHelper.addNotificationSlot(slot);
} catch (RemoteException ex) {
   HiLog.warn(LABEL, "addNotificationSlot occur exception.");
}

发布通知

构建 NotificationRequest 对象,应用发布通知前,通过 NotificationRequest 的 setSlotId() 方法与 NotificationSlot 绑定,使该通知在发布后都具备该对象的特征。

  int notificationId = 1;
   NotificationRequest request = new NotificationRequest(notificationId);
   request.setSlotId(slot.getId());

调用 setContent() 设置通知的内容。

  String title = "title";
   String text = "There is a normal notification content.";
   NotificationNormalContent content = new NotificationNormalContent();
   content.setTitle(title)
          .setText(text);
   NotificationContent notificationContent = new NotificationContent(content);
   request.setContent(notificationContent); // 设置通知的内容
调用 publishNotification() 发送通知。
   try {
      NotificationHelper.publishNotification(request);
   } catch (RemoteException ex) {
      HiLog.warn(LABEL, "publishNotification occur exception.");
   }

取消通知

取消通知分为取消指定单条通知和取消所有通知,应用只能取消自己发布的通知。

调用 cancelNotification() 取消指定的单条通知。

 int notificationId = 1;
  try {
      NotificationHelper.cancelNotification(notificationId);
  } catch (RemoteException ex) {
      HiLog.warn(LABEL, "cancelNotification occur exception.");
  }

调用 cancelAllNotifications() 取消所有通知。

 try {
      NotificationHelper.cancelAllNotifications();
  } catch (RemoteException ex) {
      HiLog.warn(LABEL, "cancelAllNotifications occur exception.");
  }

鸿蒙OS IntentAgent开发指导

IntentAgent封装了一个指定行为的 Intent,可以通过 triggerIntentAgent 接口主动触发,也可以与通知绑定被动触发。具体的行为包括:启动 Ability 和发送公共事件。例如:收到通知后,在点击通知后跳转到一个新的 Ability,不点击则不会触发。

接口说明
IntentAgent 相关基础类包括 IntentAgentHelper、 IntentAgentInfo、 IntentAgentConstant 和 TriggerInfo,基础类之间的关系如下图所示:

在这里插入图片描述

IntentAgentHelper封装了获取、激发、取消IntentAgent等静态方法。

在这里插入图片描述

IntentAgentInfo

IntentAgentInfo 类封装了获取一个 IntentAgent 实例所需的数据。使用构造函数 IntentAgentInfo(int requestCode, OperationType operationType, List flags, List intents, IntentParams extraInfo) 获取 IntentAgentInfo 对象。
requestCode:使用者定义的一个私有值。
operationType:为 IntentAgentConstant.OperationType 枚举中的值。
flags:为 IntentAgentConstant.Flags 枚举中的值。
intents:将被执行的意图列表。operationType 的值为 START_ABILITY,START_SERVICE 和 SEND_COMMON_EVENT 时,intents 列表只允许包含一个 Intent;operationType 的值为 START_ABILITIES 时,intents 列表允许包含多个 Intent
extraInfo:表明如何启动一个有页面的 ability,可以为 null,只在operationType 的值为 START_ABILITY 和 START_ABILITIES 时有意义。
IntentAgentConstant

IntentAgentConstant 类中包含 OperationType 和 Flags 两个枚举类:

类名 枚举值
在这里插入图片描述

TriggerInfo
TriggerInfo 类封装了主动激发一个 IntentAgent 实例所需的数据,使用构造函数TriggerInfo( String permission, IntentParams extraInfo, Intent intent, int code) 获取 TriggerInfo 对象。

permission:IntentAgent 的接收者的权限名称,只在 operationType 的值为 SEND_COMMON_EVENT 时,该参数才有意义。
extraInfo:激发 IntentAgent 时用户自定义的额外数据。
intent:额外的 Intent。如果 IntentAgentInfo 成员变量 flags 包含CONSTANT_FLAG,则忽略该参数;如果 flags 包含 REPLACE_ELEMENT,REPLACE_ACTION,REPLACE_URI,REPLACE_ENTITIES 或 REPLACE_BUNDLE,则使用额外 Intent 的 element,action,uri,entities 或 bundleName 属性替换原始 Intent 中对应的属性。如果 intent 是空,则不替换原始 Intent 的属性。
code:提供给 IntentAgent 目标的结果码。

开发步骤
获取 IntentAgent 的代码示例如下:

// 指定要启动的Ability的BundleName和AbilityName字段
// 将Operation对象设置到Intent中
Operation operation = new Intent.OperationBuilder()
        .withDeviceId("")
        .withBundleName("com.huawei.testintentagent")
        .withAbilityName("com.huawei.testintentagent.entry.IntentAgentAbility")
        .build();
intent.setOperation(operation);
List<Intent> intentList = new ArrayList<>();
intentList.add(intent);
// 定义请求码
int requestCode = 200;
// 设置flags
List<Flags> flags = new ArrayList<>();
flags.add(Flags.UPDATE_PRESENT_FLAG);
// 指定启动一个有页面的Ability
IntentAgentInfo paramsInfo = new IntentAgentInfo(requestCode, IntentAgentConstant.OperationType.START_ABILITY, flags, intentList, null);
// 获取IntentAgent实例
IntentAgent agent = IntentAgentHelper.getIntentAgent(this, paramsInfo);

通知中添加 IntentAgent 的代码示例如下:

int notificationId = 1;
NotificationRequest request = new NotificationRequest(notificationId);
String title = "title";
String text = "There is a normal notification content.";
NotificationNormalContent content = new NotificationNormalContent();
content.setTitle(title)
       .setText(text);
NotificationContent notificationContent = new NotificationContent(content);
request.setContent(notificationContent); // 设置通知的内容
request.setIntentAgent(agent); // 设置通知的 IntentAgent

主动激发 IntentAgent 的代码示例如下:

int code = 100;
IntentAgentHelper.triggerIntentAgent(this, agent, null, null, new TriggerInfo(null, null, null, code ));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

看山还是山,看水还是。

你的打赏是我最大鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值