项目原先把 Android 运行期间分配的 USB deviceId 拼入菜品摄像头配置,并将三种 UVC 设备与 Camera2 ID 的关系写死。实际设备重启后,USB 枚举顺序会变化:同一台摄像头可能获得不同的 deviceId 和 /dev/videoN,导致已保存的摄像头配置无法正确恢复,或人脸识别打开了另一台摄像头。
FY-3576SE 当前连接 3 台 USB 摄像头,三台设备的 VID/PID 均不相同:
| 客户显示名称 | 稳定标识 | 当前 V4L2 | 当前 Camera2 ID |
|---|---|---|---|
| MC-500U(XC-TECH) | 1374_41357 | /dev/video0 | 100 |
| USB 2.0 Camera(Sonix Technology Co., Ltd.) | 3141_25440 | /dev/video2 | 102 |
| USB2.0_CAM1(Sonix Technology Co., Ltd.) | 11391_19040 | /dev/video28 | 128 |
历史记录中的另一轮启动曾出现 MC-500U 与 USB2.0_CAM1 的 V4L2/Camera2 编号互换,证明这些编号只能作为本次启动的运行时地址,不能直接作为持久化唯一标识。
VID_PID 稳定标识,不再保存 Android 运行时 deviceId。deviceId_VID_PID 配置:首次读取时自动规范化为 VID_PID。fbl_旧ID 配置,避免升级后丢失原分辨率。/sys/class/video4linux/video*/device 追溯 USB 父设备并读取 VID/PID;EXTERNAL 的相机 ID;采用测试先行:
最终验证结果:
./gradlew :app:assembleDebug:成功,包含本次摄像头修改的 Debug APK 已生成。git diff --check:通过。:app:testDebugUnitTest :app:assembleDebug --rerun-tasks 未通过主代码编译:工作区中并发进行的菜单响应结构调整已经移除 dishItemList1 至 dishItemList6,但 DishRecognitionActivity 与 DishMenuManagementActivity 仍引用这些旧字段,共 12 个编译错误;该部分不属于本次摄像头改动,本次未修改或绕过它。设备侧本次只进行了只读枚举和 sysfs/Camera2 信息核验,未覆盖安装 APK,未修改设备现有配置。安装后的重启恢复、设置页显示和三台摄像头逐台预览仍需实机验收。
当前设备的三台摄像头可以用 VID/PID 唯一区分。如果以后同时接入两台完全相同且 VID/PID 相同的摄像头,单独使用 VID/PID 无法唯一标定;后续需优先加入可靠 USB 序列号,缺少序列号时再使用固定 USB 物理端口,并在换口时提示重新绑定。本次映射遇到重复稳定标识或歧义时不会猜测设备。
本次仅调整摄像头配置持久化、旧配置迁移、UVC/Camera2 动态映射和设置页名称展示。未修改菜品识别算法、人脸算法、支付接口、激活流程或 Git 历史;工作区中已有的人脸激活相关改动保持原样。