公共事件的订阅和发布
介绍
本示例主要展示了公共事件相关的功能,实现了一个检测用户部分行为的应用。具体而言实现了如下几点功能:
1.通过订阅系统公共事件,实现对用户操作行为(亮灭屏、锁屏和解锁屏幕、断联网)的监测;
2.通过在用户主动停止监测行为时发布自定义有序公共事件,实现对用户主动触发监听行为的持久化记录;
3.通过在用户设置对某一事件的监听状态时发布粘性事件,记录下本次应用运行期间允许监听的事件列表,同时在应用退出时将临时允许的修改为不允许。
效果预览
使用说明:
1.安装编译生成的hap包,桌面上显示应用图标如下,点击图标即可进入应用。
2.进入应用显示菜单页,可选择“进入”,“历史”,“设置”及“关于”几个选项。
3.点击“进入”后跳转至主页面,点击主页面“开始监控”按钮,将开始监听系统公共事件,并进行计时,此时按钮内容变更为“停止监听”;点击停止监听按钮,页面上将显示本次监听时长及监听期间收到的干扰信息汇总,并在页面右下角显示“查看详情”按钮,点击按钮将跳转至详情页,显示监听期间收到的干扰信息,应用当前仅监听了亮灭屏、锁屏和解锁屏幕、断联网等用户可操作的系统公共事件,后续可根据需求快速扩展。
4.返回至应用菜单页面,点击“历史”可查看用户操作监听的历史记录,当前支持每次运行期间最多存储10条历史记录,超过10条后将删除历史数据。
5.返回至应用菜单页面,点击“设置”可进行具体系统事件的监听配置,应用提供了“一直”、“仅本次”及“从不”三个选项,其中“仅本次”选项是指本次应用运行期间将监听特定系统公共事件,应用退出后该选项将自动调整为“从不”。
6.返回至应用菜单页面,点击“关于”可查看应用版本信息及本示例的说明。
具体实现
-
该示例分为四个模块:
-
进入模块
- 使用到应用文上下文,createSubscriber方法创建订阅者,getCurrentTime获取获取自Unix纪元以来经过的时间进行对用户操作行为的监测功能页面开发。
- 源码参考:[Consts.ets]
-
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { commonEventManager } from '@kit.BasicServicesKit';
export default class consts {
// definition for database
static readonly DATA_BASE_NAME: string = "nothing_pre";
static readonly DATA_BASE_KEY_TOTAL_TIMES: string = "totalTimes";
static readonly DATA_BASE_KEY_START_TIME: string = "startTime";
static readonly DATA_BASE_KEY_WIFI_POWER_STATE: string = commonEventManager.Support.COMMON_EVENT_WIFI_POWER_STATE;
static readonly DATA_BASE_KEY_SCREEN_OFF: string = commonEventManager.Support.COMMON_EVENT_SCREEN_OFF;
static readonly DATA_BASE_KEY_SCREEN_ON: string = commonEventManager.Support.COMMON_EVENT_SCREEN_ON;
static readonly DATA_BASE_KEY_SCREEN_LOCKED: string = commonEventManager.Support.COMMON_EVENT_SCREEN_LOCKED;
static readonly DATA_BASE_KEY_SCREEN_UNLOCKED: string = commonEventManager.Support.COMMON_EVENT_SCREEN_UNLOCKED;
static readonly DATA_BASE_KEY_ONCE_EVENTS: string = "onceCall";
static readonly DATA_BASE_KEY_NEVER_EVENTS: string = "neverCall";
// definition for event enable state
static readonly ENABLE_STATE_ALWAYS: number = 0;
static readonly ENABLE_STATE_ONCE: number = 1;
static readonly ENABLE_STATE_NEVER: number = 2;
// definition for record volume
static readonly MAX_RECORD_NUM: number = 10;
// definition for self defined common events
static readonly COMMON_EVENT_FINISH_MEDITATION: string = "finish_meditation";
static readonly COMMON_EVENT_SETTING_UPDATE: string = "setting_update";
}
- 源码参考:[LaunchFeature.ets]
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { common } from '@kit.AbilityKit';
import { commonEventManager, BusinessError } from '@kit.BasicServicesKit';
import consts from '../module/Consts';
import { preferences } from '@kit.ArkData';
import Logger from '../module/Logger';
import { router } from '@kit.ArkUI';
import { Want } from '@kit.AbilityKit';
import { GlobalContext } from '../module/GlobalContext';
export default class LaunchFeature {
private innerContext: common.UIAbilityContext | null = null;
private pref: preferences.Preferences | null = null;
private subscriber: commonEventManager.CommonEventSubscriber | null = null;
private subscriberLow: commonEventManager.CommonEventSubscriber | null = null;
private currentRecordTimes: number = 0;
constructor(abilityContext: common.UIAbilityContext) {
this.innerContext = abilityContext;
}
async init(): Promise<void> {
await preferences.getPreferences(this.innerContext as common.UIAbilityContext, consts.DATA_BASE_NAME)
.then((pref) => {
this.pref = pref;
});
await this.pref?.get(consts.DATA_BASE_KEY_WIFI_POWER_STATE, 0).then((value: preferences.ValueType) => {
(GlobalContext.getContext()
.getObject('settings') as Map<string, number>).set(commonEventManager.Support.COMMON_EVENT_WIFI_POWER_STATE, value as number);
});
await this.pref?.get(consts.DATA_BASE_KEY_SCREEN_OFF, 0).then((value1: preferences.ValueType) => {
(GlobalContext.getContext()
.getObject('settings') as Map<string, number>).set(commonEventManager.Support.COMMON_EVENT_SCREEN_OFF, value1 as number);
});
await this.pref?.get(consts.DATA_BASE_KEY_SCREEN_ON, 0).then((value2: preferences.ValueType) => {
(GlobalContext.getContext()
.getObject('settings') as Map<string, number>).set(commonEventManager.Support.COMMON_EVENT_SCREEN_ON, value2 as number);
});
await this.pref?.get(consts.DATA_BASE_KEY_SCREEN_LOCKED, 0).then((value3: preferences.ValueType) => {
(GlobalContext.getContext()
.getObject('settings') as Map<string, number>).set(commonEventManager.Support.COMMON_EVENT_SCREEN_LOCKED, value3 as number);
});
await this.pref?.get(consts.DATA_BASE_KEY_SCREEN_UNLOCKED, 0).then((value4: preferences.ValueType) => {
(GlobalContext.getContext()
.getObject('settings') as Map<string, number>).set(commonEventManager.Support.COMMON_EVENT_SCREEN_UNLOCKED, value4 as number);
});
}
private insertRecord = (event: commonEventManager.CommonEventData, value: preferences.ValueType) => {
if (event.parameters) {
(value as Array<string>).push(event.parameters[consts.DATA_BASE_KEY_START_TIME]);
}
// refresh database
this.pref?.put(consts.DATA_BASE_KEY_TOTAL_TIMES, value).then(() => {
let detail: