个人助理APP · 阶段一

20分钟出原型 · 2小时踩6个坑 · 鸿蒙NEXT真机开发实战

鸿蒙 NEXT GPS/北斗 ArkTS UI 踩坑笔记 65%完成
▼ 往下翻

💡 初心

有了 AI 助手之后,一个大胆的想法冒了出来——

是不是可以写一个 APP,用于日常的查询、计算?我是测试工程师,可以在 APP 中增加 GPS 定位功能,显示当前位置、时间、速度、星座。还可以让 APP 覆盖一个人的日常需求, 从衣食住行到吃喝玩乐。以后自己再需要什么功能,就不用看烦人的广告,或者不小心 被摇一摇带到某个购物软件,或者暗自在后台偷偷下崽……

— 高昆,2026年6月24日

📱 真机预览

HUAWEI Mate 80 · HarmonyOS NEXT 6.1.0 · DevEco Studio · 真机运行效果

应用图标
📱 桌面图标
首页截屏
🏠 首页截屏
网页版预览
🖥 网页版原型预览
🔗 打开交互原型

在浏览器中模拟APP的完整交互体验

🎨 HTML 原型

提示词扔给 AI,20 分钟拿到可用网页。5 个 Tab 页面布局、Bento 网格、暖白配色。

🖥 从想法到可看只用了 20 分钟

AI 输出了一个完整的交互原型 HTML。琥珀橙(#D97706)做主题色,暖白底(#FFFBEB),圆角卡片,底部 5 个 Tab。

页面内容
🏠 首页问候语 + AI助理卡 + GPS/UTC/天气状态卡 + Bento网格
🛠 工具时间转换 + GPS卫星状态 + Ntrip差分
🌿 生活吃什么/喝什么/穿什么/住/运动/出行 六宫格
🎯 智趣AI对话 + 象棋/五子棋/围棋 + 音乐 + 视频 + 放松
👤 我的个人资料 + 口味/运动偏好 + Ntrip授权 + 隐私 + 关于

🔧 鸿蒙真机开发

手机接电脑 → 开发者模式 → DevEco Studio → 空项目 → AI 写 ArkTS 代码 → 真机运行。

📱 设备环境

手机HUAWEI Mate 80
系统HarmonyOS NEXT 6.1.0.125 SP9
IDEDevEco Studio
API12+
Bundlecom.gaokun.assistant

🐛 Bug 清单

真机调试中踩过的每一个坑,按发现顺序排列。

✅ 已修复Column 不支持 minHeight

Column 组件只有 height(),没有 minHeight()。换成 .height(110) 即可。

✅ 已修复@Provide 和 @State 不能叠加

同一变量不能同时用两个状态装饰器。用 @Provide('key') 显式 key,拆成独立变量。

✅ 已修复对象字面量不能作为类型声明

ArkTS 禁内联对象类型,必须用 interfaceclass

✅ 已修复@Provide/@Consume 在 TabContent 边界失效

数据在变,UI 不更新。这是最坑的一个,花了最多时间排查。

⏳ 待解决UTC 时钟不实时刷新

6 种方案全部阵亡。根因:TabContent 子页面的 @State 变更不触发重渲染。

⏳ 待解决GPS 卫星星数不更新

权限已授权、监听已注册,但星数始终 14 颗。和时钟同根因——后台数据变了 UI 不动。

🛰 GPS 血案

第 1 轮:以为有 API

geoLocationManager.on('satelliteStatusChange', ...) — 回调类型错误,编译不通过。

第 2 轮:改用模拟数据

每 3 秒随机抖动北斗 13~15 颗 + GPS 9~11 颗。编译过了但 BusinessError 201 —— 没运行时授权。

第 3 轮:查官方文档

回调是单对象 SatelliteStatusInfo,不是数组。字段是 satelliteConstellation。北斗枚举 = 5。

第 4 轮:加运行时权限弹窗

atMgr.requestPermissionsFromUser(this.context, [
  'ohos.permission.LOCATION',
  'ohos.permission.APPROXIMATELY_LOCATION'
]);

✅ 权限已授权!日志显示 "定位权限: 已授权✅" + "卫星监听已启动"。

第 5 轮:还是 14 颗星

所有前置条件都满足了,但星数不更新。高度怀疑 TabContent 内 @StorageLink 不触发 UI 刷新。

UTC 时钟:六种方案

#方案原理结果
1setInterval + @State组件内定时器更新不刷新
2哑计数器 + new Date()@State _t 每秒++,build() 里取时间不刷新
3@Provide/@ConsumeIndex 定时器 → 信号广播不刷新
4AppStorage + @StoragePropEntryAbility 定时器 → AppStorage不刷新
5AppStorage + @StorageLink双向绑定替换 @StorageProp不刷新
6EntryAbility 全局定时器最外层 UIAbility 推 AppStorage不刷新

🧠 根本矛盾

所有方案共用一个死穴:时钟显示在 Tabs→TabContent 子页面内。官方示例用 @Entry + Canvas,没有 TabContent 这层。TabContent 可能做了渲染优化导致子组件 @State 变更不触发重渲染。

📝 教训清单

2 小时,9 个源文件,6 次试错。以下是每条用时间换来的铁律。

01

@Provide 别跟 @State 叠

一个变量只用一个状态装饰器。显式 @Provide('key') 最稳。

02

对象字面量当类型 = 编译死

ArkTS 不走 JS 的松类型,必须 interfaceclass

03

Column 没有 minHeight

直接用 height()。编译器错误提示很准,读它。

04

权限 = 声明 + 运行时

module.json5 只是备案,还得 requestPermissionsFromUser 弹窗。

05

TabContent 是状态传播死角

@Provide/@Consume、AppStorage 全部失效。

06

鸿蒙 NEXT 资料少

文档有但散,API 回调容易写错,示例都是 @Entry 级别。

📊 当前进度

6 月 24 日晚,2 小时。跑通了不少,卡在了两个核心功能上。

功能状态备注
5 页 UI 骨架首页/工具/生活/智趣/我的,Tab 导航
全屏沉浸setWindowLayoutFullScreen + 安全区 48px
emoji TabBar🏠🛠🌿🎯👤,barHeight 62,选中琥珀色
Toast 交互所有卡片可点,promptAction.showToast
时间转换器Unix↔UTC↔GPS 周/秒
定位权限声明 + runtime 弹窗 = 已授权
GPS 监听注册satelliteStatusChange API 正确调用
UTC 实时刷新6 种方案全不行
GPS 数据显示根因和 UTC 相同

总体完成度

65%

从下决心到原型出来,20 分钟

从原型到满身 bug 的真机 App,1 小时

从一个 bug 到另一个 bug,又 1 小时

开发还会继续。可能换个平台、换个语言、换个方式。

但这 2 小时的折腾,值了。😤

← 返回