FaceStudyPop 照片存储双设备兼容修复方案及实施记录
结论:K203 拍照 Bitmap 已生成,但 Android 12 拒绝应用在公共存储根目录创建
/sdcard/takePhoto,导致保存路径为空。K203、YF/FY 等设备统一切换到应用专属目录,
不增加设备型号分支。
问题现象
人脸采集右侧能够显示照片,点击上传却提示“请先拍照”。显示使用内存 Bitmap,上传使用落盘文件,
两者状态因此出现分离。
根因证据
- K203 运行 Android 12,应用的 LEGACY_STORAGE 状态为 ignore。
- 原实现尝试在公共存储根目录创建 takePhoto。
- MediaProvider 拒绝创建非默认顶层目录,File.createNewFile 随后抛出 IOException。
- 保存返回空路径,FaceStudyPop 的上传文件对象为 null。
兼容决策
所有设备统一使用 Context.getExternalFilesDir("takePhoto");外部目录不可用时回退到
Context.getFilesDir()。不按 K203、YF 或 FY 型号分支。
改动边界
- 修改 BitmapUtils.java 和 FaceStudyPop.java。
- 保留旧公共目录保存方法,避免影响其他调用方。
- 不修改相机、方向、镜像、人脸检测和上传接口。
- 不迁移或删除旧公共目录文件。
实施内容
- 新增接收 Context 的应用专属目录保存重载。
- 检查目录、压缩结果、文件存在性和长度,并记录具体失败路径。
- FaceStudyPop 改用新重载。
- 上传按钮只在文件真实落盘后启用。
- 保存失败立即提示重新拍照。
- 上传复用现有 ProgressDialogHelper 显示“正在上传,请稍后...”,
防止重复点击,并在成功、失败或弹框销毁时关闭 Loading。
预期路径
/storage/emulated/0/Android/data/com.zhct.multipurpose/files/takePhoto/{staffUuid}.png
验证记录
- 目标 Java 文件空白检查:已通过。
- JDK 8 执行
sh ./gradlew :app:testDebugUnitTest :app:assembleDebug --console=plain;
存储修复版为 BUILD SUCCESSFUL in 28s,加入上传 Loading 后最终复核为
BUILD SUCCESSFUL in 8s。
- 最终 Debug APK SHA-256:
e262868e653552f2ba466413bc0a6ce34634456917856be7e9ed690f67388aa1。
- K203(Android 12)覆盖安装成功;保存文件为 154896 字节、240x427;
无原 MediaProvider 拒绝和 IOException,“上传”由置灰变为可用。
- YF_029E(Android 11)覆盖安装成功;保存文件为 98550 字节、240x320;
UI Automator 确认“上传”的 enabled 由 false 变为 true。
- 两台设备拉取 PNG 检查均能正常解码、方向正常。
- 加入 Loading 后的最终 APK 再次覆盖安装到 K203 和 YF_029E,两台均返 Success。
- 不主动上传,不修改服务端头像。
已知边界
- 应用专属目录随应用卸载删除,符合上传临时文件用途。
- 旧文件不迁移,新拍照片从本版本开始使用新路径。
- 现有存储权限本次不删除,避免影响未审计功能。