HarmonyOS Sample 之 CommonEvent 公共事件 原创 精华

Buty9147
发布于 2021-7-30 17:33
浏览
2收藏

@toc

CommonEvent 公共事件

介绍

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

搭建环境

安装DevEco Studio,详情请参考DevEco Studio下载
设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:

如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。
如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境

代码结构和逻辑关系

HarmonyOS Sample 之 CommonEvent 公共事件-鸿蒙开发者社区
CommonEventPlugin.java 公共事件插件,定义了事件监听器和事件订阅者,实现了用户订阅、发送和接收公共事件的功能。

实现步骤

1.事件监听器的定义和使用:

Plugin中定义事件监听器接口和接收事件的方法

/**
 * 定义通知事件监听器
 */
public interface NotificationEventListener {
    void onEventReceive(String result);
}

Plugin中声明事件监听器对象变量,并提供set方法

//通知事件监听器
private NotificationEventListener eventListener;
/**
 * 设置事件监听器
 *
 * @param eventListener Notification Even Listener
 */
public void setEvenListener(NotificationEventListener eventListener) {
    this.eventListener = eventListener;
}

Slice中implements事件监听器接口并在onStart初始化时设置监听器为this

/**
* MainAbilitySlice
*/
public class MainAbilitySlice extends AbilitySlice implements CommonEventPlugin.NotificationEventListener {

private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP,0xD0001,"=>"+MainAbilitySlice.class.getSimpleName());
private static final int DIALOG_BOX_WIDTH = 984;
private CommonEventPlugin notificationPlugin = new CommonEventPlugin(this);
private Text resultText;

@Override
public void onStart(Intent intent) {
    super.onStart(intent);
    super.setUIContent(ResourceTable.Layout_main_ability_slice);
    initComponents();

    //因为MainAbilitySlice 实现了CommonEventPlugin.NotificationEventListener
    notificationPlugin.setEvenListener(this);
}

Slice中实现事件监听器的接收事件的方法,用于信息展示。

/**
 * CommonEventPlugin.NotificationEventListener 接口定义的方法
 * @param result
 */
@Override
public void onEventReceive(String result) {
    HiLog.debug(LABEL,  "onEventReceive");
    resultText.setText(result);
}

2.事件订阅者的定义和使用:

Plugin中定义事件订阅者,需要继承CommonEventSubscriber,实现默认的构造方法以及onReceiveEvent方法,当接收到事件时通过事件监听器的onEventReceive方法通知Slice

/**
 * 自定义事件订阅者
 */
class TestCommonEventSubscriber extends CommonEventSubscriber {

    public TestCommonEventSubscriber(CommonEventSubscribeInfo subscribeInfo) {
        super(subscribeInfo);
    }

    @Override
    public void onReceiveEvent(CommonEventData commonEventData) {
        HiLog.debug(LABEL_LOG, "onReceiveEvent");
        if (commonEventData == null || commonEventData.getIntent() == null) {
            return;
        }
        //获取 Intent 中操作的描述。
        String receivedAction = commonEventData.getIntent().getAction();
        String receivedData= commonEventData.getData();
        //String receivedData=commonEventData.getIntent().getStringParam("eventInfo");
        HiLog.info(LABEL_LOG, "%{public}s", "onReceiveEvent action:" + receivedAction+",commonEventData:"+receivedData);
        //
        if (receivedAction.equals(event) && eventListener != null) {
            eventListener.onEventReceive("Receive commonevent succeeded,commonevent is:" + event);
        }
    }

}

Plugin中声明事件订阅者对象变量

//自定义事件订阅者
private TestCommonEventSubscriber subscriber;

在自定义订阅事件的方法中初始化事件订阅者对象,通过CommonEventManager.subscribeCommonEvent订阅事件。

/**
 * 订阅 commonEvent
 * Subscribe commonEvent
 */
public void subscribeEvent() {
    if (unSubscribe) {
        HiLog.debug(LABEL_LOG, "subscribeEvent");
        //封装订阅者想要订阅的特定常见事件。
        MatchingSkills matchingSkills = new MatchingSkills();
        matchingSkills.addEvent(event);


        CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);
        //设置此 CommonEventSubscribeInfo 对象的订阅者优先级。
        // 此方法仅用于有序的常见事件。 具有更高优先级的订阅者将首先收到此类事件。
        subscribeInfo.setPriority(100);

        subscriber = new TestCommonEventSubscriber(subscribeInfo);
        try {
            //订阅事件
            CommonEventManager.subscribeCommonEvent(subscriber);

            showTips(context, "Subscribe succeeded");
            unSubscribe = false;
        } catch (RemoteException e) {
            HiLog.error(LABEL_LOG, "%{public}s", "subscribeEvent remoteException.");
        }
    }
}

Plugin还提供了4种不同类型的公共事件发布方法,无序的、权限、有序的、粘性的

/**
 * 发布无序的公共事件
 * Publish disordered commonEvent
 */
public void publishDisorderedEvent(String eventInfo) {
    HiLog.debug(LABEL_LOG, "publishDisorderedEvent:"+eventInfo);
    Intent intent = new Intent();
    //
    intent.setParam("eventInfo", eventInfo);
    Operation operation = new Intent.OperationBuilder().withAction(event).build();
    intent.setOperation(operation);
    //code - 表示公共事件的自定义结果代码。 代码的值一般为-1。 您可以将其设置为任何 int 值。 该参数仅适用于有序的普通事件,可选。
    //data - 表示公共事件的自定义结果数据。 数据的值一般为空。 您可以将其设置为任何字符串。 该参数仅适用于有序的普通事件,可选。
    CommonEventData eventData = new CommonEventData(intent,1,eventInfo);

    try {
        CommonEventManager.publishCommonEvent(eventData);
        showTips(context, "Publish succeeded");
    } catch (RemoteException e) {
        HiLog.error(LABEL_LOG, "%{public}s", "publishDisorderedEvent remoteException.");
    }
}

/**
 * 发布权限 commonEvent
 * Publish permission commonEvent
 */
public void publishPermissionEvent(String eventInfo) {
    HiLog.debug(LABEL_LOG, "publishPermissionEvent:"+eventInfo);
    Intent intent = new Intent();
    Operation operation = new Intent.OperationBuilder().withAction(event).build();
    intent.setOperation(operation);
    CommonEventData eventData = new CommonEventData(intent,1,eventInfo);

    CommonEventPublishInfo publishInfo = new CommonEventPublishInfo();
    String[] permissions = {"ohos.sample.permission"};
    //设置订阅者的权限
    publishInfo.setSubscriberPermissions(permissions);
    try {
        CommonEventManager.publishCommonEvent(eventData, publishInfo);
        showTips(context, "Publish succeeded");
    } catch (RemoteException e) {
        HiLog.error(LABEL_LOG, "%{public}s", "publishPermissionEvent remoteException.");
    }
}

/**
 * 发布有序的 commonEvent
 * Publish ordered commonEvent
 */
public void publishOrderlyEvent(String eventInfo) {
    HiLog.debug(LABEL_LOG, "publishOrderlyEvent:"+eventInfo);
    Intent intent = new Intent();
    Operation operation = new Intent.OperationBuilder().withAction(event).build();
    intent.setOperation(operation);
    CommonEventData eventData = new CommonEventData(intent,1,eventInfo);
    //将事件添加到此 MatchingSkills 对象。
    MatchingSkills skills = new MatchingSkills();
    skills.addEvent(event);
    //提供发布公共事件的信息,包括设置订阅者过滤条件、公共事件类型和模式。
    CommonEventPublishInfo publishInfo = new CommonEventPublishInfo();
    publishInfo.setOrdered(true);
    try {
        CommonEventManager.publishCommonEvent(eventData, publishInfo);
        showTips(context, "Publish succeeded");
    } catch (RemoteException e) {
        HiLog.error(LABEL_LOG, "%{public}s", "publishOrderlyEvent remoteException.");
    }
}

/**
 * 发布粘性 commonEvent
 * Publish sticky commonEvent
 */
public void publishStickyEvent(String eventInfo) {
    HiLog.debug(LABEL_LOG, "publishStickyEvent:"+eventInfo);
    Intent intent = new Intent();
    Operation operation = new Intent.OperationBuilder().withAction(event).build();
    intent.setOperation(operation);
    CommonEventData eventData = new CommonEventData(intent,1,eventInfo);

    //指定公共事件是否具有粘性。
    CommonEventPublishInfo publishInfo = new CommonEventPublishInfo();
    publishInfo.setSticky(true);
    try {
        CommonEventManager.publishCommonEvent(eventData, publishInfo);
        showTips(context, "Publish succeeded");
    } catch (RemoteException e) {
        HiLog.error(LABEL_LOG, "%{public}s", "publishStickyEvent remoteException.");
    }
}

发布携带权限的公共事件,发布者需要在config.json的reqPermissions中事先声明所需的权限。
发布粘性的公共事件,发布者也需要在config.json的reqPermissions中申请发布粘性公共事件所需的权限

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

订阅者需要的权限
发布粘性的公共事件,发布者也需要在config.json的reqPermissions中申请发布粘性公共事件所需的权限**

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

问题总结

1.公共事件功能需要用到哪些对象
CommonEventSubscriber //提供在订阅者收到新的公共事件时回调的方法。CommonEventSubscriber 是一个抽象类。
CommonEventData //承载公共事件,例如发布公共事件内容,存储订阅后收到的公共事件。
CommonEventSubscribeInfo //公共事件订阅信息,设置发布者的过滤条件,例如设备 ID 和权限,用于订阅所需的公共事件。
CommonEventManager //管理公共事件,例如发布、订阅和取消订阅公共事件。
CommonEventPublishInfo //提供发布公共事件的信息,包括设置订阅者过滤条件、公共事件类型和模式。
MatchingSkills //封装订阅者想要订阅的特定常见事件,支持过滤器。
Operation //封装了与 Intent 相关的参数和操作。
Intent //Intent 是对象之间传递信息的载体。

2.CommonEventData 的code和data参数只适用于有序的普通事件
//code - 表示公共事件的自定义结果代码。 代码的值一般为-1。
您可以将其设置为任何 int 值。 该参数仅适用于有序的普通事件,可选。
//data - 表示公共事件的自定义结果数据。 数据的值一般为空。
您可以将其设置为任何字符串。 该参数仅适用于有序的普通事件,可选。

3.这是一个最基础的公共事件的示例一定要理解清楚,以后一些其它的示例都会用到。

效果展示

HarmonyOS Sample 之 CommonEvent 公共事件-鸿蒙开发者社区
操作对应的日志输出
HarmonyOS Sample 之 CommonEvent 公共事件-鸿蒙开发者社区

完整代码

附件直接下载

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
CommonEvent.zip 1.37M 67次下载
已于2021-8-10 11:01:04修改
2
收藏 2
回复
举报
2条回复
按时间正序
/
按时间倒序
小昕大魔王
小昕大魔王

请问如何监听其他应用发出的公共事件?如SystemUI发出的公共事件,还是设置了权限的公共事件,这种怎么监听?

比如com.huawei.navigationbar.statuschange这种,在隐藏时是SystemUI发送的,但需要huawei.android.permission.HW_SIGNATURE_OR_SYSTEM这种权限才行。

回复
2021-10-22 10:00:10
Buty9147
Buty9147

不清楚你这个事件,

CommonEventSupport提供一系列常见事件的静态系统级常量。

我试验过订阅 蓝牙、息屏 这些系统事件是可以,例如蓝牙状态改变的事件,权限在config.json配置上,然后订阅即可。

 

To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission.

订阅事件

 

回复
2021-10-25 15:32:36
回复
    相关推荐