HarmonyOS Sample 之 CommonEvent 公共事件 原创 精华
@toc
CommonEvent 公共事件
介绍
每个应用都可以订阅自己感兴趣的公共事件,订阅成功后且公共事件发布后,系统会把其发送给应用。
这些公共事件可能来自系统、其他应用和应用自身,用来支持用户订阅、发送和接收公共事件。
发送公共事件需要借助 CommonEventData 对象,接收公共事件需要继承 CommonEventSubscriber 类并实现 onReceiveEvent 回调函数。
本示例演示了公共事件的订阅、发布和退订。
搭建环境
安装DevEco Studio,详情请参考DevEco Studio下载。
设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:
如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。
如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境。
代码结构和逻辑关系
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.这是一个最基础的公共事件的示例一定要理解清楚,以后一些其它的示例都会用到。
效果展示
操作对应的日志输出
完整代码
附件直接下载
请问如何监听其他应用发出的公共事件?如SystemUI发出的公共事件,还是设置了权限的公共事件,这种怎么监听?
比如com.huawei.navigationbar.statuschange这种,在隐藏时是SystemUI发送的,但需要huawei.android.permission.HW_SIGNATURE_OR_SYSTEM这种权限才行。
不清楚你这个事件,
CommonEventSupport提供一系列常见事件的静态系统级常量。
我试验过订阅 蓝牙、息屏 这些系统事件是可以,例如蓝牙状态改变的事件,权限在config.json配置上,然后订阅即可。
To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission.
订阅事件