Flutter 三方库 flutter_broadcasts 的鸿蒙适配教程

本文配套仓库:https://atomgit.com/oh-flutter/flutter_broadcasts(TAG:0.4.0-ohos-1.0.0-beta.1,分支:feat/ohos_flutter_broadcasts_0.4.0)。本文解决的是:从上游 GitHub 仓库开始,把 flutter_broadcasts 完整适配到 OpenHarmony / HarmonyOS 平台,并在鸿蒙真机上验证。

flutter_broadcasts 是 pub.dev 上的一个跨平台广播插件(作者 Kevin Latusinski,MIT 协议,0.4.0)。它把 Android 的 BroadcastReceiver/Intent 与 iOS 的 NSNotificationCenter 封装成同一套 Dart API:构造一个 BroadcastReceiver 订阅若干事件名,调用 sendBroadcast() 发布消息,就能在应用内甚至跨应用传递数据,是"组件解耦""感知系统状态"这类场景的常用选择。它原本只支持 Android 与 iOS,没有鸿蒙;而鸿蒙 Flutter 应用要做广播通信,得自己对接 ArkTS 侧的 commonEventManager 公共事件服务。本文完整走一遍社区三方库适配的标准流程:把上游仓库同步到 AtomGit,拉到宿主机,建适配分支,用命令自动补全 ohos 目录,补全 Dart 与 ArkTS 两侧实现,补齐适配说明文件后提交分支与 TAG,最后用真机验证全部接口。

一、环境搭建

鸿蒙 Flutter 开发环境(ohos 版 SDK、DevEco Studio、签名配置)的完整搭建步骤,官方指南已经写得很细,直接照做即可:

Flutter OHOS 开发环境搭建指南

适配工作比单纯使用多一项要求:终端里 flutter 命令必须指向 ohos 版 SDK,因为后文自动补全 ohos 目录靠的是它提供的 flutter create --platforms ohos 能力。环境装好后用 flutter devices 确认能识别鸿蒙设备。本文实测使用的环境:

版本
Flutter(ohos 版)3.41.10-ohos-1.0.1(Dart 3.11.5)
编译 SDKcompatibleSdkVersion 5.1.0(18),runtimeOS HarmonyOS
实测设备HUAWEI ADA-AL10U 真机(OpenHarmony 6.1.1.120 / API 24)

二、适配过程

2.1 将上游仓库同步到 AtomGit

鸿蒙 Flutter 三方库社区托管在 AtomGit,上游项目在 GitHub,适配的第一步是把上游代码完整迁入 AtomGit 上为它新建的目标仓库 oh-flutter/flutter_broadcasts。做法是把上游克隆下来,添加 AtomGit 远端后整库推送,保留全部 commit 历史与 TAG,后续上游发新版时也能用同样的方式增量同步:

# 克隆上游仓库,目录名与目标仓库保持一致
git clone https://github.com/kevlatus/flutter_broadcasts.git flutter_broadcasts
cd flutter_broadcasts

# 关联 AtomGit 目标仓库
git remote add atomgit https://atomgit.com/oh-flutter/flutter_broadcasts.git

# 推送全部分支与 TAG
git push atomgit --all
git push atomgit --tags

推送完成后,打开 AtomGit 上目标仓库的页面,能看到与上游一致的提交历史和源码目录:

在这里插入图片描述

图一:同步完成后 AtomGit 目标仓库的代码页

2.2 拉取代码到宿主机

从目标仓库把代码拉到本地,后续所有操作都在这份代码上进行:

git clone https://atomgit.com/oh-flutter/flutter_broadcasts.git
cd flutter_broadcasts

此时的目录是上游的原始结构,只有 Android 与 iOS 两端实现,没有任何鸿蒙相关内容:

flutter_broadcasts/
├── android/                 # Android 实现:FlutterBroadcastsPlugin.kt
├── ios/                     # iOS 实现:FlutterBroadcastsPlugin.m / Swift 版
├── example/                 # 上游自带示例(Android / iOS)
├── lib/
│   ├── flutter_broadcasts.dart        # 导出入口
│   └── src/
│       ├── broadcast.dart             # BroadcastMessage 与顶层 sendBroadcast()
│       ├── flutter_broadcasts.dart    # part 汇总文件
│       ├── native_channel.dart        # MethodChannel 通信单例
│       └── receiver.dart              # BroadcastReceiver 生命周期管理
├── test/                    # 单元测试
├── pubspec.yaml
├── CHANGELOG.md
├── LICENSE
└── README.md

在这里插入图片描述

图二:clone 完成后的仓库目录,尚无 ohos 目录

2.3 创建适配分支并补全 ohos 目录结构

先建适配分支。分支命名规则是 feat/ohos_<库名>_<版本号>,版本号取自上游 pubspec.yamlversion 字段,这里是 0.4.0:

git checkout -b feat/ohos_flutter_broadcasts_0.4.0

接着用 ohos 版 Flutter SDK 提供的能力自动补全 ohos 目录。这条命令会读取 pubspec.yaml,生成鸿蒙工程骨架,并在 pubspec.yamlplugin.platforms 下追加 ohos 注册节点:

flutter create --platforms ohos .

命令结束后,仓库里多出一个 ohos/ 目录,pubspec.yaml 里多出一段注册:

flutter:
  plugin:
    platforms:
      android:
        package: de.kevlatus.flutter_broadcasts
        pluginClass: FlutterBroadcastsPlugin
      ios:
        pluginClass: FlutterBroadcastsPlugin
      ohos:                          # 新增
        pluginClass: FlutterBroadcastsPlugin

生成的 ohos 目录结构与各文件职责:

ohos/
├── index.ets                          # 模块出口:导出插件类给鸿蒙工程消费
├── oh-package.json5                   # 模块描述:名称、版本与依赖声明
├── build-profile.json5                # 模块构建配置
├── hvigorfile.ts                      # hvigor 构建脚本
├── BuildProfile.ets                   # 构建期生成的配置
└── src/main/
    ├── module.json5                   # 模块清单
    └── ets/components/plugin/
        └── FlutterBroadcastsPlugin.ets    # 插件实现(此刻只是空模板)
文件职责
index.ets把插件类导出为模块默认出口,宿主工程的 GeneratedPluginRegistrant.ets 靠它完成注册
oh-package.json5声明插件模块的元信息;对 flutter_ohos 引擎的依赖由宿主工程统一解析
src/main/module.json5鸿蒙模块清单,声明模块类型与入口
FlutterBroadcastsPlugin.ets插件实现本体,此刻由模板生成,只实现了生命周期空壳——2.4 节要补的就是它

在这里插入图片描述

图三:flutter create 命令输出与生成的 ohos 目录

2.4 在插件文件中补全 ohos 实现

适配的改动全景如下。核心原则是只做加法:Android、iOS 的原有实现一行不动。

文件改动
lib/src/native_channel.dart新增 ohos 通道与平台判断,接口调用路由到鸿蒙实现
pubspec.yamlplugin.platforms 注册 ohos 节点(2.3 已完成)
ohos/.../FlutterBroadcastsPlugin.ets补全插件实现(空模板到完整实现)
example/lib/main.dart重写 demo,覆盖全部公开接口并加入系统公共事件演示
四份说明文件新增 README.OpenSource、README.OpenHarmony_CN.md、README.OpenHarmony.md、CHANGELOG.OpenHarmony.md

Dart 侧:上游把所有通道通信集中在一个 _BroadcastChannel 单例里,适配只需在这个单例上做平台路由,BroadcastReceiverBroadcastMessage 的公开 API 完全不用动:

class _BroadcastChannel {
  static const MethodChannel _channel =
      const MethodChannel('de.kevlatus.flutter_broadcasts');

  /// The channel used on the OpenHarmony platform.
  ///
  /// On ohos, the native side registers an identically named channel inside
  /// the plugin's ArkTS implementation, which routes the calls to the
  /// `commonEventManager` APIs.
  static const MethodChannel _ohosChannel =
      const MethodChannel('de.kevlatus.flutter_broadcasts');

  /// `kIsWeb` is checked first on purpose: accessing [Platform] throws on
  /// the web platform, so it must be guarded.
  static bool get _isOhos => !kIsWeb && Platform.operatingSystem == 'ohos';

  static MethodChannel get _activeChannel => _isOhos ? _ohosChannel : _channel;

  static _BroadcastChannel instance = _BroadcastChannel();

  Stream<BroadcastMessage> startReceiver(BroadcastReceiver receiver) async* {
    final String? result =
        await _activeChannel.invokeMethod('startReceiver', receiver.toMap());

    if (result != null) {
      throw FlutterError(result);
    }

    yield* _messages.where((event) => receiver._id == event._receiverId);
  }
  // stopReceiver / sendBroadcast 同样通过 _activeChannel 调用
}

三个设计决策值得展开。其一,平台判断用 Platform.operatingSystem == 'ohos',并且把 kIsWeb 的检查放在前面——web 平台上访问 dart:ioPlatform 会直接抛异常,必须先短路。其二,_ohosChannel_channel 同名不是笔误:鸿蒙侧 ArkTS 插件注册的就是这个名字,Dart 侧用 getter 按平台选择实例,业务层对路由完全无感知。其三,失败语义沿用上游约定——原生侧出错时回传错误字符串,Dart 侧检查到非空 result 就抛 FlutterError,与 Android/iOS 行为一致。

ArkTS 侧:Android 实现与鸿蒙系统能力的对应关系如下,整个插件就是围绕这张映射表展开的:

AndroidOpenHarmony commonEventManager
BroadcastReceiver(names)createSubscriber({events: names})
context.registerReceiversubscribe
context.unregisterReceiverunsubscribe
Intent(action) + putExtrapublish(name, {parameters})
onReceive(intent)subscribe 回调中的 CommonEventData

插件骨架遵循 flutter_ohos 插件模板的生命周期三接口:onAttachedToEngine 里创建通道并注册处理器,onDetachedFromEngine 里退订全部订阅者并注销处理器,onMethodCallstartReceiver/stopReceiver/sendBroadcast 三个方法分发。订阅一条公共事件的完整链路:

commonEventManager.createSubscriber(subscribeInfo,
  (createError: BusinessError, subscriber: commonEventManager.CommonEventSubscriber) => {
    if (createError) {
      result.error(ERROR_CODE, createError.message, null);
      return;
    }
    commonEventManager.subscribe(subscriber,
      (eventError: BusinessError, data: commonEventManager.CommonEventData) => {
        if (eventError || !data) {
          console.error(`${TAG}: failed to receive common event, code=${eventError?.code}`);
          return;
        }
        // The common event service injects the publisher's module name
        // into the parameters; strip it to keep parity with the Android
        // implementation, whose Intent extras carry user data only.
        const raw = (data.parameters ?? {}) as Record<string, Object>;
        const parameters: Record<string, Object> = {};
        Object.keys(raw).forEach((key: string) => {
          if (key !== 'moduleName') {
            parameters[key] = raw[key];
          }
        });
        const message: Record<string, Object> = {
          'receiverId': id,
          'name': data.event,
          'data': normalizeValue(parameters),
          'timestamp': Date.now(),
        };
        channel?.invokeMethod('receiveBroadcast', message, new NotifyResult());
      });
    this.receivers.set(id, subscriber);
    result.success(null);
  });

有三个关键点。第一,公共事件服务会把发布方的 moduleName 注入事件参数,而 Android 的 Intent extras 只携带用户数据,所以回调里显式过滤掉 moduleName,保证 data 内容跨平台一致。第二,timestamp 由插件以毫秒时间戳补齐——Android 与 iOS 都没有标准化的消息时间戳,上游 Dart 侧用 DateTime.fromMillisecondsSinceEpoch(map['timestamp']) 解析,鸿蒙端补上同样的字段后三端语义对齐。第三,NotifyResult 是一个空实现的 MethodResultreceiveBroadcast 是原生到 Dart 的长期通知,一次订阅会回调多次,而引擎要求每次方法调用只允许回复一次,业务侧的 result.success(null) 已经在订阅建立时用过,通知路径必须换一个专用的回复对象兜底,否则会触发二次回复崩溃。

发送广播一侧还有一个隐蔽的坑——参数展开:

private onSendBroadcast(call: MethodCall, result: MethodResult): void {
  const name = String(call.argument('name'));
  const dataValue = call.argument('data') as Record<string, Object> | null | undefined;
  // The decoded argument is a Map instance, which the common event service
  // drops during cross-process serialization. Expand it into a plain record
  // so that the parameters survive the round trip.
  const publishParameters: Record<string, Object> = {};
  if (dataValue instanceof Map) {
    (dataValue as Map<string, Object>).forEach((value: Object, key: string) => {
      publishParameters[key] = normalizeValue(value);
    });
  } else if (dataValue !== null && dataValue !== undefined) {
    const source = dataValue as Record<string, Object>;
    Object.keys(source).forEach((key: string) => {
      publishParameters[key] = normalizeValue(source[key]);
    });
  }
  const publishData: commonEventManager.CommonEventPublishData = {
    parameters: publishParameters,
  };
  commonEventManager.publish(name, publishData, (error: BusinessError) => {
    if (error) {
      result.error(ERROR_CODE, error.message, null);
      return;
    }
    result.success(null);
  });
}

StandardMessageCodec 解码出来的 data 是 ArkTS 的 Map 实例,而公共事件服务做跨进程序列化时会把它直接丢弃,表现为订阅方收到的 data 恒为空。上面的代码把 Map 逐层展开成普通 Record 再交给 publish,参数才能在跨进程往返中存活。配套的 normalizeValue 工具函数与 Android 端的 normalize 对齐:编解码器无法表示的类型降级为字符串,保证发布不因类型问题失败。这个问题的排查过程见 4.1 节。"收到的事件参数与发送内容不符"还有一个同类问题:修复前,公共事件服务注入的 moduleName 会残留在订阅方的 data 里(见 2.4 的过滤处理),修复前后对照见图十二。

2.5 补全适配说明文件并提交分支

社区要求每个适配仓库携带四份说明文件:

文件作用
README.OpenSource开源合规声明:上游地址、协议、版本、责任人
README.OpenHarmony_CN.md中文适配说明:接口映射、使用方式、已知问题
README.OpenHarmony.md英文适配说明,内容与中文版对齐
CHANGELOG.OpenHarmony.md鸿蒙侧变更记录,含实测验证结论

其中 README.OpenSource 的实际内容:

[
  {
    "Name": "flutter_broadcasts",
    "License": "MIT",
    "License File": "LICENSE",
    "Version Number": "0.4.0",
    "Owner": "qiaomu8559968@126.com",
    "Upstream URL": "https://github.com/kevlatus/flutter_broadcasts",
    "Description": "在原库基础上新增 OpenHarmony 平台支持,基于公共事件 commonEventManager 实现广播消息的订阅与发送"
  }
]

CHANGELOG.OpenHarmony.md 记录适配内容与真机验证结论(摘要):

## [0.4.0-ohos-1.0.0-beta.1]

- 适配 OpenHarmony 平台:新增 ohos 目录、Dart 侧平台分支与 pubspec 平台注册
- 基于 commonEventManager(@kit.BasicServicesKit)实现公共事件订阅与发布
- ohos 端 sendBroadcast 在发布完成后正常回复,规避上游 Android 端不回写 result 导致 Future 挂起的问题
- 接收回调补充毫秒级 timestamp 字段,对齐 Dart 侧解析协议
- 发送与接收时将事件参数 Map 展开为 Record,规避公共事件服务跨进程序列化丢失参数的问题
- 接收侧过滤公共事件服务注入的 moduleName 字段,使 data 内容与 Android Intent extras 语义对齐
- 真机验证环境:HUAWEI ADA-AL10U,OpenHarmony 6.1.1.120(API 24)

提交分支时把适配改动、example 与文档分成独立的 commit,然后按社区规则打 TAG。TAG 命名规则是 原库版本-ohos-适配版本-beta.x,这里适配版本从 1.0.0 起:

# 提交(分组示意,实际按改动拆分)
git add lib/ pubspec.yaml ohos/
git commit -m "feat: adapt flutter_broadcasts for the OpenHarmony platform"
git add example/
git commit -m "feat: rework example to cover the full API on ohos"
git add README.OpenSource README.OpenHarmony_CN.md README.OpenHarmony.md CHANGELOG.OpenHarmony.md
git commit -m "docs: add OpenHarmony adaptation docs"

# 打 TAG 并推送
git tag 0.4.0-ohos-1.0.0-beta.1
git push atomgit feat/ohos_flutter_broadcasts_0.4.0 --tags

在这里插入图片描述
在这里插入图片描述

图四:分支提交历史与 TAG

三、在 Demo 中验证适配效果

3.1 使用仓库自带的 example

上游 example 只有 Android/iOS 配置,适配时把它重写为覆盖全部公开接口的鸿蒙演示工程:一个发送卡片(可编辑事件名与 data 键值对),两个接收卡片——Receiver A 订阅自定义事件 de.kevlatus.flutter_broadcasts_example.demo_action,Receiver B 订阅系统公共事件 usual.event.SCREEN_ONusual.event.SCREEN_OFF。每个接收卡片实时显示 isListening 状态与最近收到的消息(名称、data、时间戳)。

构建、安装、启动的完整命令序列:

cd example
flutter build hap --debug

cd ohos
# 若已安装旧版本,先停进程再覆盖安装
hdc shell aa force-stop de.kevlatus.flutter_broadcasts_example
hdc install -r ../build/ohos/hap/entry-default-signed.hap

# 启动应用
hdc shell aa start -b de.kevlatus.flutter_broadcasts_example -a EntryAbility

应用启动后的初始状态,Receiver A 已在 initState 中自动开始订阅:

在这里插入图片描述

图五:example 启动后的初始界面

3.2 自建工程时以 AtomGit 链接方式引入

不想跑 example 的读者,在自己的工程里用 git 依赖也能直接接入,ref 锁定 TAG 保证可复现:

dependencies:
  flutter_broadcasts:
    git:
      url: https://atomgit.com/oh-flutter/flutter_broadcasts.git
      ref: 0.4.0-ohos-1.0.0-beta.1

执行 flutter pub get 拉取即可。TAG 与框架版本对照:

Flutter(ohos 版)3.41.10-ohos-1.0.1
TAG0.4.0-ohos-1.0.0-beta.1
分支feat/ohos_flutter_broadcasts_0.4.0

兼容性说明:以上组合在 stable 渠道实测通过;若使用 canary 引擎,注意宿主工程 compatibleSdkVersion 需与引擎要求匹配,过低的取值会在构建期报 SDK 版本不匹配。

3.3 调用接口并观察真机运行效果

最小调用代码只有三段:订阅、发送、停止。

// 1. 订阅:构造 receiver,监听消息流,start 生效
final receiver = BroadcastReceiver(
  names: ['de.kevlatus.flutter_broadcasts_example.demo_action'],
);
receiver.messages.listen((BroadcastMessage message) {
  debugPrint('received ${message.name}: ${message.data}');
});
await receiver.start();

// 2. 发送
await sendBroadcast(BroadcastMessage(
  name: 'de.kevlatus.flutter_broadcasts_example.demo_action',
  data: {'from': 'demo'},
));

// 3. 停止
await receiver.stop();

发送与接收。点击 Send Broadcast 后,Receiver A 的消息列表立即出现 {from: demo},data 内容干净无多余字段,消息自带毫秒时间戳;发送侧因 sendBroadcast 正常回写 result,SnackBar 弹出 “sendBroadcast completed (result received)”——上游 Android 端不回写 result 导致 Future 挂起的问题在鸿蒙端不存在:

在这里插入图片描述

图六:发送后接收方显示消息,发送方 SnackBar 确认完成

生命周期闭环。点击 Receiver A 的 stop,isListening 变为 false;此时再点 Send,消息列表不再新增,说明原生侧订阅确已退订:

在这里插入图片描述

图七:停止订阅后状态与界面同步

在这里插入图片描述

图八:退订期间发送的事件不再送达

重新点击 start,isListening 恢复 true,再次发送消息正常到达,完整的订阅-退订-再订阅闭环可用:

在这里插入图片描述

图九:重新订阅后消息恢复送达

系统公共事件。Receiver B 订阅 usual.event.SCREEN_ON/usual.event.SCREEN_OFF 后,按电源键息屏再亮屏,两条系统事件带 reason 参数到达(SCREEN_ON 携带 {reason: POWER_KEY}SCREEN_OFF 携带 {reason: HARD_KEY} 或超时熄屏时的 {reason: TIMEOUT}),说明系统事件的参数透传正常:

在这里插入图片描述

图十:系统公共事件携带 reason 参数到达

受限场景也如实记录:设备锁屏后应用进程会被系统冻结(hilog 中可见 freezePid 标记),冻结期间的系统事件不会实时送达,而是在进程解冻(解锁回前台)后由公共事件服务集中补发。下图是实测中一次补发的完整列表——35 分钟前息屏时冻结的事件,在解锁后全部按序到达:

在这里插入图片描述

图十一:锁屏冻结期间的事件在解锁后补发

这是 OpenHarmony 的系统进程管理行为,不是插件缺陷;前台场景下的自定义事件不受影响。业务上若依赖实时息屏感知,可结合 stop/start 在退后台时暂停订阅、回前台时恢复。

适配完成度总结BroadcastReceiver 构造与订阅、sendBroadcaststop/start 生命周期、isListening 状态在鸿蒙真机上全链路可用;系统公共事件订阅语义正确、参数透传正常,仅有锁屏冻结带来的延迟投递这一系统级限制;三端返回值语义一致——start/stop/sendBroadcast 均为无值 Future,错误统一以 FlutterError 抛出。

四、常见问题

4.1 适配过程中的问题

Q1:flutter create --platforms ohos 会破坏已有工程吗?

不会。它只做两件事:生成 ohos/ 目录、在 pubspec.yamlplugin.platforms 下追加 ohos 注册节点,不触碰 android/ios 目录与 Dart 代码。在已适配的仓库上重复执行也是幂等的,适配合并冲突时放心重跑。

Q2:ArkTS 编译报类型错误,提示不能将类型赋给参数。

flutter_ohos 的 ArkTS 严格模式对 call.argument() 返回值的类型收窄要求比 Kotlin 高,call.argument('id') as number 这类直接断言在部分引擎版本上编译不过。本文的写法是先收窄到可空类型再判空:const idValue = call.argument('id') as number | null | undefined; if (idValue === undefined || idValue === null) { ... },最后 Number(idValue) 显式转换。排查编译错误时优先检查所有 call.argument 的类型链路。

Q3:订阅方收到的 data 恒为空,发送明明带了参数。

这是本次适配实踩最隐蔽的一坑:StandardMessageCodec 解码出的 data 是 ArkTS Map 实例,CommonEventPublishData.parameters 期望的是普通 Record,公共事件服务跨进程序列化时会把 Map 直接丢弃,事件能到达但参数没了。修复是发送前把 Map 逐层展开为 Record(见 2.4 的 onSendBroadcast)。定位方法:在原生侧 publish 前打印参数确认非空,再用 hdc shell hilog 过滤公共事件服务日志确认到达订阅方时的内容,两端一对比即可锁定序列化环节。

在这里插入图片描述

图十二:修复前收到的事件参数存在 moduleName 注入问题

Q4:运行时报 MethodResult 二次回复异常。

flutter_ohos 的引擎契约是每次方法调用只允许回复一次,而广播插件的原生到 Dart 通知(receiveBroadcast)天然是多次的。解决方式是为通知路径准备一个空实现的 MethodResultNotifyResult),业务请求的 result 只在 start/stop/send 各自完成时回复一次,两条路径严格分离。

4.2 使用过程中的问题

Q1:锁屏后收不到 SCREEN_ON/SCREEN_OFF,解锁后一次性收到一批。

OpenHarmony 会冻结后台应用进程(hilog 中表现为 freezePid 标记),冻结期间公共事件不会实时投递,进程解冻后由系统集中补发。实测一次 35 分钟的锁屏期间事件在解锁后全部按序到达(见图十一)。这不是插件问题,前台场景的自定义事件不受影响;需要实时感知开关屏的业务应在退后台时 stop、回前台时 start

Q2:收到的消息 timestamp 是什么时间?

鸿蒙端由插件在事件到达原生侧的时刻补入毫秒时间戳,Dart 侧解析为 DateTime,与上游 Android/iOS 的语义对齐。注意它是"到达时间"而非"发布时间"——若发布方与订阅方不在同一毫秒,两者可能有微小差值;结合 4.2 Q1,锁屏冻结期间的补发事件时间戳同样是解冻补发时刻。

Q3:调用 stop() 后界面上的 isListening 还是 true。

BroadcastReceiver 不是 ChangeNotifierisListening 只在 build 时求值。按钮回调里 await receiver.stop() 之后必须 setState 刷新,否则 UI 停留旧值,后续 stop 还会被 if (!isListening) return 早退,看起来像"停不掉"。正确写法:

TextButton(
  onPressed: () async {
    await receiver.stop();
    if (mounted) {
      setState(() {});
    }
  },
  child: const Text('stop'),
)

Q4:除了开关屏,还能订阅哪些系统公共事件?

OpenHarmony 定义了完整的系统公共事件清单(usual.event.* 前缀),常见的还有网络状态变化、电量变化、语言切换等。订阅方式与本文的 SCREEN_ON/OFF 完全一致,把事件名放进 names 列表即可;部分系统事件需要在 module.json5 中声明对应权限后才能收到,具体以系统公共事件官方文档为准。

五、结语

本文完成了 flutter_broadcasts 的鸿蒙适配全流程:上游仓库同步 AtomGit、建分支并用 flutter create --platforms ohos 补全骨架、Dart 侧平台路由加 ArkTS 侧 commonEventManager 实现、四份适配说明文件、提交分支与 TAG,最终在 HUAWEI 真机上验证了全部接口。适配使用中的问题欢迎在鸿蒙仓库提 Issue,原库行为相关的讨论建议到上游仓库 Issue反馈;接口怎么用、参数与返回值的细节,请继续阅读《给鸿蒙 App 增加广播收发能力 —— flutter_broadcasts 的鸿蒙使用指南》

六、相关链接

欢迎加入 CPF-Flutter 鸿蒙社区,社区入口、环境搭建指南和本文相关链接统一放在这里:

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐