Flutter 鸿蒙插件适配实战:用 app_version_details 1.0.3 读取版本号与包名
适配仓库: https://atomgit.com/oh-flutter/app_version_details
适配 TAG: 尚未发布,当前请锁定受测提交受测提交:
f161b93e3c484aecf8a8910b22a64827dff71bf3
一、最终效果与适配目标
关于页、问题反馈、升级提示和日志上报都要显示应用版本。app_version_details 1.0.3 提供完整版本、版本名、构建号和包名,但原生实现没有覆盖 OHOS。最容易犯的错误是返回插件自身版本,或者把示例工程清单里的静态值硬编码到插件里。
这次适配从系统读取当前宿主应用的 BundleInfo。同一个插件装进不同应用,必须返回各自已安装包的真实 versionName、versionCode 和 bundle name。Flutter 构建还可能根据宿主 pubspec.yaml 覆盖 AppScope 里的版本值,因此最终判断依据应是设备已安装元数据。

图 1:真机宿主显示完整版本、名称、构建号和包名。
| 验证点 | 实测结果 | 证据 |
|---|---|---|
| 四个公开 API | 完整版本、版本名、构建号和包名互相一致 | 图 1、图 6 |
| 系统元数据对照 | 两轮读取均与 bm dump 一致 | 图 6 |
| 重复读取 | 每轮额外读取 5 次,结果稳定 | 图 6 |
| 自动化与构建 | 23 项 Dart/Widget/ArkTS 功能测试及 HAP 构建通过 | 图 4、图 5 |
| 验证边界 | 结论针对已安装宿主元数据,不把构建前静态清单当成真机事实 | 真机说明 |
成果速览
| 项目 | 内容 |
|---|---|
| 上游基线 | 1.0.3 对应提交 ee25940295f5106fa15de0255bfdb3d5a0ab35b0,Apache-2.0 |
| 适配分支 | feat/ohos_app_version_details_1.0.3 |
| 适配 TAG | 尚未发布 |
| 真机受测提交 | f161b93e3c484aecf8a8910b22a64827dff71bf3 |
| 当前远程 HEAD | 81c7d18bd0188a152925fa38b16c41b37a6a13a8,后续只更新设备验证文档 |
| 新增 OHOS 能力 | 读取宿主完整版本与 bundle name,隔离旧 Engine 异步回调 |
| 真机结论 | 四个 Dart API 与已安装 bundle 元数据对照通过 |
二、本次环境
| 项目 | 实测版本 |
|---|---|
| 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 |
| 目标库 | app_version_details 1.0.3 |
环境安装直接参考 Flutter OH 环境搭建指南。截至 2026 年 9 月 12 日,版本号最大的 Flutter OH 标签是预览版 3.44.9+ohos-0.0.1-canary1,最新正式稳定标签仍是 3.41.10-ohos-1.0.1。本文保留真正完成插件构建和真机回归的稳定版,不把未经同等验证的预览版写成实测环境。
三、仓库基线与分支
上游没有 1.0.3 标签,本次以提交 ee25940295f5106fa15de0255bfdb3d5a0ab35b0 为基线,并核对公开 Dart 入口与 1.0.3 发布包一致。Apache-2.0 许可证和历史完整保留。选库前检查清单及实时组织仓库,没有发现同包名适配。
git clone https://atomgit.com/oh-flutter/app_version_details.git
cd app_version_details
git switch feat/ohos_app_version_details_1.0.3
git remote -v
分支及平台骨架复现:
git switch -c feat/ohos_app_version_details_1.0.3 ee25940295f5106fa15de0255bfdb3d5a0ab35b0
flutter create --template=plugin --platforms=ohos --no-pub .
模板中的示例类名和通道随后改回原项目定义。图 2 汇总了实际 AtomGit origin、适配分支和 HEAD,可核对仓库来源与当前分支状态。

图 2:AtomGit origin、适配分支和当前 HEAD。
四、四个 Dart API 实际只有两个原生读取
final details = AppVersionDetails();
final version = await details.getVersion();
final packageName = await details.getPackageName();
final versionName = await details.getVersionName();
final buildNumber = await details.getBuildNumber();
通道 app_version_details 只有 getAppVersion 和 getPackageName 两个原生方法。getVersionName() 与 getBuildNumber() 沿用 Dart helper,从 1.2.3+456 中拆分,不需要在 OHOS 再增加一套逻辑。保持这条调用链能避免四个接口读取出互相矛盾的版本。
五、读取 BundleInfo 并隔离旧引擎请求
在 pubspec.yaml 注册 AppVersionDetailsPlugin 后,生产 ArkTS 调用:
const info = await bundleManager.getBundleInfoForSelf(0);
if (call.method === 'getAppVersion') {
result.success(`${info.versionName}+${info.versionCode}`);
} else {
result.success(info.name);
}
真实代码还校验 versionName 非空、versionCode 为非负安全整数、bundle name 非空。无效元数据和系统异常返回 ERROR,未知方法返回 notImplemented,不会用伪造默认值掩盖原生失败。
系统查询是异步的。插件在 Engine attach 时递增 generation,请求发起时保存当前值;查询回来后如果 generation 已变,返回 UNAVAILABLE。这样旧引擎发起的读取不会在重绑后被当成新引擎数据。
读取自身 bundle 信息不需要额外权限。返回的是宿主,不是插件 HAR 的包名和版本。
完整版本用 versionName+versionCode 拼接时,分隔符也属于原 API 契约。版本名本身如果包含业务后缀,Dart helper 仍按既有规则解析;OHOS 端不应自行改成点号、括号或本地化格式,否则同一套 Flutter 代码会在平台间得到不同结构。

图 3:BundleInfo 读取、引擎代次隔离与版本字符串组装。
六、交付文件
适配保留全部 lib/、Android/iOS 代码、Apache-2.0 LICENSE 和上游历史;新增 OHOS HAR、example/ohos/、双语 OpenHarmony 文档、Dart/Widget 测试、生产 ArkTS 测试及设备入口。示例会一次展示四项值,并允许错误后重试。
本地签名、证书、SDK 路径、Node 依赖、生成元数据和 HAP 全部排除。目标仓库没有现成 README.OpenSource 要求,因此没有创建空占位文件。
七、测试与构建
flutter pub get
flutter analyze
flutter test
npm install --prefix ohos/test --no-save --no-package-lock typescript@5.9.3
node --test ohos/test/app_version_details.test.cjs
cd example
flutter test
flutter build hap --debug --no-codesign
9 项 Dart、2 项 widget 和 12 项实际 ArkTS 功能测试通过,共 23 项;另有 1 项重复回复夹具自检,不计为插件功能测试。静态分析无问题,无签名 HAP 构建成功。测试覆盖格式、零值和大版本号、空元数据、系统错误、新鲜读取、未知方法及引擎重绑。
真机代码固定为 f161b93e3c484aecf8a8910b22a64827dff71bf3,之后 81c7d18 只更新设备文档。

图 4:Flutter 复跑与 23 项 Dart/ArkTS 功能用例统计。

图 5:HAP 元数据及真机宿主锁定提交。
八、真机与 bm dump 交叉核对
dependencies:
app_version_details:
git:
url: https://atomgit.com/oh-flutter/app_version_details.git
ref: f161b93e3c484aecf8a8910b22a64827dff71bf3
执行 flutter pub get 后应核对 pubspec.lock 的 resolved-ref。当前没有适配 TAG,因此示例固定到真机实际使用的代码提交,避免分支后续变化导致构建漂移。
隔离宿主在同一 PID 中执行两轮,均得到:完整版本 1.0.0+1、版本名 1.0.0、构建号 1、包名 com.example.flutter_oh_demo,每轮额外重复读取 5 次也保持一致。随后使用 hdc shell bm dump -n com.example.flutter_oh_demo 独立查询,系统安装信息中的名称、versionName=1.0.0 和 versionCode=1 完全一致。
预验收曾错误期待 AppScope 静态值 1000000,因此失败。独立 bm dump 证明 Flutter 构建按宿主 pubspec.yaml 把安装版本覆盖成 1,插件返回是正确的。修正的是宿主断言,不是为了让测试通过而改插件返回值。
这次失败反而补上了一个必要的验收原则:先从系统取得事实,再写断言。若先相信源码清单,测试可能稳定失败;若直接迁就插件返回值,又会失去独立对照。bm dump 让两者有了第三方基线。

图 6:两轮插件读取与 bm dump 安装元数据对照。
应用内多状态补拍

图 7:app_version_details 1.0.3 首次读取宿主完整版本、Bundle Name、版本名和构建号。

图 8:点击刷新后进入第 2 次读取,时间更新,四项版本数据与一致性检查结果保持不变。
九、提交与远端状态
git status --short
git add pubspec.yaml ohos example test README.OpenHarmony.md README.OpenHarmony_CN.md
git commit -m "feat: add OHOS support for app_version_details"
git push -u origin feat/ohos_app_version_details_1.0.3
仓库公开,默认分支为适配分支。2026 年 9 月 12 日匿名读取 HEAD 为 81c7d18bd0188a152925fa38b16c41b37a6a13a8。该 HEAD 在受测代码之后只增加设备验证文档,本文的依赖仍锁定真机受测提交。
十、FAQ
Q1:为什么返回 1.0.0+1,不是 AppScope 中的版本号
- 现象: 构建前静态清单与真机结果不同。
- 原因: Flutter 构建会依据宿主
pubspec.yaml覆盖安装包版本。 - 解决方法: 以已安装 bundle 的
bm dump为验收基线。 - 验证结果: 插件两轮结果与系统安装信息一致。
Q2:getVersionName 和 getBuildNumber 为什么不再调用原生
- 现象: 四个公开接口只见两个通道方法。
- 原因: 上游已在 Dart 层从完整版本拆分名称与构建号。
- 解决方法: 保留 helper,避免平台重复实现。
- 验证结果: 四项值在真机上互相一致。
Q3:原生失败时 helper 的默认值会生效吗
- 现象: 业务期待失败后得到默认版本。
- 原因: helper 只对原生成功返回 null 的情况有默认值,平台异常仍向上传播。
- 解决方法: 调用方捕获
PlatformException并明确展示未知状态。 - 验证结果: Dart 与 ArkTS 测试都覆盖错误传播。
十一、总结
app_version_details 已能在 Flutter 鸿蒙应用中读取真实宿主版本和 bundle name,Dart helper 继续提供版本名与构建号。23 项功能测试、HAP 构建、两轮真机读取及 bm dump 对照形成了完整证据。预验收失败也说明,版本测试必须看最终安装元数据,不能迷信构建前静态文件。
十二、参考链接
欢迎加入CPF-Flutter 鸿蒙社区:https://atomgit.com/CPF-Flutter
更多推荐


所有评论(0)