0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于ArkTS语言的OpenHarmony APP应用开发:公共事件的订阅和发布

福州市凌睿智捷电子有限公司 2024-09-19 08:05 次阅读

1、程序介绍

本示例主要展示了公共事件相关的功能,实现了一个检测用户部分行为的应用。

具体而言,本案例实现了如下几个公共事件功能:

通过订阅系统公共事件,实现对用户操作行为(亮灭屏、断联网)的监测;

通过在用户主动停止监测行为时发布自定义有序公共事件,实现对用户主动触发监听行为的持久化记录;

通过在用户设置对某一事件的监听状态时发布粘性事件,记录下本次应用运行期间允许监听的事件列表,同时在应用退出时将临时允许的修改为不允许。

具体而言,本案例实现如下几个界面:

进入应用显示菜单页,可选择“进入”,“历史”,“设置”及“关于”几个选项。

点击“进入”后跳转至主页面,点击主页面“开始监控”按钮,将开始监听系统公共事件,并进行计时,此时按钮内容变更为“停止监听”;点击停止监听按钮,页面上将显示本次监听时长及监听期间收到的干扰信息汇总,并在页面右下角显示“查看详情”按钮,点击按钮将跳转至详情页,显示监听期间收到的干扰信息,应用当前仅监听了亮灭屏、断联网等用户可操作的系统公共事件,后续可根据需求快速扩展。

返回至应用菜单页面,点击“历史”可查看用户操作监听的历史记录,当前支持每次运行期间最多存储20条历史记录,超过20条后将删除历史数据。

返回至应用菜单页面,点击“设置”可进行具体系统事件的监听配置,应用提供了“一直”、“仅本次”及“从不”三个选项,其中“仅本次”选项是指本次应用运行期间将监听特定系统公共事件,应用退出后该选项将自动调整为“从不”。

返回值应用菜单页面,点击“关于”可查看应用版本信息及本示例的说明。

本案例已在OpenHarmony凌蒙派-RK3568开发板验证通过

API接口:9

2、知识准备

2.1、commonEvent模块

OpenHarmony通过CES(Common Event Service,公共事件服务)为应用程序提供订阅、发布、退订公共事件的能力。

公共事件从系统角度可分为:系统公共事件和自定义公共事件。

系统公共事件:CES内部定义的公共事件,只有系统应用和系统服务才能发布,例如HAP安装,更新,卸载等公共事件。目前支持的系统公共事件详见系统公共事件列表。

自定义公共事件:应用自定义一些公共事件用来实现跨进程的事件通信能力。

公共事件按发送方式可分为:无序公共事件、有序公共事件和粘性公共事件。

无序公共事件:CES转发公共事件时,不考虑订阅者是否接收到,按订阅者订阅先后顺序转发。

有序公共事件:CES转发公共事件时,按订阅者订阅先后顺序,在接收到前一个订阅者回复后,再转发下一个订阅者。

粘性公共事件:能够让订阅者收到在订阅前已经发送的公共事件就是粘性公共事件。普通的公共事件只能在订阅后发送才能收到,而粘性公共事件的特殊性就是可以先发送后订阅。发送粘性事件必须是系统应用或系统服务,且需要申请ohos.permission.COMMONEVENT_STICKY权限。

每个应用都可以按需订阅公共事件,订阅成功,当公共事件发布时,系统会将其发送给对应的应用。这些公共事件可能来自系统、其他应用和应用自身。

2.1.1、引入commonEvent模块

import commonEvent from '@ohos.commonEvent';

2.1.2、commonEvent函数

declare namespace commonEvent {
function publish(event: string, callback: AsyncCallback<void>): void;
function publish(event: string, options: CommonEventPublishData, callback: AsyncCallback<void>): void;
function publishAsUser(event: string, userId: number, callback: AsyncCallback<void>): void;
function publishAsUser(event: string, userId: number, options: CommonEventPublishData, callback: AsyncCallback<void>): void;
function createSubscriber(subscribeInfo: CommonEventSubscribeInfo, callback: AsyncCallback<CommonEventSubscriber>): void;
function createSubscriber(subscribeInfo: CommonEventSubscribeInfo): Promise<CommonEventSubscriber>;
function subscribe(subscriber: CommonEventSubscriber, callback: AsyncCallback<CommonEventData>): void;
function unsubscribe(subscriber: CommonEventSubscriber, callback?: AsyncCallback<void>): void;
}

其中,参数定义如下:

publish:发送公共事件,event 表示事件名称。

publishAsUser:发送指定用户的公共事件。

createSubscriber:创建事件的订阅者。

subscribe:订阅事件,可以是公共事件,也可以是自定义事件。

unsubscribe:取消订阅事件,一旦取消,后续对的事件将不再接收。

2.1.3、创建订阅者

function createSubscriber(subscribeInfo: CommonEventSubscribeInfo, callback: AsyncCallback<CommonEventSubscriber>): void;
function createSubscriber(subscribeInfo: CommonEventSubscribeInfo): Promise<CommonEventSubscriber>;

以异步方法构造CommonEventSubscriber对象,创建公共事件订阅者对象,使用callback形式返回。

其中,参数定义如下:

参数名类型必填说明
subscribeInfoCommonEventSubscribeInfo公共事件订阅者信息
callbackAsyncCallback事件监听回调函数,当收到订阅的事件时,回调订阅的事件数据

2.1.4、开启订阅事件

function subscribe(subscriber: CommonEventSubscriber, callback: AsyncCallback<CommonEventData>): void;

以异步方法订阅公共事件,使用callback形式返回。在调用subscriber接口订阅公共事件前,需要先通过createSubscriber接口创建一个CommonEventSubscriber对象。

其中,参数定义如下:

参数名类型必填说明
subscribeInfoCommonEventSubscribeInfo公共事件订阅者信息
callbackAsyncCallback事件监听回调函数,当收到订阅的事件时,回调订阅的事件数据

2.1.5、取消订阅事件

function unsubscribe(subscriber: CommonEventSubscriber, callback?: AsyncCallback<void>): void;

以异步方法取消订阅公共事件,使用callback形式返回。与subscribe接口相同,需要传入一个已创建的CommonEventSubscriber对象。

其中,参数定义如下:

参数名类型必填说明
subscribeInfoCommonEventSubscribeInfo公共事件订阅者信息
callbackAsyncCallback事件监听回调函数,当收到订阅的事件时,回调订阅的事件数据

2.1.6、发布事件

function publish(event: string, callback: AsyncCallback<void>): void;
function publish(event: string, options: CommonEventPublishData, callback: AsyncCallback<void>): void;
function publishAsUser(event: string, userId: number, callback: AsyncCallback<void>): void;
function publishAsUser(event: string, userId: number, options: CommonEventPublishData, callback: AsyncCallback<void>): void;

以callback形式发布公共事件。

其中,参数定义如下:

参数名类型必填说明
subscribeInfoCommonEventSubscribeInfo公共事件订阅者信息
callbackAsyncCallback事件监听回调函数,当收到订阅的事件时,回调订阅的事件数据

3、程序解析

按照页面划分,本案例大致可分为如下几个页面:

(1)Launch.ets:应用显示菜单页面。进入应用显示菜单页,可选择“进入”,“历史”,“设置”及“关于”几个选项。

(2)Main.ets:主页面。显示“进入监控”按键,“开始监控”按钮,将开始监听系统公共事件,并进行计时,此时按钮内容变更为“停止监听”;点击停止监听按钮,页面上将显示本次监听时长及监听期间收到的干扰信息汇总,并在页面右下角显示“查看详情”按钮,点击按钮将跳转至详情页,显示监听期间收到的干扰信息,应用当前仅监听了亮灭屏、断联网等用户可操作的系统公共事件,后续可根据需求快速扩展。

(3)History.ets:历史页面。可查看用户操作监听的历史记录,当前支持每次运行期间最多存储20条历史记录,超过20条后将删除历史数据。

(4)Setting.ets:设置页面。可进行具体系统事件的监听配置,应用提供了“一直”、“仅本次”及“从不”三个选项,其中“仅本次”选项是指本次应用运行期间将监听特定系统公共事件,应用退出后该选项将自动调整为“从不”。

(5)Detail.ets:查看详情页面。可负责查看当前监控的具体信息。供Main.ets调用。

(6)About.ets:关于页面。显示软件信息。

3.1、Launch.ets

首先,定义一个私有变量feature,用于负责具体的公共事件订阅以及页面间跳转。

private feature :launchFeature = new launchFeature(getContext() as context.UIAbilityContext)

注意:feature具体事务可参考entry/src/main/ets/feature/LaunchFeature.ts。

其次,编辑页面显示界面。

build() {
Column() {
Image($rawfile('jumpToStart.png'))
.objectFit(ImageFit.Contain)
.width(160)
.height(75)
.onClick(this.feature.jumpToStart)
.position({ x: '30%', y: '20%' })
Image($rawfile('jumpToHistory.png'))
.objectFit(ImageFit.Contain)
.width(160)
.height(75)
.onClick(this.feature.jumpToHistory)
.position({ x: '30%', y: '35%' })
Image($rawfile('jumpTosetting.png'))
.objectFit(ImageFit.Contain)
.width(160)
.height(75)
.onClick(this.feature.jumpToSetting)
.position({ x: '30%', y: '50%' })
Image($rawfile('jumpAbout.png'))
.objectFit(ImageFit.Contain)
.width(160)
.height(75)
.onClick(this.feature.jumpToAbout)
.position({ x: '30%', y: '65%' })
}
.backgroundImage($rawfile('vbg720.png'))
.backgroundImageSize(ImageSize.Contain)
.width('100%')
.height('100%')
}

再次,创建LauchFeatrue.ts,主要负责页面跳转和记录公共事件记录。

其中,负责页面跳转的代码如下所示:

jumpToHistory = () => {
Logger.info("ready to jump to history page")
router.push({
url: 'pages/History',
params: {}
})
}

jumpToSetting = () => {
Logger.info("ready to jump to setting page")
router.push({
url: 'pages/Setting',
params: {}
})
}
......

其中,记录公共事件记录的代码如下所示:

private callbackFunc = (error, event) => {
this.pref.has(consts.DATA_BASE_KEY_TOTAL_TIMES, (err, ret) => {
if (ret) {
this.pref.get(consts.DATA_BASE_KEY_TOTAL_TIMES, []).then((value) => {
this.insertRecord(event, value)
})
} else {
let value: Array<string> = []
this.insertRecord(event, value)
}
})
if (this.currentRecordTimes >= consts.MAX_RECORD_NUM) {
this.subscriber.finishCommonEvent()
return
}
this.subscriber.abortCommonEvent()
this.subscriber.finishCommonEvent()
this.currentRecordTimes++
}

private callbackLowFunc = (error, event) => {
this.currentRecordTimes = 0
this.pref.get(consts.DATA_BASE_KEY_TOTAL_TIMES, []).then((value: Array<string>) => {
for (let i = 0; i < consts.MAX_RECORD_NUM; i++) {
this.pref.delete(value[i]).then(() => {
this.pref.flush()
})
}
})
this.currentRecordTimes = 0;
}

最后,定义onPageShow(),在用户浏览页面时触发该事件。

async onPageShow() {
await this.feature.init()
}

3.2、Main.ets

首先,定义一个实际负责main页面逻辑操作的类对象。

private feature:mainFeature = new mainFeature()

其次,在build()中定义按键画面。

Image(this.btnSrc)
.objectFit(ImageFit.Contain).size({ width: 320, height: 150 })
.onClick(this.executeCallBack)

再次,this.executeCallBack()根据btnState数值变化开启或关闭公共事件监听。

private executeCallBack = () => {
if (!this.btnState) {
this.handleStart()
} else {
this.handleStop()
}
}

再次,定义handleStart()开启公共事件监听。

private handleStart = () => {
this.btnState = true
this.btnSrc = $rawfile('stop.png')
this.detailState = Visibility.None
this.currentState = Visibility.Visible
this.totalEventsInString = ''
this.totalEvents = 0
this.totalTimeInString = ''
// 获取系统时间
sysTime.getCurrentTime().then((curTime) => {
this.startTime = curTime
let subscriberInfo = {
events: this.feature.getCurrentValidEvents()
}
// 创建订阅者
commonEvent.createSubscriber(subscriberInfo, (error, subscriber) => {
this.validEventsSubscriber = subscriber
// 开启订阅事件
commonEvent.subscribe(subscriber, this.systemEventCallback)
})
})
}

最后,定义handleStop()关闭公共事件监听。

private handleStop = () => {
this.btnState = false
this.btnSrc = $rawfile('start.png')
this.detailState = Visibility.Visible
this.currentState = Visibility.None
this.totalEventsInString = this.totalEvents.toString()
// 刷新时间
sysTime.getCurrentTime().then((curTime) => {
this.totalTimeInString = utils.convertTimeToFormatString(curTime - this.startTime)
// 取消订阅事件
commonEvent.unsubscribe(this.validEventsSubscriber, () => {
Logger.info("unsubscribe called")
})
let options = {
isOrdered: true,
parameters: {
'startTime': utils.getLocaleTime(this.startTime),
'endTime': utils.getLocaleTime(curTime),
'totalTime': this.totalTimeInString,
'totalEvents': this.totalEventsInString,
}
}
// 发布公共事件
commonEvent.publish(consts.COMMON_EVENT_FINISH_MEDITATION, options, () => {
Logger.info("success to publish COMMON_EVENT_FINISH_MEDITATION")
})
})
}

4、项目编译

4.1、打开项目

打开DevEco Studio,再打开自定义通知项目。

4.2、编译程序

点击菜单栏上的“Build” -> "Rebuild Project"。如果出现无法编译,则注意查看Event Log界面。如下所示:

d591e662-761a-11ef-bb4b-92fbcf53809c.png

点击Run 'npm install',让DevEco Studio安装相关依赖包。

重新点击菜单栏上的“Build” -> "Rebuild Project"。出现如下错误:

d5ad6414-761a-11ef-bb4b-92fbcf53809c.png

点击上图红色框部分,安装相关服务。

重新点击菜单栏上的“Build” -> "Rebuild Project",编译成功。

d5c75f90-761a-11ef-bb4b-92fbcf53809c.png

4.3、安装程序

点击“entry”按钮,将项目程序安装到设备端。如下图所示:

d5ea4b22-761a-11ef-bb4b-92fbcf53809c.png

如果出现下述报错,表示无法安装。如图所示:

d5fe24b2-761a-11ef-bb4b-92fbcf53809c.png

点击上图红色框的蓝色字体,弹出"Project Structure"对话框,点击"Apply",再点击"OK"。如图所示:

d6212e12-761a-11ef-bb4b-92fbcf53809c.png

重新点击“entry”按钮,将项目程序安装到设备端。

d63d6762-761a-11ef-bb4b-92fbcf53809c.png

5、运行结果

运行结果如下所示

d650d4b4-761a-11ef-bb4b-92fbcf53809c.png

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • APP
    APP
    +关注

    关注

    33

    文章

    1557

    浏览量

    72152
  • 应用开发
    +关注

    关注

    0

    文章

    57

    浏览量

    9226
  • OpenHarmony
    +关注

    关注

    25

    文章

    3546

    浏览量

    15734
收藏 人收藏

    评论

    相关推荐

    HarmonyOS开发实例:【事件的订阅发布

    公共事件相关的功能,实现了一个检测用户部分行为的应用。
    的头像 发表于 04-15 17:36 895次阅读
    HarmonyOS<b class='flag-5'>开发</b>实例:【事件的<b class='flag-5'>订阅</b>和<b class='flag-5'>发布</b>】

    基于ArkTS语言OpenHarmony APP应用开发:HelloOpenharmony

    1、程序简介 该程序是基于OpenHarmony标准系统编写的UI应用类:HelloOpenHarmony。 本案例是基于API 9接口开发。 本案例已在OpenHarmony凌蒙派-
    发表于 09-14 12:47

    基于ArkTS语言OpenHarmony APP应用开发:自定义通知

    OpenHarmony凌蒙派-RK3568开发板验证通过,具体代码可参考:https://gitee.com/Lockzhiner-Electronics/lockzhiner-rk3568-openharmony
    发表于 09-14 15:12

    基于ArkTS语言OpenHarmony APP应用开发公共事件的订阅发布

    监听特定系统公共事件,应用退出后该选项将自动调整为“从不”。 返回值应用菜单页面,点击“关于”可查看应用版本信息及本示例的说明。 本案例已在OpenHarmony凌蒙派-RK3568开发板验证通过
    发表于 09-18 13:16

    HarmonyOS应用开发-公共事件处理

    开发过程中service想要控制多个ability时,可以考虑使用公共事件处理。发布无序的公共事件: //发布
    发表于 11-02 15:15

    HUAWEI DevEco Studio 3.1版本发布,配套ArkTS声明式开发全面升级

    构建产物。 3)新增支持ArkTS/JS与C/C++跨语言调试特性,在C/C++工程中,采用ArkTS/JS与C/C++进行混合开发,能够在ArkT
    发表于 11-17 11:52

    HarmonyOS/OpenHarmony应用开发-Stage模型ArkTS语言AbilityConstant

    状态。APP_RECOVERY1应用恢复保存状态。接口示例:*附件:HarmonyOSOpenHarmony应用开发-stage模型ArkTS语言
    发表于 04-03 09:15

    HarmonyOS/OpenHarmony应用开发-Stage模型ArkTS语言AbilityStage

    进行初始化时回调。context接口示例:*附件:HarmonyOSOpenHarmony应用开发-stage模型ArkTS语言AbilityStage.docx
    发表于 04-07 15:16

    HarmonyOS/OpenHarmony应用开发-Stage模型ArkTS语言扩展能力基类

    \'@ohos.app.ability.ExtensionAbility\'; 接口示例: *附件:HarmonyOSOpenHarmony应用开发-stage模型ArkTS
    发表于 04-26 10:00

    HarmonyOS/OpenHarmony应用开发-ArkTS语言基本语法说明

    的封装和复用UI描述。 @Extend/@Style:扩展内置组件和封装属性样式,更灵活地组合内置组件。 stateStyles:多态样式,可以依据组件的内部状态的不同,设置不同样式。*附件:HarmonyOSOpenHarmony应用开发-
    发表于 06-01 10:25

    HarmonyOS/OpenHarmony应用开发-ArkTS语言声明式UI描述

    (100) . Button(\'click +1\') ..onClick(() => { .console.info(\'+1 clicked!\'); .}) .} .} *附件:HarmonyOSOpenHarmony应用开发-
    发表于 06-05 15:26

    HarmonyOS优选主力应用开发语言-ArkTS概述

    ArkTS是HarmonyOS优选的主力应用开发语言ArkTS围绕应用开发在TypeScript(简称TS)生态基础上做了进一步扩展,继承
    发表于 06-09 10:52

    OpenHarmony ArkTS工程目录结构(Stage模型)

    一、应用工程结构 图片来源:OpenHarmony官网 AppScope > app.json5:应用的全局配置信息。 entry:OpenHarmony工程模块,编译构建生成一个
    发表于 09-18 15:23

    OpenHarmony 应用开发SDK、API 与基础工具

    一、整体说明 ArkTS 语言是鸿蒙系统主推的应用开发语言。因此鸿蒙系统提供给开发者的 API 绝大部分也是
    发表于 09-19 15:45

    基于ArkTS语言OpenHarmony APP应用开发:HelloOpenharmony

    1、程序简介该程序是基于OpenHarmony标准系统编写的UI应用类:HelloOpenHarmony。本案例是基于API9接口开发。本案例已在OpenHarmony凌蒙派-RK35
    的头像 发表于 09-15 08:09 64次阅读
    基于<b class='flag-5'>ArkTS</b><b class='flag-5'>语言</b>的<b class='flag-5'>OpenHarmony</b> <b class='flag-5'>APP</b>应用<b class='flag-5'>开发</b>:Hello<b class='flag-5'>Openharmony</b>