# M1 静态页面验收记录 ## 环境 - 记录日期:2026-09-10 - 构建版本:0.1.0 (versionCode 1) - 构建机:Windows 11,JDK 17.0.12,Android SDK `D:\Android\Sdk`(仅 `platform-tools` / `platforms;android-36` / `build-tools;36.1.0`) - **测试设备:无** —— 本机没有安装任何模拟器镜像,也没有连接真机 补充证据(说明「无设备」不是随口一说,而是逐项查过的): ``` $ ls D:\Android\Sdk build-tools cmdline-tools licenses platform-tools platforms # 没有 emulator/,也没有 system-images/ $ adb devices List of devices attached # 空列表,没有连接真机 ``` `C:\Users\10314\.android\avd\` 下**残留着两个 AVD 定义**(`Medium_Phone_API_36.1`、 `Pixel_9_Pro`),但它们是**不可用的空壳**:二者都指向已删除的旧 SDK `C:\Users\10314\AppData\Local\Android\Sdk`(其 `emulator\emulator.exe` 与 `system-images\android-36.1\google_apis_playstore\x86_64\` 均已不存在),且属于另一个项目 (`D:\work\xiangmu\mediq-app`)。**不要因为看到 AVD 目录就以为本机可以起模拟器。** 另注:当前 shell 的 `ANDROID_HOME` 仍指向那个已删除的旧路径,构建实际靠 `local.properties` 的 `sdk.dir=D:\Android\Sdk` 生效。 ## 自动化验证(已执行) - 单元测试:`./gradlew :app:testDebugUnitTest` —— **21 项全绿** (`FormattersTest` 7 + `MockDataProviderTest` 5 + `HomeViewModelTest` 1 + `WorkoutViewModelTest` 1 + `DeviceViewModelTest` 2 + `MetricDetailViewModelTest` 3 + `RoutesTest` 2) - 构建:`./gradlew clean assembleDebug` —— `BUILD SUCCESSFUL`, 产物 `app/build/outputs/apk/debug/app-debug.apk`(18,907,329 字节) - **未执行**:各页面的 `@Preview` 在 Android Studio 中渲染。本机没有 IDE GUI,agent 无法打开 Preview 面板,**这一项与人工验收一样是未执行的** —— 不要把它写进「已执行」段落 (旧稿把它列在上面这一节里,那等于声称验证过一件没做过的事)。 ## 人工验收(未执行 —— 无设备) 下表**全部未打勾**。这份清单已原样保留,交给有设备的人执行;不要在没有实测的情况下填入结果。 | 项 | 结果 | 备注 | |---|---|---| | 应用启动无崩溃 | 未执行 | 无设备 | | 四 Tab 切换 | 未执行 | 无设备 | | 重按已高亮的父 Tab 的行为 | 未执行 | 需实测:推测会停在子页而非回到 Tab 根 | | 每个页面的 `@Preview` 可渲染 | 未执行 | 需在 Android Studio 中逐个打开确认 | | 次要文字灰度一致 | 未执行 | 不得出现 `TextSecondary` 与 `onSurfaceVariant` 混用 | | 首页:设备状态条 / 步数大环 8,426 / 六个指标卡(血压“未开启”) | 未执行 | 无设备 | | 指标详情页:周/月切换(7 根 / 30 根柱子) | 未执行 | 无设备 | | 睡眠详情:分期卡片只在睡眠指标出现,入睡/起床读起来像「一晚」 | 未执行 | 无设备 | | 运动页 / 运动历史页 | 未执行 | 无设备 | | 设备页 / 设备设置开关(返回后状态保持) | 未执行 | 无设备 | | 我的页 | 未执行 | 无设备 | | 旋转屏幕、深色系统设置下不崩溃 | 未执行 | 无设备 | ### 需在有设备时重点确认的项(原清单细目,逐条保留) - 应用启动无崩溃,底部四个 Tab 显示为 健康 / 运动 / 设备 / 我的 - 四个 Tab 可自由切换,切换后状态保留、无闪烁 - **重按已高亮的父 Tab 的行为**:实现为 `popUpTo(start){saveState}` + `restoreState`, 推测会**恢复到该 Tab 保存的子页栈**(停在子页而非回到 Tab 根)。请实测并记录实际行为; 若实测是「停在子页」而产品希望「回到根」,那是一个独立的小改动,记下来即可 - 首页:步数大环显示 8,426,目标 10,000,环按比例填充 - 首页:点击任一指标卡进入详情页,标题为该指标中文名 - 详情页:返回后回到首页 - 运动页:显示“开始运动”卡片 + 5 条运动记录;「查看全部」进入历史页后底部导航栏仍可见 - 设备页:戒指卡片显示电量 78%、固件版本 1.0.5 - 睡眠卡片的入睡/起床时间**读起来像「一晚」**(如 入睡 22:41 / 起床 06:41),而不是跨好几天。 阶段一按「最后一个数据点往前 8 小时」演示(R29);若显示成跨天,说明 `DEMO_SLEEP_WINDOW_MILLIS` 那段被改坏了 ## 已知限制(阶段一有意为之) - 数据全部为 Mock,不连蓝牙、不连后端 - 血压恒为“未开启”占位(`HealthSummary.bloodPressure = null`) - 设备设置页的开关只改内存状态,重启即重置(对应 M2 的协议 0502/0504) - 睡眠分期条与入睡/起床时间是演示值(固定比例 + 最后一个数据点往前 8 小时),无真实分期数据 - 详情页统计摘要一律保留一位小数(步数因此显示为「平均 7512.3」这类精度过剩的形式) - 仅浅色模式 ## 覆盖缺口声明 **M1 的全部运行时行为目前只有编译期与单元测试保证,没有任何一次真机/模拟器运行。** `assembleDebug` 成功只说明代码能编译、能打包,**不说明界面正确、不说明不会崩溃**。 这是本机没有设备导致的已知缺口(ledger Ruling R21),不是「已验证通过」。 首次拿到设备时,请从上面那张人工验收表开始逐项补齐。 具体而言,**没有任何一行 M1 的 Compose 界面代码被真正渲染过**:导航图能否起来、 四个 Tab 是否显示正确文案、`MetricBarChart` 的柱子数量、`RingProgress` 的填充比例、 睡眠分期卡片是否只在睡眠指标下出现、次要文字灰度是否统一 —— 这些全部未经运行时检验。 单元测试覆盖的是 `Formatters` 的纯函数、`MockDataProvider` 的数据形状,以及七个 ViewModel 的状态流;**它们不经过 Compose 渲染管线,也不能发现布局、主题或导航层面的错误。**