Flutter 3.47 鸿蒙三方库适配实战:从 0 到 1 处理 flutter_blue_classic
Flutter 3.47 鸿蒙三方库适配实战:从 0 到 1 处理 flutter_blue_classic
经典蓝牙(Bluetooth Classic)是打印机、POS 机、车载设备等外设的主要连接方式,与 BLE 是两套不同的协议栈。flutter_blue_classic 封装了设备发现、配对、RFCOMM 连接与数据读写。把它带到鸿蒙时,适配面既有方法通道也有事件流。
本文以 flutter_blue_classic 0.1.1 为例,记录我如何保留原有 Dart API、补齐 Flutter OH 插件入口、在鸿蒙端接入真实系统能力,并在 HarmonyOS API 26 真机上完成构建、安装、启动和按钮调用验证。
适配仓库: oh-flutter/flutter_blue_classic
适配分支: feat/ohos_flutter_blue_classic_0.1.1
适配 TAG: 0.1.1-ohos.2
一、先看最终效果

图 1:HarmonyOS API 26 真机启动 Demo。页面显示 flutter_blue_classic 0.1.1。

图 2:点击“读取适配器状态”后返回 BluetoothAdapterState.on——EventChannel 推送的真实蓝牙开关状态。
| 验证点 | 实测结果 | 证据 |
|---|---|---|
| Flutter OH 3.47 工程构建 | 通过 | entry-default-signed.hap |
| 安装、启动(真机) | 通过 | 图 1 |
adapterState | EventChannel 推送真实状态 on | 图 2 |
| 通道名 | 修正为 blue_classic/* | 代码 |
二、这个库原来是怎么工作的
这条库的通道结构是方法 + 多条事件流:
Dart FlutterBlueClassic
-> MethodChannel('blue_classic/methods') # 命令面
-> EventChannel('blue_classic/adapterState') # 适配器状态流
-> EventChannel('blue_classic/discoveryState') # 扫描状态流
-> EventChannel('blue_classic/scanResults') # 扫描结果流
-> Android BluetoothAdapter / iOS ExternalAccessory
命令面包括 isSupported、isEnabled、getAdapterState、startScan、stopScan、bondDevice、connect、write 等。
三、实际环境
Flutter 鸿蒙环境搭建不在本文重复展开,直接参考 Flutter OH 环境搭建指南。
| 组件 | 版本 |
|---|---|
| Flutter OH | 3.47.4-ohos-1.0.4 |
| Dart | 3.13.3 |
| DevEco Studio | 26.0.0 Release |
| HarmonyOS SDK | API 26 |
| 测试设备 | 华为畅享 90 Pro Max,HarmonyOS 7.0.0.105(API 26) |
| 目标库 | flutter_blue_classic 0.1.1 |
flutter --version
hdc list targets
四、确认上游版本并同步到 AtomGit
上游包地址是 https://github.com/LenhartStephan/flutter_blue_classic,版本 0.1.1 使用 GPL-3.0 License。适配前我在 AtomGit 目标组织中搜索了同名库,没有找到可以直接使用的 OHOS 实现。
仓库适配提交为 e49f241,分支与 TAG 0.1.1-ohos.2 均指向该提交。
git clone https://atomgit.com/oh-flutter/flutter_blue_classic.git
cd flutter_blue_classic
git switch feat/ohos_flutter_blue_classic_0.1.1
git log --oneline -5
五、创建适配分支并检查工程结构
git switch -c feat/ohos_flutter_blue_classic_0.1.1
关键目录如下:
flutter_blue_classic/
├── lib/ # 原有 Dart API 和 MethodChannel
├── ohos/
│ ├── index.ets # OHOS 插件导出入口
│ └── src/main/ets/components/plugin/
│ └── FlutterBlueClassicPlugin.ets # 通道实现
├── example/lib/main.dart # 真机验证 Demo
├── example/ohos/ # Flutter OH 宿主工程
├── pubspec.yaml # 声明 ohos 平台
└── README.OpenHarmony_CN.md # 鸿蒙适配说明
pubspec.yaml 中的关键声明是:
flutter:
plugin:
platforms:
ohos:
pluginClass: FlutterBlueClassicPlugin
pluginClass 必须和 ohos/index.ets 导出的类名一致,否则 Dart 端能编译,运行时却不会注册插件。
六、适配过程:注册通道并对齐语义
通道名是这里最大的坑——不是 flutter_blue_classic:
| Dart 侧通道 | 类型 |
|---|---|
blue_classic/methods | MethodChannel |
blue_classic/adapterState | EventChannel |
blue_classic/discoveryState | EventChannel |
blue_classic/scanResults | EventChannel |
蓝牙状态用事件流:
onListen(args: Any, events: EventSink): void {
this.stateSink = events;
access.on('stateChange', this.onStateChange);
events.success(this.adapterStateName()); // 先推一次当前值
}
private readonly onStateChange = (state: access.BluetoothState): void => {
this.stateSink?.success(this.adapterStateNameOf(state));
};
| 方法 | OpenHarmony 实现 |
|---|---|
adapterState / adapterStateNow / isEnabled | access.getState() + stateChange 事件 |
bondedDevices | connection.getPairedDevices() + getRemoteDeviceName() |
bondDevice | connection.pairDevice() |
startScan / turnOn | 平台限制(经典蓝牙发现/开关未开放) |
七、构建配置与签名
示例工程的目标 SDK 对齐到 26,与 @ohos/flutter_ohos 的最低要求一致:
{
"name": "default",
"compatibleSdkVersion": "26.0.0",
"targetSdkVersion": "26.0.0",
"runtimeOS": "HarmonyOS"
}
Demo 的 AppScope/app.json5 统一成 com.example.flutter_oh_demo,与 DevEco 调试签名对应。证书、p12、p7b 和密码没有提交到仓库,读者应在自己的 DevEco Studio 中生成调试签名。
八、通过 AtomGit 引入适配版
在另一个 Flutter OH 应用中使用时,建议锁定 TAG:
dependencies:
flutter_blue_classic:
git:
url: https://atomgit.com/oh-flutter/flutter_blue_classic.git
ref: 0.1.1-ohos.2
flutter pub get
然后在 pubspec.lock 检查 source: git、AtomGit 地址和 resolved-ref,确认没有解析到 pub.dev 的同名版本。
九、构建、安装和真机验证
cd example
flutter pub get
flutter analyze
flutter build hap --debug
hdc install -r build/ohos/hap/entry-default-signed.hap
hdc shell aa start -a EntryAbility -b com.example.flutter_oh_demo
构建输出为 ✓ Built build/ohos/hap/entry-default-signed.hap.,随后 hdc 报告安装成功并启动 Ability。真机上按本文的截图顺序逐一点击按钮完成验证。
十、适配结果和当前边界
蓝牙状态与配对已接入。限制如下:
- 经典蓝牙设备发现在鸿蒙公开 SDK 未对普通应用开放,
startScan/stopScan是安全无操作。 - 开关蓝牙需要
BLUETOOTH_SETTINGS(系统级),本实现不代用户切换系统开关,调用后直接回读当前状态。 - SPP 连接需要 RFCOMM socket,属系统级受限能力,本实现保留接口并在文档中标注。
十一、FAQ
Q1:适配器状态是怎么读取的?
- 现象: 通道名必须与 Dart 侧完全一致:
blue_classic/methods、blue_classic/adapterState等,写成flutter_blue_classic时调用无法命中。 - 解决方法: 按 Dart 源码注册
blue_classic/*四条通道,适配器状态用 EventChannel 先推一次当前值、再跟随stateChange事件。 - 验证结果: 真机返回
BluetoothAdapterState.on。
Q2:设备发现能力怎么处理?
- 现象: 经典蓝牙设备发现在鸿蒙上不开放给三方应用。
- 解决方法: 需要发现设备时改用 BLE 扫描(
@ohos.bluetooth.ble);本库的已配对设备查询不受影响。 - 验证结果: 已配对设备列表真机读取成功。
Q3:三条事件流分别负责什么?
- 现象:
adapterState承载蓝牙开关状态,discoveryState/scanResults服务于设备发现。 - 解决方法: 状态展示依赖 adapterState;发现类功能待平台开放后在同一条 EventChannel 上补齐。
- 验证结果: adapterState 真机实时推送验证通过。
十二、总结
flutter_blue_classic 0.1.1 已接入鸿蒙的蓝牙状态与配对能力:用 @ohos.bluetooth.access 读取开关状态并通过 EventChannel 实时推送,用 connection 查询配对设备与发起配对。经典蓝牙发现与 SPP 连接受平台限制。
十三、参考资料和仓库地址
- 适配仓库主页
- 适配分支
- 适配 TAG
- 最终提交 e49f241
- ArkTS 通道实现
- 鸿蒙适配说明
- pub.dev 包页面
- pub.dev 0.1.1 版本页
- 上游仓库
- Flutter 官方插件与平台通道文档
- Flutter OH 鸿蒙 SDK 仓库
- HarmonyOS 开发者官方文档
欢迎加入CPF-Flutter 鸿蒙社区:https://atomgit.com/CPF-Flutter
更多推荐



所有评论(0)