常见HarmonyOS开发中CommonEvent订阅:系统事件监听
【摘要】 常见HarmonyOS开发中CommonEvent订阅:系统事件监听监听系统脉搏,让应用随系统状态而动 一、背景与动机:为什么需要监听系统事件? 1.1 响应式应用设计现代应用不能"闭门造车",需要感知系统状态:电量低时:暂停后台下载,节省电量网络断开时:提示用户,暂停网络请求屏幕关闭时:停止动画,降低刷新频率来电时:暂停音乐播放这些都是系统事件,通过CommonEvent订阅,应用可以实...
常见HarmonyOS开发中CommonEvent订阅:系统事件监听
监听系统脉搏,让应用随系统状态而动
一、背景与动机:为什么需要监听系统事件?
1.1 响应式应用设计
现代应用不能"闭门造车",需要感知系统状态:
- 电量低时:暂停后台下载,节省电量
- 网络断开时:提示用户,暂停网络请求
- 屏幕关闭时:停止动画,降低刷新频率
- 来电时:暂停音乐播放
这些都是系统事件,通过CommonEvent订阅,应用可以实时感知系统状态变化。
1.2 鸿蒙系统事件分类
1.3 系统事件 vs 自定义事件
| 对比项 | 系统事件 | 自定义事件 |
|---|---|---|
| 发布者 | 系统 | 应用自己 |
| 事件名 | 预定义常量 | 自定义字符串 |
| 权限 | 部分需要权限 | 无需权限 |
| 数据格式 | 系统定义 | 自定义 |
| 典型用途 | 响应系统状态 | 应用间通信 |
二、核心原理:系统事件订阅机制
2.1 系统事件发布流程

2.2 事件数据结构
系统事件的数据结构是统一的:
interface CommonEventData {
// 事件名称
event: string
// 事件数据(字符串形式)
data: string
// 事件代码(整数)
code: number
// 附加参数(键值对)
parameters: {
[key: string]: unknown
}
}
不同系统事件的parameters内容不同,需要查阅文档了解具体字段。
2.3 常用系统事件列表
| 事件名 | 说明 | 触发时机 |
|---|---|---|
android.intent.action.BATTERY_CHANGED |
电量变化 | 电量改变时 |
android.intent.action.BATTERY_LOW |
电量低 | 电量低于15%时 |
android.intent.action.BATTERY_OKAY |
电量恢复 | 电量恢复到正常时 |
android.intent.action.POWER_CONNECTED |
连接电源 | 插入充电器时 |
android.intent.action.POWER_DISCONNECTED |
断开电源 | 拔出充电器时 |
android.net.conn.CONNECTIVITY_CHANGE |
网络变化 | 网络状态改变时 |
android.net.wifi.WIFI_STATE_CHANGED |
WiFi状态变化 | WiFi开关状态改变时 |
android.intent.action.SCREEN_ON |
屏幕亮起 | 屏幕点亮时 |
android.intent.action.SCREEN_OFF |
屏幕关闭 | 屏幕熄灭时 |
android.intent.action.TIME_TICK |
时间流逝 | 每分钟触发一次 |
android.intent.action.BOOT_COMPLETED |
启动完成 | 系统启动完成时 |
三、代码实战:监听各类系统事件
3.1 电量事件监听
// BatteryEventListener.ets
import { commonEventManager, CommonEventSubscribeInfo, CommonEventData } from '@kit.BasicServicesKit'
import hilog from '@ohos.hilog'
const TAG = 'BatteryEvent'
const DOMAIN = 0xFF00
/**
* 电量事件监听器
*/
export class BatteryEventListener {
private subscriber: commonEventManager.CommonEventSubscriber = null
// 电量状态
private batteryLevel: number = 100
private isCharging: boolean = false
/**
* 开始监听电量事件
*/
async startListening(): Promise<void> {
// 订阅多个电量相关事件
const subscribeInfo: CommonEventSubscribeInfo = {
events: [
'android.intent.action.BATTERY_CHANGED', // 电量变化
'android.intent.action.BATTERY_LOW', // 电量低
'android.intent.action.BATTERY_OKAY', // 电量恢复
'android.intent.action.POWER_CONNECTED', // 连接电源
'android.intent.action.POWER_DISCONNECTED' // 断开电源
]
}
try {
this.subscriber = await commonEventManager.createSubscriber(subscribeInfo)
this.subscriber.subscribe((err, data: CommonEventData) => {
if (err) {
hilog.error(DOMAIN, TAG, `Subscribe error: ${err.message}`)
return
}
this.handleBatteryEvent(data)
})
hilog.info(DOMAIN, TAG, 'Battery event listener started')
} catch (err) {
hilog.error(DOMAIN, TAG, `Start listening failed: ${err.message}`)
}
}
/**
* 处理电量事件
*/
private handleBatteryEvent(data: CommonEventData): void {
hilog.info(DOMAIN, TAG, `Event: ${data.event}`)
switch (data.event) {
case 'android.intent.action.BATTERY_CHANGED':
this.onBatteryChanged(data)
break
case 'android.intent.action.BATTERY_LOW':
this.onBatteryLow(data)
break
case 'android.intent.action.BATTERY_OKAY':
this.onBatteryOkay(data)
break
case 'android.intent.action.POWER_CONNECTED':
this.onPowerConnected()
break
case 'android.intent.action.POWER_DISCONNECTED':
this.onPowerDisconnected()
break
}
}
/**
* 电量变化
*/
private onBatteryChanged(data: CommonEventData): void {
// 从parameters中提取电量信息
const params = data.parameters
// 电量百分比
this.batteryLevel = params?.level ?? 0
// 充电状态
// status: 1=未知, 2=充电中, 3=放电中, 4=未充电, 5=充满
const status = params?.status ?? 0
this.isCharging = (status === 2 || status === 5)
hilog.info(DOMAIN, TAG, `Battery: ${this.batteryLevel}%, Charging: ${this.isCharging}`)
// 根据电量调整应用行为
this.adjustAppBehavior()
}
/**
* 电量低警告
*/
private onBatteryLow(data: CommonEventData): void {
hilog.warn(DOMAIN, TAG, 'Battery is low!')
// 暂停非必要操作
this.pauseNonEssentialTasks()
// 通知用户
this.notifyUser('电量低,已暂停后台下载')
}
/**
* 电量恢复正常
*/
private onBatteryOkay(data: CommonEventData): void {
hilog.info(DOMAIN, TAG, 'Battery is okay')
// 恢复操作
this.resumeTasks()
}
/**
* 连接电源
*/
private onPowerConnected(): void {
hilog.info(DOMAIN, TAG, 'Power connected')
this.isCharging = true
// 充电时可以执行更多操作
this.enablePowerIntensiveTasks()
}
/**
* 断开电源
*/
private onPowerDisconnected(): void {
hilog.info(DOMAIN, TAG, 'Power disconnected')
this.isCharging = false
// 使用电池时限制耗电操作
this.limitPowerConsumption()
}
/**
* 根据电量调整应用行为
*/
private adjustAppBehavior(): void {
if (this.batteryLevel < 20 && !this.isCharging) {
// 低电量且未充电,进入省电模式
this.enablePowerSavingMode()
} else if (this.batteryLevel > 50 || this.isCharging) {
// 电量充足或充电中,正常模式
this.disablePowerSavingMode()
}
}
private pauseNonEssentialTasks(): void {
hilog.info(DOMAIN, TAG, 'Pausing non-essential tasks')
// 实现暂停逻辑
}
private resumeTasks(): void {
hilog.info(DOMAIN, TAG, 'Resuming tasks')
}
private enablePowerIntensiveTasks(): void {
hilog.info(DOMAIN, TAG, 'Enabling power intensive tasks')
}
private limitPowerConsumption(): void {
hilog.info(DOMAIN, TAG, 'Limiting power consumption')
}
private enablePowerSavingMode(): void {
hilog.info(DOMAIN, TAG, 'Power saving mode enabled')
}
private disablePowerSavingMode(): void {
hilog.info(DOMAIN, TAG, 'Power saving mode disabled')
}
private notifyUser(message: string): void {
hilog.info(DOMAIN, TAG, `Notify: ${message}`)
// 实现通知逻辑
}
/**
* 停止监听
*/
async stopListening(): Promise<void> {
if (this.subscriber) {
try {
await this.subscriber.unsubscribe()
hilog.info(DOMAIN, TAG, 'Battery event listener stopped')
} catch (err) {
hilog.error(DOMAIN, TAG, `Stop listening failed: ${err.message}`)
}
}
}
/**
* 获取当前电量状态
*/
getBatteryStatus(): { level: number, isCharging: boolean } {
return {
level: this.batteryLevel,
isCharging: this.isCharging
}
}
}
3.2 网络事件监听
// NetworkEventListener.ets
import { commonEventManager, CommonEventSubscribeInfo, CommonEventData } from '@kit.BasicServicesKit'
import connection from '@ohos.net.connection'
import hilog from '@ohos.hilog'
const TAG = 'NetworkEvent'
const DOMAIN = 0xFF00
/**
* 网络类型
*/
export enum NetworkType {
NONE = 'none',
WIFI = 'wifi',
CELLULAR = 'cellular',
ETHERNET = 'ethernet',
UNKNOWN = 'unknown'
}
/**
* 网络状态
*/
export interface NetworkStatus {
isConnected: boolean
type: NetworkType
wifiName?: string
signalStrength?: number
}
/**
* 网络事件监听器
*/
export class NetworkEventListener {
private subscriber: commonEventManager.CommonEventSubscriber = null
private netConnection: connection.NetConnection = null
// 当前网络状态
private currentStatus: NetworkStatus = {
isConnected: false,
type: NetworkType.NONE
}
// 状态变化回调
private onStatusChange: ((status: NetworkStatus) => void) | null = null
/**
* 设置状态变化回调
*/
setOnStatusChange(callback: (status: NetworkStatus) => void): void {
this.onStatusChange = callback
}
/**
* 开始监听网络事件
*/
async startListening(): Promise<void> {
// 订阅网络相关事件
const subscribeInfo: CommonEventSubscribeInfo = {
events: [
'android.net.conn.CONNECTIVITY_CHANGE', // 网络连接变化
'android.net.wifi.WIFI_STATE_CHANGED', // WiFi状态变化
'android.net.wifi.STATE_CHANGE', // WiFi连接状态变化
'android.net.wifi.SCAN_RESULTS' // WiFi扫描结果
]
}
try {
this.subscriber = await commonEventManager.createSubscriber(subscribeInfo)
this.subscriber.subscribe((err, data: CommonEventData) => {
if (err) {
hilog.error(DOMAIN, TAG, `Error: ${err.message}`)
return
}
this.handleNetworkEvent(data)
})
// 同时使用connection API获取详细状态
await this.setupNetConnection()
hilog.info(DOMAIN, TAG, 'Network event listener started')
} catch (err) {
hilog.error(DOMAIN, TAG, `Start failed: ${err.message}`)
}
}
/**
* 使用connection API监听网络
*/
private async setupNetConnection(): Promise<void> {
this.netConnection = connection.createNetConnection()
// 注册网络可用回调
this.netConnection.on('netAvailable', (data: connection.NetHandle) => {
hilog.info(DOMAIN, TAG, `Network available: ${data.netId}`)
this.updateNetworkStatus(data)
})
// 注册网络丢失回调
this.netConnection.on('netLost', (data: connection.NetHandle) => {
hilog.info(DOMAIN, TAG, `Network lost: ${data.netId}`)
this.currentStatus.isConnected = false
this.currentStatus.type = NetworkType.NONE
this.notifyStatusChange()
})
// 注册网络不可用回调
this.netConnection.on('netUnavailable', () => {
hilog.info(DOMAIN, TAG, 'Network unavailable')
this.currentStatus.isConnected = false
this.currentStatus.type = NetworkType.NONE
this.notifyStatusChange()
})
}
/**
* 处理网络事件
*/
private handleNetworkEvent(data: CommonEventData): void {
hilog.info(DOMAIN, TAG, `Event: ${data.event}`)
switch (data.event) {
case 'android.net.conn.CONNECTIVITY_CHANGE':
this.onConnectivityChange(data)
break
case 'android.net.wifi.WIFI_STATE_CHANGED':
this.onWifiStateChanged(data)
break
case 'android.net.wifi.STATE_CHANGE':
this.onWifiConnectionChanged(data)
break
}
}
/**
* 网络连接变化
*/
private onConnectivityChange(data: CommonEventData): void {
const params = data.parameters
// networkInfo包含网络详细信息
const isConnected = params?.networkInfo?.isConnected ?? false
hilog.info(DOMAIN, TAG, `Connectivity changed, connected: ${isConnected}`)
if (!isConnected) {
// 网络断开
this.currentStatus.isConnected = false
this.notifyStatusChange()
}
}
/**
* WiFi状态变化(开关)
*/
private onWifiStateChanged(data: CommonEventData): void {
const params = data.parameters
// wifiState: 0=正在关闭, 1=已关闭, 2=正在打开, 3=已打开
const wifiState = params?.wifiState ?? 0
hilog.info(DOMAIN, TAG, `WiFi state: ${wifiState}`)
if (wifiState === 1) {
// WiFi已关闭
if (this.currentStatus.type === NetworkType.WIFI) {
this.currentStatus.type = NetworkType.NONE
this.currentStatus.isConnected = false
this.notifyStatusChange()
}
}
}
/**
* WiFi连接状态变化
*/
private onWifiConnectionChanged(data: CommonEventData): void {
const params = data.parameters
// networkInfo包含WiFi连接信息
const networkInfo = params?.networkInfo
if (networkInfo?.isConnected) {
this.currentStatus.type = NetworkType.WIFI
this.currentStatus.isConnected = true
this.currentStatus.wifiName = networkInfo?.ssid ?? ''
this.currentStatus.signalStrength = networkInfo?.rssi ?? 0
hilog.info(DOMAIN, TAG, `Connected to WiFi: ${this.currentStatus.wifiName}`)
this.notifyStatusChange()
}
}
/**
* 更新网络状态
*/
private async updateNetworkStatus(netHandle: connection.NetHandle): Promise<void> {
try {
// 获取网络能力
const capabilities = await connection.getNetCapabilities(netHandle)
// 判断网络类型
if (capabilities.bearerTypes.includes(connection.BearerType.WIFI)) {
this.currentStatus.type = NetworkType.WIFI
} else if (capabilities.bearerTypes.includes(connection.BearerType.CELLULAR)) {
this.currentStatus.type = NetworkType.CELLULAR
} else if (capabilities.bearerTypes.includes(connection.BearerType.ETHERNET)) {
this.currentStatus.type = NetworkType.ETHERNET
} else {
this.currentStatus.type = NetworkType.UNKNOWN
}
this.currentStatus.isConnected = true
hilog.info(DOMAIN, TAG, `Network type: ${this.currentStatus.type}`)
this.notifyStatusChange()
} catch (err) {
hilog.error(DOMAIN, TAG, `Get capabilities failed: ${err.message}`)
}
}
/**
* 通知状态变化
*/
private notifyStatusChange(): void {
hilog.info(DOMAIN, TAG, `Status changed: ${JSON.stringify(this.currentStatus)}`)
if (this.onStatusChange) {
this.onStatusChange(this.currentStatus)
}
}
/**
* 获取当前网络状态
*/
getCurrentStatus(): NetworkStatus {
return { ...this.currentStatus }
}
/**
* 检查是否有网络
*/
hasNetwork(): boolean {
return this.currentStatus.isConnected
}
/**
* 检查是否是WiFi
*/
isWifi(): boolean {
return this.currentStatus.type === NetworkType.WIFI
}
/**
* 停止监听
*/
async stopListening(): Promise<void> {
if (this.subscriber) {
try {
await this.subscriber.unsubscribe()
} catch (err) {
hilog.error(DOMAIN, TAG, `Unsubscribe failed: ${err.message}`)
}
}
if (this.netConnection) {
this.netConnection.off('netAvailable')
this.netConnection.off('netLost')
this.netConnection.off('netUnavailable')
}
hilog.info(DOMAIN, TAG, 'Network event listener stopped')
}
}
3.3 屏幕事件监听
// ScreenEventListener.ets
import { commonEventManager, CommonEventSubscribeInfo, CommonEventData } from '@kit.BasicServicesKit'
import hilog from '@ohos.hilog'
const TAG = 'ScreenEvent'
const DOMAIN = 0xFF00
/**
* 屏幕状态
*/
export enum ScreenState {
ON = 'on',
OFF = 'off',
UNKNOWN = 'unknown'
}
/**
* 屏幕事件监听器
*/
export class ScreenEventListener {
private subscriber: commonEventManager.CommonEventSubscriber = null
private screenState: ScreenState = ScreenState.UNKNOWN
// 状态变化回调
private onScreenStateChange: ((state: ScreenState) => void) | null = null
/**
* 设置状态变化回调
*/
setOnScreenStateChange(callback: (state: ScreenState) => void): void {
this.onScreenStateChange = callback
}
/**
* 开始监听屏幕事件
*/
async startListening(): Promise<void> {
const subscribeInfo: CommonEventSubscribeInfo = {
events: [
'android.intent.action.SCREEN_ON', // 屏幕亮起
'android.intent.action.SCREEN_OFF', // 屏幕关闭
'android.intent.action.USER_PRESENT' // 用户解锁
]
}
try {
this.subscriber = await commonEventManager.createSubscriber(subscribeInfo)
this.subscriber.subscribe((err, data: CommonEventData) => {
if (err) {
hilog.error(DOMAIN, TAG, `Error: ${err.message}`)
return
}
this.handleScreenEvent(data)
})
hilog.info(DOMAIN, TAG, 'Screen event listener started')
} catch (err) {
hilog.error(DOMAIN, TAG, `Start failed: ${err.message}`)
}
}
/**
* 处理屏幕事件
*/
private handleScreenEvent(data: CommonEventData): void {
hilog.info(DOMAIN, TAG, `Event: ${data.event}`)
switch (data.event) {
case 'android.intent.action.SCREEN_ON':
this.onScreenOn()
break
case 'android.intent.action.SCREEN_OFF':
this.onScreenOff()
break
case 'android.intent.action.USER_PRESENT':
this.onUserPresent()
break
}
}
/**
* 屏幕亮起
*/
private onScreenOn(): void {
this.screenState = ScreenState.ON
hilog.info(DOMAIN, TAG, 'Screen ON')
// 恢复暂停的操作
this.resumeOperations()
this.notifyStateChange()
}
/**
* 屏幕关闭
*/
private onScreenOff(): void {
this.screenState = ScreenState.OFF
hilog.info(DOMAIN, TAG, 'Screen OFF')
// 暂停不必要的操作
this.pauseOperations()
this.notifyStateChange()
}
/**
* 用户解锁
*/
private onUserPresent(): void {
hilog.info(DOMAIN, TAG, 'User present (unlocked)')
// 用户解锁后的操作
this.onUserUnlocked()
}
/**
* 恢复操作
*/
private resumeOperations(): void {
hilog.info(DOMAIN, TAG, 'Resuming operations')
// 恢复动画
// 恢复定时刷新
// 恢复实时数据更新
}
/**
* 暂停操作
*/
private pauseOperations(): void {
hilog.info(DOMAIN, TAG, 'Pausing operations')
// 暂停动画(屏幕关闭时动画无意义)
// 降低刷新频率
// 暂停实时数据更新
}
/**
* 用户解锁后
*/
private onUserUnlocked(): void {
// 刷新数据
// 检查通知
// 更新时间显示
}
/**
* 通知状态变化
*/
private notifyStateChange(): void {
if (this.onScreenStateChange) {
this.onScreenStateChange(this.screenState)
}
}
/**
* 获取当前屏幕状态
*/
getScreenState(): ScreenState {
return this.screenState
}
/**
* 屏幕是否亮起
*/
isScreenOn(): boolean {
return this.screenState === ScreenState.ON
}
/**
* 停止监听
*/
async stopListening(): Promise<void> {
if (this.subscriber) {
try {
await this.subscriber.unsubscribe()
hilog.info(DOMAIN, TAG, 'Screen event listener stopped')
} catch (err) {
hilog.error(DOMAIN, TAG, `Stop failed: ${err.message}`)
}
}
}
}
3.4 综合系统事件管理器
// SystemEventManager.ets
import { BatteryEventListener, NetworkEventListener, ScreenEventListener } from './EventListeners'
import hilog from '@ohos.hilog'
const TAG = 'SystemEventManager'
const DOMAIN = 0xFF00
/**
* 系统状态
*/
export interface SystemStatus {
battery: {
level: number
isCharging: boolean
}
network: {
isConnected: boolean
type: string
}
screen: {
isOn: boolean
}
}
/**
* 系统事件管理器
* 统一管理所有系统事件监听
*/
export class SystemEventManager {
private batteryListener: BatteryEventListener
private networkListener: NetworkEventListener
private screenListener: ScreenEventListener
// 当前系统状态
private status: SystemStatus = {
battery: { level: 100, isCharging: false },
network: { isConnected: false, type: 'none' },
screen: { isOn: true }
}
// 状态变化回调
private onStatusChange: ((status: SystemStatus) => void) | null = null
constructor() {
this.batteryListener = new BatteryEventListener()
this.networkListener = new NetworkEventListener()
this.screenListener = new ScreenEventListener()
}
/**
* 设置状态变化回调
*/
setOnStatusChange(callback: (status: SystemStatus) => void): void {
this.onStatusChange = callback
}
/**
* 启动所有监听
*/
async startAll(): Promise<void> {
hilog.info(DOMAIN, TAG, 'Starting all system event listeners')
// 并行启动所有监听
await Promise.all([
this.startBatteryListener(),
this.startNetworkListener(),
this.startScreenListener()
])
hilog.info(DOMAIN, TAG, 'All listeners started')
}
/**
* 启动电量监听
*/
private async startBatteryListener(): Promise<void> {
await this.batteryListener.startListening()
// 定期获取状态
setInterval(() => {
const batteryStatus = this.batteryListener.getBatteryStatus()
this.status.battery = batteryStatus
this.notifyStatusChange()
}, 60000) // 每分钟更新一次
}
/**
* 启动网络监听
*/
private async startNetworkListener(): Promise<void> {
this.networkListener.setOnStatusChange((networkStatus) => {
this.status.network = {
isConnected: networkStatus.isConnected,
type: networkStatus.type
}
this.notifyStatusChange()
})
await this.networkListener.startListening()
}
/**
* 启动屏幕监听
*/
private async startScreenListener(): Promise<void> {
this.screenListener.setOnScreenStateChange((screenState) => {
this.status.screen.isOn = (screenState === 'on')
this.notifyStatusChange()
})
await this.screenListener.startListening()
}
/**
* 通知状态变化
*/
private notifyStatusChange(): void {
hilog.info(DOMAIN, TAG, `System status: ${JSON.stringify(this.status)}`)
if (this.onStatusChange) {
this.onStatusChange(this.status)
}
}
/**
* 获取当前系统状态
*/
getStatus(): SystemStatus {
return { ...this.status }
}
/**
* 检查是否应该执行耗电操作
*/
shouldRunPowerIntensiveTask(): boolean {
const { battery, network, screen } = this.status
// 充电中或电量充足
const hasPower = battery.isCharging || battery.level > 30
// 有网络连接
const hasNetwork = network.isConnected
// 屏幕亮起
const screenActive = screen.isOn
return hasPower && hasNetwork && screenActive
}
/**
* 检查是否应该执行后台任务
*/
shouldRunBackgroundTask(): boolean {
const { battery, network } = this.status
// 电量充足或充电中
const hasPower = battery.isCharging || battery.level > 20
// 有网络连接
const hasNetwork = network.isConnected
return hasPower && hasNetwork
}
/**
* 停止所有监听
*/
async stopAll(): Promise<void> {
hilog.info(DOMAIN, TAG, 'Stopping all listeners')
await Promise.all([
this.batteryListener.stopListening(),
this.networkListener.stopListening(),
this.screenListener.stopListening()
])
hilog.info(DOMAIN, TAG, 'All listeners stopped')
}
}
/**
* 在UI组件中使用
*/
@Entry
@Component
struct SystemStatusPage {
@State systemStatus: SystemStatus = {
battery: { level: 100, isCharging: false },
network: { isConnected: false, type: 'none' },
screen: { isOn: true }
}
private eventManager: SystemEventManager = new SystemEventManager()
async aboutToAppear() {
// 设置状态变化回调
this.eventManager.setOnStatusChange((status) => {
this.systemStatus = status
})
// 启动监听
await this.eventManager.startAll()
}
async aboutToDisappear() {
await this.eventManager.stopAll()
}
build() {
Column() {
Text('系统状态监控')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 20 })
// 电量状态
Row() {
Text('电量:')
.width(80)
Text(`${this.systemStatus.battery.level}%`)
if (this.systemStatus.battery.isCharging) {
Text(' (充电中)')
.fontColor(Color.Green)
}
}
.width('100%')
.margin({ bottom: 10 })
// 网络状态
Row() {
Text('网络:')
.width(80)
if (this.systemStatus.network.isConnected) {
Text(`${this.systemStatus.network.type}`)
.fontColor(Color.Green)
} else {
Text('无网络')
.fontColor(Color.Red)
}
}
.width('100%')
.margin({ bottom: 10 })
// 屏幕状态
Row() {
Text('屏幕:')
.width(80)
Text(this.systemStatus.screen.isOn ? '亮起' : '关闭')
}
.width('100%')
}
.width('100%')
.height('100%')
.padding(20)
}
}
四、踩坑与注意事项
4.1 坑一:权限不足
问题:部分系统事件需要系统签名或特殊权限。
// ❌ 普通应用无法订阅某些系统事件
await commonEventManager.createSubscriber({
events: ['android.intent.action.BOOT_COMPLETED'] // 需要系统权限
})
// ✅ 检查权限并优雅降级
async function safeSubscribe() {
try {
const subscriber = await commonEventManager.createSubscriber({
events: ['android.intent.action.BOOT_COMPLETED']
})
subscriber.subscribe((err, data) => {
if (err) {
if (err.code === 201 || err.code === 202) {
// 权限不足,使用替代方案
hilog.warn(DOMAIN, TAG, 'Permission denied, using alternative')
useAlternativeApproach()
}
return
}
// 处理事件
})
} catch (err) {
hilog.error(DOMAIN, TAG, `Subscribe failed: ${err.message}`)
}
}
4.2 坑二:事件数据格式变化
问题:不同系统版本,事件数据格式可能不同。
// ❌ 假设数据格式固定
const level = data.parameters.level // 可能不存在
// ✅ 安全访问数据
function safeGetBatteryLevel(data: CommonEventData): number {
const params = data.parameters
// 多种方式获取
if (params?.level !== undefined) {
return params.level
}
// 从data字符串解析
if (data.data) {
try {
const parsed = JSON.parse(data.data)
return parsed.level ?? 0
} catch (e) {
// 解析失败
}
}
// 默认值
return 0
}
4.3 坑三:回调在非主线程
问题:CommonEvent回调可能在Binder线程,不能直接更新UI。
// ❌ 在回调中直接更新UI
this.subscriber.subscribe((err, data) => {
this.batteryLevel = data.parameters.level // 可能不在主线程
})
// ✅ 使用EventHandler转发到主线程
import { EventHandler, EventRunner } from '@kit.BasicServicesKit'
class SafeSubscriber {
private mainHandler: EventHandler
constructor() {
const mainRunner = EventRunner.getMainEventRunner()
this.mainHandler = new EventHandler(mainRunner)
}
async subscribe() {
this.subscriber.subscribe((err, data) => {
// 转发到主线程
this.mainHandler.sendEvent({
eventId: 1,
param: data
})
})
}
}
4.4 坑四:重复订阅
问题:多次调用订阅会收到多次回调。
// ❌ 多次订阅
async subscribeMultiple() {
await this.subscriber.subscribe(callback)
await this.subscriber.subscribe(callback) // 会收到两次回调
}
// ✅ 使用标志位防止重复
class SingleSubscriber {
private isSubscribed: boolean = false
async subscribe() {
if (this.isSubscribed) {
hilog.warn(DOMAIN, TAG, 'Already subscribed')
return
}
await this.subscriber.subscribe(callback)
this.isSubscribed = true
}
async unsubscribe() {
if (!this.isSubscribed) {
return
}
await this.subscriber.unsubscribe()
this.isSubscribed = false
}
}
五、HarmonyOS 6适配指南
5.1 API变更
| 变更项 | HarmonyOS 5 | HarmonyOS 6 |
|---|---|---|
| 导入方式 | @ohos.commonEvent |
@kit.BasicServicesKit |
| 订阅返回 | 同步返回 | Promise异步 |
| 错误处理 | 回调参数 | 独立error事件 |
5.2 新增功能
// HarmonyOS 6新增:事件过滤
const subscribeInfo: CommonEventSubscribeInfo = {
events: ['android.intent.action.BATTERY_CHANGED'],
// 过滤特定设备
publisherDeviceId: 'local',
// 过滤特定UID
publisherUid: 1001,
// 设置优先级
priority: 100
}
// HarmonyOS 6新增:获取粘性事件
const subscribeInfo: CommonEventSubscribeInfo = {
events: ['android.intent.action.BATTERY_CHANGED'],
// 订阅时立即获取粘性事件
getStickEvent: true
}
六、总结
6.1 核心要点回顾

6.2 最佳实践清单
- [ ] 处理权限不足的情况
- [ ] 安全访问事件数据
- [ ] 使用EventHandler转发到主线程
- [ ] 防止重复订阅
- [ ] 组件销毁时取消订阅
- [ ] 使用统一管理器管理所有监听
- [ ] 根据系统状态调整应用行为
下一篇预告:《粘性事件:延迟事件处理》——深入粘性事件机制,实现延迟订阅场景。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)