Files
prop-ai-hr/docs/MOBILE_APP_DEVICE_ACCEPTANCE.md
T

83 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 原生 App 真机验收清单
此清单用于 Android/iOS 自定义基座或签名包验收。`verify:app-assets` 校验源码侧原生配置和静态资源,`verify:android-apk` 校验实际 APK 元数据、签名与哈希;两者都不能替代本清单。
## 预条件
1. 已执行 `npm --prefix mobile-uni run build:app`,并使用 HBuilderX 的**自定义运行基座**运行当前资源。
2. Android 首次上机前,在同一构建会话设置法务确认的 `VITE_APP_TERMS_URL`、`VITE_APP_PRIVACY_URL`,执行 `npm --prefix mobile-uni run configure:app-privacy`、`build:app` 和 `verify:app-release`;不得手工放入占位地址,也不得让原生弹窗与登录页使用不同地址。
3. 使用有效的移动端测试账号;不得把管理员 Web 登录态当作 App 登录验证。
4. 每台设备保留系统版本、App `versionName/versionCode`、基座/包哈希、录屏或截图和失败日志。
5. HBuilderX/CLI 编译链必须与手机调试基座兼容;启动时出现版本不匹配弹窗即视为未通过。当前版本组合和排障命令见 `MOBILE_APP_PACKAGING.md`。
Android 每个人工步骤完成后,可在不改变设备状态的前提下保存统一证据。下列脚本只读取当前版本、前台 Activity、四项敏感权限、UI 层级、截图和应用退出记录;不会启动/停止应用、安装/卸载、清数据、授权/撤权或代替用户点击。`screen.png` 和 `window.xml` 可能包含屏幕可见信息,只会写入 Git 已忽略的 `output/`,不得转存手机号、验证码或业务原文到仓库:
```powershell
.\scripts\capture-android-acceptance.ps1 `
-Serial emulator-5554 `
-Stage privacy-before-choice
```
每次手动操作后换一个简短的 `-Stage`。首次点击“暂不同意”后会进入第二层“确认提示”,先用 `privacy-exit-confirmation` 取证;用户再亲自点击“退出应用”后用 `privacy-rejected-exited` 取证。脚本会区分 `first-choice`、`exit-confirmation` 和 `not-visible`,并在应用进程已经退出时继续记录前台 Activity、退出记录和权限,不会因 `pidof` 无结果而失败。随后重新启动并由用户点击“同意并继续”,使用 `privacy-consented`;麦克风拒绝可使用 `microphone-denied`。脚本不把“拍到页面”自动判成业务通过;验收人仍须结合预期、截图和 `acceptance-evidence.json` 签认。
## 当前证据边界
2026-07-26 已在 vivo V2443A(Android 15)的 HBuilderX 5.22 标准基座完成手机号登录,并通过生产 `dashscope/qwen3-asr-flash` 跑通“按住说话 → ASR → 提交”链路。2026-07-28 同一机型再次由 HBuilderX CLI `5.22.2026072503-alpha` 完成标准基座编译、同步和启动;未配置正式法务地址时,登录页协议默认未勾选并明确阻止验证码与登录,点击协议入口不会打开占位地址。
同日已通过 DCloud 云端证书生成并安装首个自定义基座,包名 `com.yincheng.wygj`、版本 `0.1.5 (105)`,云打包、签名、USB 安装、资源同步和启动链路成立。系统读取发现首版因未显式配置而使用默认 `targetSdkVersion=28`,随后已在 manifest 固定为 35,并将设备信息与外部存储设为启动时不申请。最终 API 35 自定义基座大小为 `21,158,193` 字节,SHA-256 为 `82D3352FF96A86F5DB4AC0C71DCB0ED6CEC98F2A785F6EAED2FE8D4FC0C5F704`,实际 APK 的包名、版本、API 35、单签名和 v2 签名均已由脚本复核。
新基座已在 vivo V2443A 完成保留数据的覆盖安装和系统 Launcher 冷启动。系统读取为 `minSdk=21`、`targetSdk=35`;启动后设备信息、外部存储、相机和麦克风均保持未授权,未出现启动权限弹窗。员工端首屏、状态栏和底部手势区正常渲染,未发现白屏、崩溃或 `FATAL EXCEPTION`;登录页法务门禁继续生效。
23:12 又生成可独立安装的非自定义基座 DCloud 云证书内测 APK `bangdao-0.1.5-dcloud-test.apk`,大小 `33,920,950` 字节,SHA-256 为 `AB634EB9A9F0939804151ED14815484FBD75DFE36CC24DF00EC23BDD762D8FD1`。APK 反编译门禁已确认包内 `androidPrivacy.json` 使用线上《服务协议》和《隐私政策》地址;同签名覆盖安装成功。只清除 `com.yincheng.wygj` 测试数据后,以系统 Launcher Activity 冷启动,原生 template 弹窗真实显示“同意并继续/暂不同意”,两个链接均在 vivo 系统浏览器打开对应 HTTPS 页面,且未发现 `FATAL EXCEPTION`。验收过程没有代替用户点击同意或拒绝;拒绝退出、同意后登录、主动录音权限、弱网、方言、iOS 和下列全项仍未通过。
2026-07-29 当前候选包升级为 `0.1.6 (106)`,大小 `33,921,279` 字节,SHA-256 为 `A5F026B70F11327355597B9FEA3625C4168700297E6D7847F10B079CEB860914`。191 项移动端单元测试和类型检查通过;APK 已通过 API 35、法务链接、签名、包内 `app-service.js` 与当前 App-Plus 编译产物一致性以及手机号、固定测试验证码、私钥和常见令牌扫描。该包在同一 vivo V2443A 完成保留数据的覆盖安装和 Launcher 冷启动,系统读取为 `minSdk=21`、`targetSdk=35`,相机、录音和媒体权限保持未授权,未发现 `FATAL EXCEPTION`。因为覆盖安装保留了前一版本的隐私状态,本次未重新触发首次隐私弹窗;仍须由用户亲自完成最新包的拒绝/同意反例。
同日,本机 Android Studio `Medium_Phone` 虚拟机完成 Android 15/API 35 启动,物理分辨率 `1080×2400`、密度 `420`。在虚拟机此前未安装本应用的前提下,`0.1.6 (106)` 首次安装成功并从系统 Launcher 冷启动,`am start -W` 记录总耗时约 `6.4s`;最新包真实显示原生《服务协议和隐私政策》弹窗,四项相机、录音、图片和视频权限均为 `granted=false`,crash 缓冲区为空。截图和 UI 层级保存在忽略目录 `output/aug1-rc/android-emulator/`;验收未代替用户点击同意或拒绝。虚拟机证据用于补充干净安装和 API 35 权限基线,不能替代真实设备的媒体、WebRTC、弱网和系统浏览器交互。
同日,候选包继续升级为 `0.1.8 (108)`,大小 `33,921,705` 字节,SHA-256 为 `E252140645F3AAD14B3594FD78E76BDF1A2122F7DC70EBD21CC5DF53223C7878`。新增的项目根原生清单与 `network_security_config.xml` 已进入实际云打包输入,193 项移动端测试、类型检查、App 构建及联网法务预检通过;APK 反编译确认包内资源与当前编译产物一致、`usesCleartextTraffic=false`、`networkSecurityConfig` 引用、系统证书信任配置、签名和敏感值扫描均通过。虚拟机卸载旧实例后全新安装,Launcher 冷启动总耗时 `2.904s`,最新原生隐私弹窗真实显示,四项敏感权限均为 `granted=false`,crash 缓冲区为空。仍未代替用户点击拒绝或同意。
同一 `0.1.8` APK 又在虚拟机完成保留数据的同版本覆盖安装。覆盖后冷启动 `3.092s`、标准 Launcher Intent 暖启动 `0.538s`、从系统桌面恢复热启动 `0.120s`;原生隐私弹窗和四项未授权状态始终保持,未发现 FATAL 或 ANR。该结果证明当前 APK 的安装升级、入口解析和首次弹窗前生命周期基线,不证明登录后前后台、弱网、录音或业务闭环。
随后针对 Android 系统文件选择器“用户取消”被误判成上传或转写失败的问题,将五个文件选择服务统一为结构化取消信号,并在九个页面恢复空闲态、清理残留“转写中”提示;真实平台异常仍显示稳定中文错误。新增回归覆盖五个选择器的取消/失败分流以及九个消费页面。直通车页同时补齐首次弱网导致五个直达对象加载失败后的原位重试,失败时清空旧通道并禁止提交,恢复后自动选择有效通道;再增加 package、lockfile 与 manifest 版本一致性门禁。移动端测试增至 `198/198`,类型检查通过。自动化证明状态机已修复,但真实系统文件选择器取消与断网恢复仍须人工点击确认。
当前候选包已升级为 `0.1.10 (110)`,大小 `33,922,134` 字节,SHA-256 为 `20CB16B4E9D024DBF5EEEF577BFBA3B4DF5E5E78B597BABB99CB7450C7AE5034`。DCloud 云打包成功后,APK 元数据、测试签名、包内资源、法务链接、网络安全配置和敏感值门禁全部通过;同一虚拟机从 `0.1.9` 保留数据覆盖安装成功,Launcher 冷启动约 `1.271s`,显示最新原生隐私弹窗,四项敏感权限仍为 `granted=false`,未发现 FATAL 或 ANR。验收仍未代替用户点击拒绝或同意。
2026-07-29 又以新增的只读统一取证脚本复核同一虚拟机的当前状态:前台 Activity 为 `io.dcloud.PandoraEntryActivity`,原生隐私标题、“暂不同意”和“同意并继续”三个控件均可见,手机号登录尚不可见;相机、录音、图片和视频权限仍为 `false`,应用退出记录中未出现 Crash/ANR。截图、UI、权限、Activity、退出记录和 JSON 均落在忽略目录 `output/aug1-rc/android-acceptance/20260728-192056-privacy-before-choice/`。该次只记录选择前基线,仍未代替用户做隐私选择。
## 已完成的 Android 基座证据
- [x] 自定义基座包名、版本、API 35、单签名、v2 签名和 SHA-256 可重复校验。
- [x] 同签名同版本覆盖安装成功,未卸载或清除 App 数据。
- [x] 系统 Launcher 冷启动进入员工首页,无启动权限弹窗、白屏或崩溃。
- [x] 启动后设备信息、外部存储、相机和麦克风权限均保持未授权。
- [x] 独立 DCloud 云证书内测 APK 的包内法务配置、API 35、单签名、v2 签名和 SHA-256 可重复校验。
- [x] 清除本 App 测试数据后首次启动先显示原生隐私弹窗,服务协议与隐私政策链接均可在系统浏览器打开。
- [x] `0.1.6 (106)` 当前候选包完成同签名覆盖安装、冷启动和启动权限复核,包内资源与当前 App-Plus 编译产物一致。
- [x] `0.1.8 (108)` 在本机 Android 15/API 35 虚拟机完成卸载重装和冷启动,最新包原生隐私弹窗真实显示,四项敏感权限保持未授权、网络安全配置已进入 APK 且未见崩溃。
- [x] `0.1.8 (108)` 在同一虚拟机完成保留数据覆盖安装、标准 Launcher 启动和首次隐私弹窗前的后台/前台恢复,未见 FATAL 或 ANR。
- [x] `0.1.10 (110)` 从 `0.1.9` 保留数据覆盖安装并冷启动成功,最新原生隐私弹窗、未授权权限基线和无 FATAL/ANR 状态保持。
- [x] 只读统一取证脚本已通过状态变更命令回归并在虚拟机实跑,可重复保存当前版本、Activity、隐私控件、权限、UI、截图和退出记录。
- [x] 媒体选择取消/真实失败与直通车首次弱网恢复状态机已由 198/198 个移动端测试覆盖;真实 Android 文件选择器取消与断网恢复仍列为下方人工门禁。
## Android(最低 Android 10 + 一台当前主流机型)
- [ ] 用户实际选择“暂不同意”后退出;选择“同意并继续”后才进入登录,且升级后的协议版本策略符合预期。
- [ ] 手机号登录、短信验证码错误、登录失效重登均符合预期。
- [ ] 首次录音允许麦克风后,可完成转写;拒绝麦克风后不循环申请,能选择本地音频继续。
- [ ] 原生实时对练可完成麦克风授权、实时转写与远端语音播放;WebRTC/WebView 不可用或断线时明确提示并保留录音对练。
- [ ] 图片、视频、文档和音频可选择并上传;受控附件下载后可打开,不泄露 OSS 地址。
- [ ] 前后台切换、网络断开/恢复、窄屏和底部手势区无白屏、遮挡或重复提交。
- [ ] 再次安装同版本后,桌面图标、启动图和 Android 导航栏不闪白。
## iPhone(iOS 15 + 一台当前刘海或灵动岛机型)
- [ ] 初次访问录音时,系统麦克风说明与功能一致;拒绝后可选择音频且不崩溃。
- [ ] 选择图片/视频/文件时,系统照片/文件访问说明与功能一致;取消选择不会残留上传状态。
- [ ] 登录、录音转写、TTS 播放、上传、受控下载、前后台切换均通过。
- [ ] 启动图全屏,无黑边;状态栏、刘海、底部安全区和键盘不遮挡主要操作。
- [ ] App Store 图标无透明通道、未预制圆角;真机图标更新后重启设备复核 iOS 缓存。
## 通过口径
每个平台的必测项全部通过,且录音拒绝、媒体取消、登录失效和离线恢复四种反例均留有证据,才可进入签名包或 TestFlight/企业 APK 测试。任何 App 壳、权限、原生插件或证书变更都必须重新云打包并重跑本清单。