flutter_qiblah 是一个方向指示库:它把系统罗盘的朝向和当前位置合并,计算出目标方位角。这类库的适配很有意思——它自己的代码里几乎没有原生逻辑,一切都委托给两个上游依赖:flutter_compass_v2 读罗盘,geolocator 读位置。把它带到鸿蒙时,真正决定成败的不是 flutter_qiblah 本身,而是这两个依赖在鸿蒙上的可用性。

本文以 flutter_qiblah 3.2.0 为例,记录我如何补齐插件注册、在 HarmonyOS API 26 模拟器上完成构建、安装、启动和入口调用验证,并给出这条链路在鸿蒙上的实际边界:依赖链中的 geolocator 没有提供 OHOS 实现,所以定位状态查询在鸿蒙上会走到“通道未实现”的真实错误,而不是一个假的结果。

适配仓库: oh-flutter/flutter_qiblah

适配分支: feat/ohos_flutter_qiblah_3.2.0

适配 TAG: 3.2.0-ohos.1

一、先看最终效果

图 1:HarmonyOS API 26 模拟器启动 Demo。页面显示插件返回的 OpenHarmony 3.47.4,状态为等待操作。

图 2:点击“检查传感器支持”后的真实结果。androidDeviceSensorSupport 在非 Android 平台按 Dart 层逻辑返回 true。

验证点实测结果证据
Flutter OH 3.47 工程构建通过entry-default-signed.hap
签名、安装和启动通过图 1
getPlatformVersion返回 OpenHarmony 3.47.4图 1
androidDeviceSensorSupport返回 true图 2
定位状态查询走 geolocator 通道图 3
真实罗盘与定位流依赖上游依赖的 OHOS 实现适配边界

图 3:调用“查询定位状态”后,页面显示 MissingPluginException:flutter.baseflow.com/geolocator 通道上没有实现。这是依赖链的真实返回,证明定位能力尚未接入 OHOS。

二、这个库原来是怎么工作的

flutter_qiblah 的 Dart 层设计是这样的:

Dart FlutterQiblah
  -> MethodChannel('ml.medyas.flutter_qiblah')   # 传感器能力检查(仅 Android)
  -> flutter_compass_v2(罗盘事件流)
  -> geolocator(位置与权限)
  -> 合并计算 QiblahDirection

它自己的 androidDeviceSensorSupport 只在 Android 平台走 MethodChannel,其他平台直接返回 true:

/// Check Android device sensor support
static Future<bool?> androidDeviceSensorSupport() async {
  if (Platform.isAndroid)
    return await _channel.invokeMethod("androidSupportSensor");
  else
    return true;
}

真正的功能入口 qiblahStream 是个组合流:把罗盘事件流和位置流合并后计算方位角。也就是说,在这条库上做鸿蒙适配,“插件注册”只能解决通道层,功能层取决于 flutter_compass_v2 和 geolocator 是否声明了 OHOS 平台。我核对过依赖:geolocator 14.x 目前提供 Android、Apple、Linux、Web 实现,没有 OHOS 实现。这就是本文边界的来源。

三、实际环境

Flutter 鸿蒙环境搭建不在本文重复展开,直接参考 Flutter OH 环境搭建指南。

组件版本
Flutter OH3.47.4-ohos-1.0.4
Dart3.13.3
DevEco Studio26.0.0 Release
HarmonyOS SDKAPI 26
测试设备DevEco 模拟器 Pura X View(HarmonyOS 7.0.0.105,API 26)

本次验证使用 DevEco Studio 26.0.0 自带的 Pura X View 模拟器,系统版本与目标真机同为 HarmonyOS 7.0.0.105 / API 26;HAP 的签名、安装与启动链路和真机一致。
| 目标库 | flutter_qiblah 3.2.0 |

四、确认上游版本并同步到 AtomGit

上游包地址是 GitHub medyas/flutter_qiblah,版本 3.2.0 使用 MIT License。适配前我在 AtomGit 目标组织中搜索了同名库,没有找到可以直接使用的 OHOS 实现。

仓库初始适配提交为 8622a85,完成后分支最新提交为 1aef639。

git clone https://atomgit.com/oh-flutter/flutter_qiblah.git
cd flutter_qiblah
git switch feat/ohos_flutter_qiblah_3.2.0
git log --oneline -5

五、创建适配分支并检查工程结构

git switch -c feat/ohos_flutter_qiblah_3.2.0

关键目录如下:

flutter_qiblah/
├── lib/
│   ├── flutter_qiblah.dart                     # 公共入口
│   ├── flutter_qiblah_method_channel.dart      # 平台接口通道 'flutter_qiblah'
│   └── src/flutter_qiblah.dart                 # 罗盘/定位组合流
├── ohos/
│   ├── index.ets                               # OHOS 插件导出入口
│   └── src/main/ets/components/plugin/
│       └── FlutterQiblahPlugin.ets             # 双通道实现
├── example/lib/main.dart                        # 上机验证 Demo
├── pubspec.yaml                                # 声明 ohos 平台
└── README.OpenHarmony_CN.md                    # 鸿蒙适配说明

六、适配过程:注册两个通道

这条库有两条通道需要注册:功能通道 ml.medyas.flutter_qiblah 和平台接口通道 flutter_qiblah。只注册功能通道的话,getPlatformVersion 探测在运行时拿不到注册。

onAttachedToEngine(binding: FlutterPluginBinding): void {
  this.channel?.setMethodCallHandler(null);
  this.channel = new MethodChannel(binding.getBinaryMessenger(), 'ml.medyas.flutter_qiblah');
  this.channel.setMethodCallHandler(this);
  this.platformChannel?.setMethodCallHandler(null);
  this.platformChannel = new MethodChannel(binding.getBinaryMessenger(), 'flutter_qiblah');
  this.platformChannel.setMethodCallHandler(this);
}

onDetachedFromEngine(binding: FlutterPluginBinding): void {
  this.channel?.setMethodCallHandler(null);
  this.channel = null;
  this.platformChannel?.setMethodCallHandler(null);
  this.platformChannel = null;
}

方法映射如下:

Dart 入口OHOS 本次策略
getPlatformVersion返回 OpenHarmony 3.47.4
androidSupportSensor返回 true(作为能力检查入口)
qiblahStream依赖 flutter_compass_v2 与 geolocator 的 OHOS 实现
checkLocationStatus依赖 geolocator 的 OHOS 实现
onMethodCall(call: MethodCall, result: MethodResult): void {
  switch (call.method) {
    case 'getPlatformVersion':
      result.success('OpenHarmony 3.47.4');
      return;
    case 'androidSupportSensor':
      result.success(true);
      return;
    default:
      result.notImplemented();
  }
}

Demo 侧我把原本的多页罗盘/地图演示收敛成一个验证页:平台版本、传感器入口、定位状态三个部分。定位状态按钮调用 FlutterQiblah.checkLocationStatus(),它会走 geolocator 的权限与服务查询——在鸿蒙上这一步会暴露依赖链的真实状态(图 3),这比包一层 try-catch 隐藏错误更有诊断价值。

七、构建配置与签名

示例工程的目标 SDK 对齐到 26,AppScope/app.json5 统一成 com.example.flutter_oh_demo,与 DevEco 调试签名对应。

{
  "name": "default",
  "compatibleSdkVersion": "26.0.0",
  "targetSdkVersion": "26.0.0",
  "runtimeOS": "HarmonyOS"
}

八、通过 AtomGit 引入适配版

dependencies:
  flutter_qiblah:
    git:
      url: https://atomgit.com/oh-flutter/flutter_qiblah.git
      ref: 3.2.0-ohos.1

九、构建、安装和设备验证

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.,随后安装启动成功。模拟器上先看到图 1(平台版本),点击“检查传感器支持”得到图 2,点击“查询定位状态”得到图 3。

十、适配结果和当前边界

层次已完成内容尚未完成内容
Dart API保留全部公开接口无
MethodChannel功能通道与平台通道双注册无
OHOS 插件注册、版本查询、传感器检查入口罗盘与定位的原生实现
依赖链已核对 geolocator 无 OHOS 实现flutter_compass_v2 的 OHOS 传感器接入
DemoAPI 26 模拟器启动与入口验证真实方位角计算

要让这条链路在鸿蒙上完整工作,需要两步:一是为 geolocator 提供 OHOS 定位实现(或替换为鸿蒙定位插件),二是为 flutter_compass_v2 接入 OHOS 方向传感器。在那之前,flutter_qiblah 的鸿蒙适配停留在“契约完整、依赖链边界明确”的状态。

十一、FAQ

Q1:为什么“检查传感器支持”返回 true?

  • 现象: 鸿蒙模拟器上 androidDeviceSensorSupport 返回 true。
  • 原因: 这条库的 Dart 实现只在 Android 走通道查询,其他平台无条件返回 true,鸿蒙端遵循同一逻辑。
  • 解决方法: 把返回值理解为“进入功能流的前置入口”,真实可用性以 qiblahStream 是否产出数据为准。
  • 验证结果: 图 2 显示返回 true,与上游代码路径一致。

Q2:定位状态查询为什么没有给出具体权限值?

  • 现象: 点击“查询定位状态”后显示的是依赖链的返回,而不是一个权限枚举。
  • 原因: geolocator 14.x 没有 OHOS 实现,权限查询在鸿蒙上没有原生承载。
  • 解决方法: 后续为依赖提供 OHOS 实现后,这同一个调用会直接返回真实权限状态,Demo 不需要改。
  • 验证结果: 图 3 是当前代码路径的真实返回。

Q3:为什么要注册两个通道?

  • 现象: 只注册 ml.medyas.flutter_qiblah 时,平台接口探测拿不到注册。
  • 原因: FlutterQiblahPlatform 的 getPlatformVersion 声明在 flutter_qiblah 通道上。
  • 解决方法: onAttachedToEngine 中同时注册两条 MethodChannel。
  • 验证结果: 图 1 显示平台版本读取成功。

十二、总结

这次适配为 flutter_qiblah 3.2.0 补齐了 OHOS 插件注册(功能通道 + 平台接口通道),保留了全部 Dart 接口,并核对了它的依赖链在鸿蒙上的实际状态。Demo 通过 Flutter OH 3.47.4 构建成签名 HAP,在 HarmonyOS API 26 模拟器上完成安装、启动和入口验证。

这次适配的结论不是“完成了方向指示”,而是“把方向指示的瓶颈定位到了依赖链”:下一步工作应该落在 geolocator 的 OHOS 实现和方向传感器接入上,而不是继续在 flutter_qiblah 本身上加代码。适配代码和说明都在 AtomGit 适配分支,复现时建议锁定 3.2.0-ohos.1 TAG。

十三、参考资料和仓库地址

欢迎加入CPF-Flutter 鸿蒙社区:https://atomgit.com/CPF-Flutter

Logo

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

更多推荐