11 KiB
M1 静态页面验收记录
环境
- 记录日期:2026-09-10
- 构建版本:0.1.0 (versionCode 1)
- 构建机:Windows 11,JDK 17.0.12,Android SDK
D:\Android\Sdk - 验收设备:Android 模拟器(非真机)
- AVD
ringtest,外形pixel_7,镜像system-images;android-36;google_apis;x86_64 - 1080×2400 @ 420dpi;系统栏 inset:状态栏 136 px、导航栏 63 px
- AVD
本次与上一次记录的差别: 上一版这份文件里,人工验收整张表都是「未执行 —— 无设备」。 2026-09-10 当天下载并装好了模拟器(见文末「模拟器是怎么装上的」),因此下面这张表已经真的跑过了。 但仍有一处必须说清楚:跑的是模拟器,不是真机。模拟器能证明界面渲染正确、导航不崩, 但证明不了真机上的性能、厂商 ROM 差异、以及 M2 之后才涉及的蓝牙权限行为。
自动化验证(已执行)
- 单元测试:
./gradlew :app:testDebugUnitTest—— 21 项全绿 (FormattersTest7 +MockDataProviderTest5 +HomeViewModelTest1 +WorkoutViewModelTest1DeviceViewModelTest2 +MetricDetailViewModelTest3 +RoutesTest2)
- 构建:
./gradlew :app:assembleDebug——BUILD SUCCESSFUL, 产物app/build/outputs/apk/debug/app-debug.apk(18,907,725 字节) - 安装并启动:
adb install -r+am start—— 成功,进程存活,logcat -b crash全程为空 - 未执行:各页面的
@Preview在 Android Studio 中渲染。本机没有 IDE GUI 自动化手段, 这一项仍是未执行的 —— 不过它原本的作用(没有设备时唯一的界面检查手段)已被下面的模拟器实测取代
人工验收(模拟器实测,逐项已执行)
| 项 | 结果 | 证据 |
|---|---|---|
| 应用启动无崩溃 | ✅ | 进程 pid 存活,mCurrentFocus 为 MainActivity,crash buffer 空 |
| 四个 Tab 显示为 健康 / 运动 / 设备 / 我的 | ✅ | 四个 Tab 文案与图标正确,选中态为淡紫底 + 绿色文字 |
| 四个 Tab 可自由切换 | ✅ | 逐个点过,无闪烁、无崩溃 |
| 首页:设备状态条 | ✅ | 「RingHealth 智能戒指 · 已连接 / 电量 78%」 |
| 首页:步数大环 8,426 / 目标 10,000 | ✅ | 环按 84% 填充,另有「6.21 公里 / 327 千卡」 |
| 首页:六个指标卡,血压显示「未开启」 | ✅ | 心率 72 次/分、睡眠 7小时32分、血氧 98%、压力 34 正常、体温 36.5 °C、血压 未开启 |
| 首页:点指标卡进详情,标题为该指标中文名 | ✅ | 点「睡眠」→ 标题「睡眠」;点「心率」→ 标题「心率」 |
| 详情页:近 7 天 7 根柱 / 近 30 天 30 根柱 | ✅ | 切换后柱子数量与统计值都变了(心率:78.0/95.1/58.0 → 77.0/96.0/59.8) |
| 睡眠详情额外显示分期卡片,其他指标没有 | ✅ | 睡眠有「睡眠分期」卡(深睡/浅睡/清醒 + 入睡/起床),心率页没有该卡 |
| 睡眠入睡/起床时间读起来像「一晚」 | ✅ | 入睡 22:08 / 起床 06:08,正好相隔 8 小时(DEMO_SLEEP_WINDOW_MILLIS 生效) |
| 详情页:返回后回到首页 | ✅ | keyevent 4 后回到健康首页 |
| 运动页:开始运动 + 5 条记录 | ✅ | 5 条:户外跑步/健走/骑行/自由训练/户外跑步 |
| 运动页「查看全部」进历史页,底部导航栏仍可见 | ✅ | 历史页 5 条记录,底部四 Tab 正常显示 |
| 设备页:戒指卡片 电量 78% / 固件 1.0.5 | ✅ | 另显示「已连接」与蓝牙图标 |
| 设备页「更多设置」开关可切换,返回后状态保持 | ✅ | 打开「压力监测」→ 返回设备页 → 再进入,开关仍为开 |
| 我的页 | ✅ | 头像卡与分组入口正常 |
| 全程无崩溃 | ✅ | logcat -b crash 自始至终为空 |
补充实测:终审修复轮的六项改动
这六项原先只有代码阅读作为依据,现在逐项在模拟器上确认:
| 改动 | 实测结果 |
|---|---|
| 详情页按指标取色 | ✅ 睡眠=蓝、心率=红,与首页各卡的 tint 一致 |
| 血压卡不可点击 | ✅ 点血压卡后与点击前逐像素一致,未发生跳转 |
压力卡 unit 接线 |
✅ 卡片显示「34 正常」,即 stressLevelLabelRes 真的接上了 |
| 周/月 chips 常驻 | ✅ 两个范围的详情页都始终显示 chips |
consumeWindowInsets 顶栏内边距 |
✅ 量了像素:状态栏 136 px,顶栏白底 136→303 px,即正好 168 px = 64 dp(Material 3 TopAppBar 标准高度),标题文字中心在顶栏内 86 px ≈ 32 dp,正中。若 insets 被叠加,顶栏会变成 88 dp 且标题偏下 —— 实测不是 |
README 注明 installDebug 需设备 |
✅ 文档项 |
consumeWindowInsets这一项此前被反复标注「推理得出、未经设备验证」,现在验证过了。 顺带确认:状态栏上方那条灰带就是状态栏本身(136 px),不是多余留白。
本轮新发现的观察(非缺陷,记录备查)
- 设备设置页与运动历史页没有
TopAppBar,也就没有返回箭头 —— 标题(「功能设置」)是普通 标题文字。返回只能靠系统返回手势,或点底部「设备」Tab。功能上可用,但与详情页(有←) 不一致。是否补一个顶栏,留给 M2 一起定。 - 运动记录的日期随运行时间变化 —— 两次截图里同一批记录显示 06:08 与 06:10。 因为 Mock 的时间戳是相对「此刻」生成的。这削弱了设计文档 §8「每次运行截图一致」的说法: 数据形状是确定性的,但日期不是。若将来要做截图对比测试,需要连时间源一起固定。
- 趋势图把最后一根柱子画成深色(其余为其 30% 透明度)—— 这是有意的,
MetricBarChart(highlightLast = true)即「高亮今天」,KDoc 里写明了。 记录在此只是为了说明:实测看到的「只有最后一根是深色」不是渲染错误。
已知限制(阶段一有意为之)
- 数据全部为 Mock,不连蓝牙、不连后端
- 血压恒为「未开启」占位(
HealthSummary.bloodPressure = null) - 设备设置页的开关只改内存状态,重启即重置(对应 M2 的协议 0502/0504); 本次只验证了跨页面保持,没有验证跨进程重启
- 睡眠分期条与入睡/起床时间是演示值(固定比例 + 最后一个数据点往前 8 小时),无真实分期数据
- 详情页统计摘要一律保留一位小数(步数因此显示为「平均 7512.3」这类精度过剩的形式)
- 仅浅色模式
- 血压卡不可点击(
value == null时onClick传null) - 详情页的周/月切换常驻,空数据时只把切换条下方的图表与统计换成一行空态文案
仍然没有验证到的
- 详情页的空数据态:当前 Mock 恒返回 7 或 30 个点,该分支不可达,本次没有、也无法触达。 它仍然是只有代码推理保证的防御性代码。
- 旋转屏幕 / 深色系统设置下不崩溃:本次未测。
@Preview渲染:未测(见上)。- 真机:未测。模拟器不能替代真机验收。
与设计文档 §6 的偏差(有意收窄,非遗漏)
- 设备页少了四项:查找戒指(050B)、智能提醒/闹钟占位、固件升级占位(OTA 17xx)、佩戴检测。 阶段一没有真实协议可对接,摆一排点不动的入口不如不摆(ledger R27)。这些能力仍属产品范围, 将于后续里程碑回归;设计文档 §6 的设备页一行已用删除线标注。本次实测确认设备页确实没有这四项。
- 详情页由「四个专属设计」收敛为一个模板:四条路由合并为
detail/{metric},七个指标共用 同一模板。仅睡眠保留了专属区块。未实现的是:步数的大环、心率的折线/静息-运动区间、 血氧的正常范围说明文案。详见设计文档 §6 下的注记。
M2 接入时的已知接缝(交接用,本阶段不修)
RingDeviceRepository 目前不足以承载 M2 的设备控制:
refreshDeviceState()零调用者 —— 接口定义了,UI 从不触发。M2 需要接上「下拉刷新」或 进入设备页时刷新,否则真机断连后界面不会更新。setFunctionEnabled是非suspend的 —— Mock 只改内存态所以无所谓,但 M2 写向 BLE 必然是挂起操作,接口签名届时需要改,连带DeviceViewModel的调用点。- 预计 M2 的改动面:
domain/repository/Repositories.kt、data/mock/*、di/AppContainer.kt、AndroidManifest.xml(BLE 权限)、app/build.gradle.kts+gradle/libs.versions.toml(厂商 Java 依赖,很可能需要 Jetifier)、feature/device/DeviceScreen.kt。 完整清单见实施计划的「M2 交接提示」一节。
覆盖缺口声明(已大幅收窄,但仍非零)
M1 的运行时行为已在 Android 模拟器上完整走查过一遍(上表逐项打勾),不再是「只有编译期保证」。 但仍有三个缺口,不要把它们读成「已验证」:
- 跑的是模拟器不是真机 —— 真机上的厂商 ROM、性能、字体缩放、刘海/挖孔适配均未检验。
- 空数据态与旋转/深色模式未触达(见上)。
@Preview未渲染 —— 不过它原本的替代作用已被模拟器实测覆盖。
首次拿到真机时,请至少重跑上表中的「启动无崩溃」「四 Tab 切换」「详情页顶栏内边距」三项。
附:模拟器是怎么装上的(含一个踩过的坑)
本机原先 D:\Android\Sdk 下没有 emulator/ 也没有 system-images/,本次新装:
# 1) 装包(注意坑:见下)
/d/Android/Sdk/cmdline-tools/latest/bin/sdkmanager.bat \
--sdk_root=D:/Android/Sdk "emulator" "system-images;android-36;google_apis;x86_64"
# 2) 建 AVD(avdmanager 不认 --sdk_root,只认环境变量)
export ANDROID_SDK_ROOT='D:\Android\Sdk' ANDROID_AVD_HOME='D:\Android\avd'
echo no | /d/Android/Sdk/cmdline-tools/latest/bin/avdmanager.bat create avd \
-n ringtest -k "system-images;android-36;google_apis;x86_64" -d pixel_7
# 3) 启动
/d/Android/Sdk/emulator/emulator.exe -avd ringtest
坑:--sdk_root 一定要写正斜杠。 写成 D:\Android\Sdk 时,Git Bash 会把反斜杠吃掉,
变成 Windows 的盘符相对路径 D:AndroidSdk —— 这不是绝对路径,而是「D 盘当前目录下的
AndroidSdk」。结果 sdkmanager 把 5.3 GB 的包装进了 cmdline-tools\latest\bin\AndroidSdk\。
同盘移动是瞬时的,已搬回 D:\Android\Sdk\。在 Git Bash 里给 Windows 工具传路径,一律用正斜杠。
另外 ANDROID_AVD_HOME 已设为用户级变量 D:\Android\avd(AVD 镜像有几个 G,C 盘只剩 29 G)。