148 lines
9.0 KiB
Markdown
148 lines
9.0 KiB
Markdown
# MAG160C 安卓统一 APP — 会话状态与心跳锚点
|
||
|
||
> 本文件是本任务("整合 4 个官方 APP 重写为 Android 16 现代化 APP")的心跳锚点。
|
||
> 每完成一个里程碑更新勾选;会话中断先读本文件 + `reverse_apk_features.md`,
|
||
> 再按"下一步"继续。约定:不弹询问窗,按计划自主推进,重大分歧点才停下来问。
|
||
|
||
## 任务目标
|
||
|
||
1. 逆向 C:\Project\MAG160C\app 4 个官方 APP(普通版/专业版/ThermoScope/demo)→ 已完成
|
||
2. 整合全部功能开发一款安卓 APP:适配 Android 16(API 36)、现代 UI、横竖屏、
|
||
无流氓文件夹、干爽简洁 → **进行中**
|
||
3. 背景问题:专业版在用户 Android 16 手机上花屏(根因见 reverse_apk_features.md §6)
|
||
|
||
## 已完成的里程碑
|
||
|
||
- [x] 工具链:jadx 1.5.1(C:\Tools\jadx)、Ghidra 12.1.2(C:\Tools)、IDA MCP 可用
|
||
- [x] 4 APK 解包 + jadx 全量反编译(%TEMP%\opencode\apkwork\jadx_*)
|
||
- [x] 普通版/专业版/ThermoScope/demo 功能清单 → docs/android_app/reverse_apk_features.md
|
||
- [x] IDA:pro libcoresdk.so GetOutputImage/copyBitmap 位图格式证实(ARGB_8888)
|
||
- [x] Ghidra:libcxsdk.so 导出 C++ API 清单(CFunctions 族,与 ARM64 coresdk 同源)
|
||
- [x] 花屏根因分析(32 位专属库 + targetSdk25 legacy 渲染栈)
|
||
|
||
## 关键事实速查(开发时直接用)
|
||
|
||
- USB:VID 0x833C PID 1,EP 0x03/0x82/0x81/0x84,帧 28B 头+38400B+尾,15fps
|
||
- 协议/渲染/温度算法全部已逆向:analysis/protocol_spec.md + csdk/(逐像素验证过的官方管线)
|
||
- csdk 的 mag160c_render 无平台依赖:USB 帧 → 320×240 RGB24 + 探针测温(毫度)
|
||
- DDT 标定文件:可从设备经 0x6BB6B66D/E 下载(官方 prepareProcessImage 同款),仓库有
|
||
build-artifacts/mag160c_official.ddt(1.8MB,SN 160043865)
|
||
- MDT 文件格式:reverse_apk_features.md §4(152B Tail + 5 段布局 + ROI 256B 记录)
|
||
- 温度:毫度 int;MDT 解码走 ConvertResponse2Temperature + T2E(Revise) + CorrectTemperature
|
||
|
||
## 用户已确认的范围(2026-09-06)
|
||
|
||
- 云功能:预留 Retrofit 接口模块,默认关闭
|
||
- 扫码打标 + 任务巡检(sqlite/xml) + 红外基准图叠加:v1 全部实现
|
||
- **网络互连(用户新增需求)**:主机手机插 USB 热像仪,局域网内另一台手机
|
||
远程实时预览——UDP 广播自动发现 + 手动添加内网 IP;自定义轻量协议
|
||
(控制通道 JSON + 图像流),不走厂商 33596/33597 协议
|
||
|
||
## 当前阶段
|
||
|
||
**阶段 2/8 完成:纯Kotlin核心管线移植并逐字节验证(2026-09-06)**
|
||
|
||
## 已完成里程碑(本任务)
|
||
|
||
- [x] 阶段1:轻量工具链定案——NDK/CMake/zig 全部卸载(-2.4GB),纯 Kotlin 方案:
|
||
渲染管线+温度算法+帧解析从 C 移植为 Kotlin,Gradle 8.14.3 + SDK 已有组件
|
||
- [x] 阶段2:项目骨架(android/,AGP 8.11.1 + Kotlin 2.2.0 + Compose BOM,
|
||
compileSdk/targetSdk 36,minSdk 26),最小APK可构建
|
||
- [x] 阶段2:表数据自动生成 analysis/gen_kotlin_tables.py → OfficialTables.kt
|
||
(palette256 ARGB / T2E 646 / T2E274 / E2T_ACC_Q10)
|
||
- [x] 阶段2:核心移植 FrameStream / RenderPipeline / TempMath(毫度测温)
|
||
- [x] 阶段2:PC端参考工具 analysis/render_offline.c(gcc 编译)+ 差分测试:
|
||
**Kotlin 输出与C参考逐字节一致**(60帧序列,首渲染帧32,NUC/LUT/灰度/输出全同)
|
||
- [x] 阶段2:FrameStream 分块重组测试 + 温度换算单调性测试全过
|
||
|
||
## 移植陷阱记录(教训)
|
||
|
||
- C 无符号32位回绕:乘积/减法必须 u32() 掩码(cdf*denom、0xffc0000-iv7*0x40000、
|
||
(v-win_lo)*S 等)
|
||
- lutRebuild 的 u12 基址是常量 iv7*0x10+0x10,**不是**链式 u21v;u21v 只用于曲线钳制比较
|
||
- Kotlin ByteArray 存 255 = -1:lut[bfmax] != 0xFF 判断必须 (b.toInt() and 0xFF)
|
||
- 暖机窗口内 FFC 状态机暂停(warm check 在 ffc_step 之前)——移植时保持顺序
|
||
|
||
## 用户反馈修复(2026-09-07)
|
||
|
||
- [x] **中文乱码根因**:部分源码曾被python以GBK重写(AppRoot.kt),编译出的字符串
|
||
mojibake。已写 fix_encoding.py 全量转UTF-8 + kotlin.daemon.jvmargs 锁UTF-8 +
|
||
dex字节级验证(classes5/9.dex 中"媒体库"UTF-8正确)
|
||
- [x] **权限弹窗**:Manifest 加 USB_DEVICE_ATTACHED intent-filter + device_filter
|
||
(插热像仪系统自动弹权限/启动);相册页运行时申请 READ_MEDIA_IMAGES
|
||
(模拟器实测弹窗正常)
|
||
- [x] **图标**:全部重绘为可验证几何图形(双弧圆/直线/矩形),横竖屏截图确认渲染正确
|
||
- [x] **专业版三大功能补齐**:多点测温(点击加Pt1..PtN、再点删除)、右侧色标条
|
||
(渐变+最高/最低温标注)、最高温追踪开关(追踪·开/关)
|
||
- [x] **演示模式**:无设备时用真实管线+DDT渲染合成帧(热块场景),全UI可探索;
|
||
demo温度用局部线性显示映射(真机温度走管线数学)
|
||
- [x] Android 16.1 模拟器(Medium_Phone AVD)实机验证:中文/图标/布局/横竖屏正常,
|
||
预览图在 analysis/preview/preview_*.png
|
||
|
||
## 用户反馈修复 第二轮(2026-09-07)
|
||
|
||
- [x] 竖屏时热像图旋转90°竖着显示(填满屏宽);横屏时保持传感器原生4:3方向
|
||
填满屏高——两个方向下显示区域都最大化(用户要求的官方行为)
|
||
- [x] 横屏:控制栏移到屏幕右侧(竖列),竖屏保持底部横排6项等分——切换时
|
||
不再跳位
|
||
- [x] 追踪/测温点标记改为大号"圆环+实心点"图标,字高随密度缩放(更大)
|
||
- [x] 色标条放大(宽20dp、高0.8视口)+更大刻度字号
|
||
- [x] ScreenOrientation=fullSensor:跟随传感器旋转(系统旋转锁定时也转,
|
||
与官方普通版一致)
|
||
- [x] **SurfaceView旋转存活**:AppRoot/LiveScreen改为稳定单分支布局(导航/控制
|
||
栏做成overlay),SurfaceView不再因横竖屏切换被销毁重建(此前横屏花屏空
|
||
白的根因)
|
||
- [x] 模拟器实测:竖屏/横屏截图确认全部生效(analysis/preview/)
|
||
|
||
## 待办
|
||
|
||
- 真机USB实测(温度绝对值标定、FFC/录像/MDT保存端到端)
|
||
- 网络互连远程预览(用户需求:UDP自动发现+手动IP)
|
||
- 离线MDT温度解码(ConvertResponse2Temperature+标定参数,待真机文件对照)
|
||
- 厂商12调色板精确提取(需运行时抓取)
|
||
|
||
## 里程碑日志
|
||
|
||
- 阶段3b 完成(2026-09-06 晚): 拍照 MDT 容器(jpg+info块+raw帧+备注)存入
|
||
MediaStore DCIM/MAG160C;MP4 录像 = Surface 编码 H.264 @320×240 15fps 2Mbps
|
||
- 阶段4 完成: 媒体库(MediaStore 扫描 + 内嵌 JPEG 缩略图 + MDT 尾部校验)
|
||
- 阶段5a 完成: 分析查看器(detectTransformGestures 缩放1-4x/平移、12 调色板
|
||
重渲染原始帧、自动窗口、备注编辑回写容器、温度探针近似)
|
||
- 阶段5b 完成: PDF 巡检报告(PdfDocument:标题/7×4信息表/热像图/结果/建议/测试员)
|
||
- 阶段6a 完成: 设置页(默认调色板/发射率/报警温度/关于,SharedPreferences 私有)
|
||
+ 任务巡检解析器 TaskParser(sqlite task/region/device/part/phase + XML title/target)
|
||
|
||
## 阶段3a 完成(2026-09-06 晚)
|
||
|
||
- [x] USB传输层 usb/UsbTransport.kt(VID 0x833C 枚举/权限/claim/EP查找)
|
||
- [x] 命令协议 usb/MagProtocol.kt(4B命令+FFC 8B;0x5BB5B55B 信息块解析)
|
||
- [x] 直播会话 usb/IrSession.kt(66b/66c/66f → FFC(0)x2 → 300ms → START(73),
|
||
读线程→FrameStream→RenderPipeline→帧回调;STOP(74);手动FFC)
|
||
- [x] 官方12调色板 core/Palettes.kt(铁虹=官方提取表,其余为标准曲线近似)
|
||
- [x] UI骨架:底部导航4区(实时/相册/分析/设置,横屏自动切侧栏 NavigationRail)
|
||
- [x] 实时画面 ui/live/:SurfaceView+软件Canvas渲染(letterbox+数码变倍+OSD
|
||
中心温/最高最低温标记),ViewModel驱动,慢速测温定时器
|
||
- [x] DDT标定文件打包进 assets/mag160c.ddt
|
||
- [x] 全APK assembleDebug 成功(11.7MB,无material-icons膨胀)
|
||
- [ ] 待实机验证USB流(需插设备)
|
||
|
||
## 开发计划(待确认后逐阶段执行)
|
||
|
||
- 阶段 1:环境(cmdline-tools/NDK r27+/gradle 8.x + 16KB 对齐配置 + AGP 8.x)
|
||
- 阶段 2:新仓库 app-android(Kotlin + Compose M3 + NDK 移植 csdk 渲染/温度 C 代码 + Kotlin USB 层)
|
||
- 阶段 3:实时画面(USB 流+官方管线+OSD+ROI+调色板+FFC+增强+PIP 可见光+拍照 MDT+MP4 录像)
|
||
- 阶段 4:媒体库(MediaStore,DCIM/MAG160C,无流氓文件夹)
|
||
- 阶段 5:MDT 离线分析(缩放/ROI/参数/PDF 报告/备注)
|
||
- 阶段 6:设置/任务巡检/可选云(Retrofit opt-in)
|
||
- 阶段 7:Android 16 专项适配验收(16KB 对齐/横竖屏/深色/预测性返回)
|
||
- 阶段 8:打包安装到用户手机实测
|
||
|
||
## 心跳约定
|
||
|
||
- 每完成一个阶段:更新本文件勾选 + git commit(不 push)。
|
||
- 中断恢复:读本文件 → 按"下一步"继续 → 环境检查命令:
|
||
```powershell
|
||
Test-Path C:\Users\ZXC\AppData\Local\Android\Sdk\ndk\<ver>
|
||
Get-Command java; Get-Command gradle
|
||
```
|