适配仓库: https://atomgit.com/oh-flutter/network_status_bridge
适配分支:
feat/ohos_network_status_bridge_0.0.5受测提交:
3650e53a67afe9720c03b429177c2967e0a77b19
一、最终效果与适配目标
network_status_bridge 提供一个很小但实用的接口:读取当前默认网络类型,并在默认网络变化时发出事件。上游 0.0.5 没有 OHOS 平台目录。本次适配不改变 NetworkType、getCurrentType() 和 onNetworkChanged,只为原 MethodChannel/EventChannel 接入 HarmonyOS NetConnection。

图 1:CHZ-AL00 / HarmonyOS 7.0.0.105 上订阅网络流后收到首值,当前默认网络为 Wi-Fi。

图 2:取消订阅后页面显示"监听已暂停",已接收事件数保持为 1。

图 3:重新订阅后收到新的 Wi-Fi 首值,事件数由 1 变为 2。
| 验证点 | 实测结果 | 证据 |
|---|---|---|
| 当前默认网络 | getCurrentType() 返回 NetworkType.wifi |
图 1、图 8 |
| 订阅首值 | 注册完成后立即查询并投递 Wi-Fi | 图 1 |
| 取消和重订阅 | 取消后不再投递,重订阅获得新首值 | 图 2、图 3 |
| 自动化与构建 | 8 Dart + 3 Widget + 15 ArkTS,共 26 项及 HAP 通过 | 图 6、图 7 |
| 验证边界 | 未主动切换 Wi-Fi、蜂窝和离线;网络类型不等于互联网可达 | 图 8 |
二、成果速览
| 项目 | 内容 |
|---|---|
| 上游基线 | 0.0.5,提交 ba6a3fb395f29ca5a783dd283d3bafd8bcab5fd3,MIT |
| 适配分支 | feat/ohos_network_status_bridge_0.0.5 |
| 适配提交 | 3650e53a67afe9720c03b429177c2967e0a77b19 |
| 新增 OHOS 能力 | 默认网络查询、首值事件、变化去重、取消和解绑清理 |
| 原有接口 | NetworkStatusBridge.getCurrentType、onNetworkChanged |
| 权限 | ohos.permission.GET_NETWORK_INFO |
| 真机结论 | Wi-Fi 查询、首值、取消与重订阅通过;真实网络切换未覆盖 |
2026 年 9 月 11 日,我核对 pub.dev 最新版本、上游 HEAD、候选清单以及 oh-flutter、CPF-Flutter、hxa-flutter 的同名仓库,未发现可直接使用的 OHOS 适配,因此以最新 0.0.5 开始实现。
三、实测环境
| 组件 | 实测版本 |
|---|---|
| Flutter OH | 3.41.10-ohos-1.0.1 |
| Dart | 3.11.5 |
| DevEco Studio | 26.0.0 Release |
| HarmonyOS SDK | API 26;示例兼容 API 18 |
| 真机 | CHZ-AL00,HarmonyOS 7.0.0.105 |
| 插件 | network_status_bridge 0.0.5 |
环境搭建参考 Flutter OH 环境搭建指南。Flutter OH 的版本号最大标签 3.44.9+ohos-0.0.1-canary1 是预览版;本文实测的是稳定版 3.41.10-ohos-1.0.1。
四、同步仓库并补全 OHOS 结构
我保留上游 Git 历史与 MIT 许可证,将代码同步到 AtomGit,再从 0.0.5 基线创建适配分支:
shell
git clone https://atomgit.com/oh-flutter/network_status_bridge.git
cd network_status_bridge
git switch -c feat/ohos_network_status_bridge_0.0.5 ba6a3fb395f29ca5a783dd283d3bafd8bcab5fd3
flutter create --template=plugin --platforms=ohos --no-pub .
随后将模板类替换为 NetworkStatusBridgePlugin,保留根目录 lib/ 的真实通道名,并增加独立 OHOS 示例、权限和测试。

图 4:AtomGit origin、统一适配分支、当前 HEAD 和工作区状态。
五、原有 API 与类型映射
Dart 层契约很明确:
dart
final NetworkType current = await NetworkStatusBridge.getCurrentType();
final StreamSubscription<NetworkType> subscription =
NetworkStatusBridge.onNetworkChanged.listen((NetworkType type) {
debugPrint('default network: ${type.name}');
});
原生返回整数,Dart 按枚举下标映射:0 为 none、1 为 wifi、2 为 cellular、3 为 wired、4 为 other。越界值也降级成 other,防止新平台类型导致数组异常。方法通道是 network_status_bridge/method,事件通道是 network_status_bridge/event,OHOS 端必须逐字保持一致。
六、用 NetConnection 查询和监听默认网络
方法 getCurrentType 通过 hasDefaultNetSync()、getDefaultNetSync() 和 getNetCapabilitiesSync() 读取当前默认网络。实现按 Wi-Fi、蜂窝、以太网和其他类型映射;没有默认网络或无效 netId 返回 0。
监听端使用无 specifier 的 createNetConnection(),对应系统默认网络。注册成功后立即调用 emit(),因此新订阅会得到首值。netAvailable、netLost、netUnavailable 和 netCapabilitiesChange 到达时都重新查询当前默认网络,而不是直接根据回调名称猜状态。这能处理旧网络丢失与新网络成为默认值几乎同时发生的情况。
typescript
const changed = (): void => this.emit(session);
session.monitor.on('netAvailable', changed);
session.monitor.on('netLost', changed);
session.monitor.on('netUnavailable', changed);
session.monitor.on('netCapabilitiesChange', changed);
每个 Subscription 保存最后一个类型,相同值不重复发送。取消时清空当前 session 和 sink;如果取消发生在异步注册完成之前,晚到的注册回调会立即注销旧 monitor,不能串入下一次订阅。系统查询失败通过 network_query_failed 或 network_observation_failed 上抛,不伪造成 none。

图 5:默认网络查询、事件重查、去重和订阅生命周期的生产代码。
ohos/src/main/module.json5 只增加实际需要的权限:
json5
"requestPermissions": [
{ "name": "ohos.permission.GET_NETWORK_INFO" }
]
这个库不主动发起网络请求,因此不需要为插件本身声明 INTERNET。
七、测试、构建与交付
适配分支新增 OHOS HAR、示例宿主、双语说明、Dart/Widget 契约测试和 ArkTS 生产源码测试。签名文件、SDK 路径、依赖缓存和 HAP 构建产物不进入仓库。
shell
flutter pub get
flutter analyze
flutter test
node --test ohos/test/network_status_bridge.test.cjs
cd example
flutter analyze
flutter test
flutter build hap --debug --no-codesign
8 项 Dart、3 项 Widget、15 项 ArkTS 共 26 项通过。测试覆盖五类映射、越界值、查询失败、首值、去重、注册失败、取消早于注册、旧回调隔离、注销失败和 Engine 重绑。

图 6:静态检查无问题,26 项自动化功能测试通过。

图 7:无签名 HAP 的实际元数据、摘要和受测提交。
八、通过固定 SHA 做真机验证
当前尚无 OHOS TAG,业务项目应锁定完整提交:
yaml
dependencies:
network_status_bridge:
git:
url: https://atomgit.com/oh-flutter/network_status_bridge.git
ref: 3650e53a67afe9720c03b429177c2967e0a77b19
隔离宿主最初使用本地 path 对受测源码构建、签名和安装;提交前只清理了行尾空格,没有功能变化。真机读取当前默认网络为 Wi-Fi,订阅得到 Wi-Fi 首值,取消后重新订阅再次得到 Wi-Fi,三项检查全部通过。后续文章补图又复现了 1 -> 1 -> 2 的事件数变化。

图 8:真机成功项和未覆盖的外部网络切换边界。
本轮没有关闭 Wi-Fi、插拔蜂窝网络或制造真实离线,因此不能从两次 Wi-Fi 首值推断变化事件在所有系统场景都已验收。更重要的是,网络接口存在只说明可以尝试请求,不代表互联网或目标服务一定可达。
应用内补拍:手动刷新

图 9:手动刷新后页面仍读取到 Wi-Fi,并保留当前监听状态和首值事件记录。
九、FAQ
Q1:为什么 netLost 不能直接发送 none
- 现象: 旧默认网络丢失时,新默认网络可能已经可用。
- 原因: 回调描述的是某条网络变化,不一定代表设备此刻没有默认网络。
- 解决方法: 每次回调重新查询默认网络并按最新 capabilities 映射。
- 验证结果: ArkTS 测试覆盖"旧网络丢失时新网络已成为默认"的场景。
Q2:为什么刚订阅就收到一条事件
- 现象: 用户没有切换网络,事件计数已经是 1。
- 原因: 上游契约要求订阅注册成功后发送当前首值,便于页面立即得到状态。
- 解决方法: 把第一条视为状态快照;如只关心变化,可在业务层保存基线后比较。
- 验证结果: 真机两次订阅都收到 Wi-Fi 首值,行为一致。
Q3:Wi-Fi 是否说明互联网正常
- 现象: 插件返回
wifi,业务请求仍可能失败。 - 原因: 本库只读取默认网络承载类型,不探测 DNS、网关或服务端。
- 解决方法: 业务请求仍需超时、重试和错误处理;需要可达性时单独做目标服务探测。
- 验证结果: 本文明确未做外部互联网可达性验收。
十、总结
network_status_bridge 0.0.5 的 OHOS 适配保留原有两个 Dart 入口,用 NetConnection 补齐默认网络查询和变化流,并重点处理了首值、去重、晚到注册和解绑清理。26 项自动化、HAP 构建以及 Wi-Fi 查询、取消和重订阅真机验证已经通过。
当前结论不覆盖真实 Wi-Fi/蜂窝/离线切换、VPN 和其他设备。正式使用时锁定受测 SHA,并把"网络类型"和"服务可达"当成两层不同信号。
十一、参考链接
欢迎加入CPF-Flutter 鸿蒙社区:https://atomgit.com/CPF-Flutter