Flutter 鸿蒙插件适配实战:用 flutter_device_name 0.0.3 读取用户设备名称
适配仓库: https://atomgit.com/oh-flutter/flutter_device_name
适配分支:
feat/ohos_flutter_device_name_0.0.3受测提交:
fdd0d8eb565f5b21aed9dd33f24b9b7483285c5d
一、最终效果与适配目标
flutter_device_name 的目标不是读取产品型号,而是读取用户在系统中看到和设置的设备名称。这个区别会直接影响设备列表、局域网发现和“在哪台设备登录”的提示。本次适配只补 OHOS 的 getDeviceName 实现,保持 DeviceName().getName() 的可空返回契约不变。

图 1:CHZ-AL00 / HarmonyOS 7.0.0.105 上读取到“华为畅享 90 Pro Max”,并显示真实读取时间。
| 验证点 | 实测结果 | 证据 |
|---|---|---|
| 公共 API | DeviceName().getName() 返回用户设备名称 | 图 1、图 6 |
| 独立原生对照 | 同一 UIAbility 直接查询 Settings,结果完全一致 | 图 6 |
| 空值与异常 | 空设置返回 null,系统失败显式上抛 | 自动化 |
| 生命周期 | 无 UIAbility 时返回 no_ability,重绑后恢复 | 自动化 |
| 自动化与构建 | 6 Dart + 8 ArkTS,共 14 项及 HAP 通过 | 图 4、图 5 |
成果速览
| 项目 | 内容 |
|---|---|
| 上游基线 | 0.0.3,提交 780cbd5c2be9df6d07f473415ff692abec32a945,BSD-3-Clause |
| 首次适配提交 | 991a086c7a278f07d4ceedefd583a5dd7eb7e788 |
| 真机修复提交 | fdd0d8eb565f5b21aed9dd33f24b9b7483285c5d |
| 新增 OHOS 能力 | 从 DEVICE_SHARED Settings 读取用户定义名称 |
| 保持不变的接口 | DeviceName.getName() 与 flutter_device_name 通道 |
| 真机结论 | 修复 Context 后与独立原生结果一致;系统重命名回环未覆盖 |
二、实测环境与基线
| 组件 | 实测版本 |
|---|---|
| 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 |
| 插件 | flutter_device_name 0.0.3 |
环境安装参考 Flutter OH 环境搭建指南。本文以稳定版 3.41.10-ohos-1.0.1 完成真机回归;更大版本号的 3.44.9+ohos-0.0.1-canary1 是预览版。
2026 年 9 月 11 日核对时,0.0.3 是 pub.dev 最新发布版,上游提交和发布源码一致,许可证为 BSD-3-Clause。目标组织与适配清单中未发现同包名 OHOS 实现后,我将上游历史同步到 AtomGit。
三、创建分支与工程结构
git clone https://atomgit.com/oh-flutter/flutter_device_name.git
cd flutter_device_name
git switch -c feat/ohos_flutter_device_name_0.0.3 780cbd5c2be9df6d07f473415ff692abec32a945
flutter create --template=plugin --platforms=ohos --no-pub .
模板生成的插件壳改为 FlutterDeviceNamePlugin,并保留上游通道 flutter_device_name。适配分支同时加入独立 example、Dart 契约测试、ArkTS 生产源码测试和双语文档。

图 2:AtomGit origin、适配分支、修复后的完整 HEAD 和干净工作区。
四、公共 API 很小,语义不能偷换
final DeviceName plugin = DeviceName();
final String? name = await plugin.getName();
返回 null 表示系统没有可用的用户设备名称。适配代码不能在这种情况下自动改用 deviceInfo.productModel,因为型号与用户定义名称是两种数据。也不能缓存结果,否则用户在系统设置中重命名后,下一次读取仍会得到旧值。
五、真机发现的 Context 问题
第一版实现用 ApplicationContext 调用 Settings。自动化和构建都通过,但真机返回 null,hilog 出现 Settings: helper is null。我随后在同一个宿主里用 UIAbilityContext 直接查询,能够正确读到名称。这说明问题不在设置项或权限,而在 Context 类型。
最终插件实现 AbilityAware,随 UIAbility 绑定保存上下文,并在解绑时清理:
onAttachedToAbility(binding: AbilityPluginBinding): void {
this.context = binding.getAbility().context;
}
onDetachedFromAbility(): void {
this.context = null;
}
const name = settings.getValueSync(
this.context,
settings.general.DEVICE_NAME,
'',
settings.domainName.DEVICE_SHARED,
);
result.success(name.length > 0 ? name : null);
无 UIAbility 时返回 no_ability,Engine 已解绑时返回 plugin_detached,系统查询异常返回 device_name_unavailable。这个插件无需新增权限。

图 3:UIAbilityContext、DEVICE_SHARED 域、空值和生命周期错误的最终实现。
六、修复后的测试与构建
flutter pub get
flutter analyze
flutter test
node --test ohos/test/device_name.test.cjs
cd example
flutter analyze
flutter build hap --debug --no-codesign
6 项 Dart 和 8 项 ArkTS 共 14 项通过。原生测试包含 Unicode 名称、空值、不缓存、系统异常恢复、未知方法、Engine 重绑、无 Ability、Ability 解绑与重新绑定。Context 修复后重新执行静态检查和无签名 HAP 构建。

图 4:Context 修复后的 14 项自动化和静态检查结果。

图 5:修复版 HAP、SHA-256 和远程依赖提交。
七、固定修复提交并真机复验
dependencies:
flutter_device_name:
git:
url: https://atomgit.com/oh-flutter/flutter_device_name.git
ref: fdd0d8eb565f5b21aed9dd33f24b9b7483285c5d
隔离宿主的 pubspec.lock 确认解析到修复提交,签名 HAP 构建和覆盖安装通过。第二轮真机中,公开 API 返回“华为畅享 90 Pro Max”,同一 UIAbility 通过独立原生通道读取到完全相同的文本,基础探测通过。

图 6:第一次失败原因、修复提交以及公开 API 与独立 Settings 查询的一致结果。
本轮没有修改系统设备名再改回,因此只证明当前值读取正确;名称变化时不缓存的行为由自动化覆盖,真实重命名回环仍需单独验收。
应用内补拍:插件与原生对照

图 7:插件公开 API、DEVICE_SHARED、默认域和独立原生读取结果一致。

图 8:刷新后再次读取同一设备名称,读取时间更新且对照结果仍为“一致”。
八、FAQ
Q1:为什么不能使用 ApplicationContext
- 现象: 方法正常返回,但真机结果为空,系统日志显示 Settings helper 为空。
- 原因: 当前 Settings 查询需要 UIAbilityContext,ApplicationContext 不满足调用上下文要求。
- 解决方法: 实现
AbilityAware,在 Ability attach/detach 时保存和清理 UIAbilityContext。 - 验证结果: 修复后 8 项 ArkTS 回归、HAP 构建和真机独立对照通过。
Q2:名称为空时为什么不返回产品型号
- 现象: 业务希望任何设备都显示一段非空文本。
- 原因: 本库契约是用户定义名称,产品型号不是同一字段。
- 解决方法: 插件保留
null;业务层可明确显示“未设置”,如确需型号应接入设备信息 API。 - 验证结果: 空设置返回 null 和 Unicode 名称保真均有自动化覆盖。
Q3:为什么每次都重新读取
- 现象: 看起来可以缓存名称减少通道调用。
- 原因: 用户可以在系统设置中重命名,缓存会返回过期值。
- 解决方法: 每次业务刷新时调用
getName(),页面异步返回后检查mounted。 - 验证结果: 原生测试修改模拟设置值后,下一次读取立即得到新名称。
九、总结
flutter_device_name 0.0.3 的 OHOS 适配最终只做一件事:用正确的 UIAbilityContext 从 DEVICE_SHARED Settings 读取用户设备名称,并如实处理空值和异常。首次真机失败促使 Context 路径得到修正;14 项自动化、HAP 构建及真机原生对照随后通过。
业务接入必须固定到 fdd0d8e... 修复提交,不能使用此前的首次适配 commit。系统重命名回环和其他设备仍是当前验证边界。
十、参考链接
欢迎加入CPF-Flutter 鸿蒙社区:https://atomgit.com/CPF-Flutter
更多推荐



所有评论(0)