本方案覆盖称重餐台的 A01、A02、A03 防逃单报警,以及报警日志独立、配置审计和解除码范围调整。
onStop() 与进程中断后的报警处理逻辑。| 编号 | 名称 | 触发条件 | 解除条件 |
|---|---|---|---|
| A01 | 余额不足 | 餐盘人员查询成功且余额可解析为数值、余额小于等于 0 | 先移开餐盘,再刷有效解除码 |
| A02 | 未放餐盘取餐 | 打餐前、无餐盘码、重量稳定,重量相对稳定基线减小达到阈值 | 刷有效解除码 |
| A03 | 餐盘未绑定 | 查询成功但无人员信息,或接口明确返回“餐盘未绑定” | 先移开餐盘,再刷有效解除码 |
三类正式报警均独立开关、默认开启。报警触发后同一时刻仅保留一个活动报警,阻断普通扫码业务,显示不可取消的全屏报警页,红灯持续闪烁,语音每 5 秒循环播放。
HomeActivity 在餐盘人员查询成功后判断 A01,在人员为空或明确“餐盘未绑定”结果处判断 A03,在稳定重量回调中判断 A02。AntiEscapeController 只允许一个活动报警,后续触发不会覆盖当前报警;报警期间普通餐盘码不进入人员查询或取餐业务。AntiEscapeAlarmSnapshotStore 在触发后保存报警类型、内容和触发时间,作为进程异常后的最小审计快照。AntiEscapeAlarmDialogFragment:禁止点外部关闭、拦截返回键并隐藏状态栏和导航栏。AntiEscapeAlarmSignalController 在触发时立即播放对应语音,之后每 5 秒重复;A01 使用余额不足语音,A02 使用“请先放餐盘”,A03 使用“请先绑定餐盘”。LightController 进入报警优先模式后以约 500ms 间隔闪烁红灯,普通绿灯、关灯或短闪请求不能覆盖报警灯光。有效解除码为连续六码范围:888880 至 888899,含边界共 20 个,原 888888 包含在范围内。
resolveMethod=UNLOCK_CARD,不记录具体解除码,避免泄露管理解除码。/Log/alarm_log_yyyyMMdd.txt
复用现有 LocalFileRecorder,保持异步追加、日期分文件、目录自动创建和磁盘可用空间低于 3GB 时的自动清理策略。
| 事件 | 记录内容 | 示例 |
|---|---|---|
| 触发 | 报警类型、报警内容、触发时间 | ANTI_ESCAPE|event=TRIGGER|type=A01|content=...|triggerAt=... |
| 解除 | 报警类型、报警内容、触发时间、解除方式、解除时间 | ANTI_ESCAPE|event=RESOLVE|type=A01|...|resolveMethod=UNLOCK_CARD|resolvedAt=... |
| 开关配置 | 报警类型、旧值、新值、设置来源 | ANTI_ESCAPE|event=CONFIG|type=A01|setting=enabled|previous=true|value=false|source=SETTINGS |
| A02 阈值配置 | 旧阈值、新阈值、单位、设置来源 | ANTI_ESCAPE|event=CONFIG|type=A02|setting=no_tray_pick_alarm_threshold|previous=5|value=10|unit=g|source=SETTINGS |
仅在设置值实际改变且校验通过后记录配置事件;无变化或非法阈值输入不写入日志。
报警 TXT 仅做本地审计,不调用新增服务端上传接口;普通 local_log_ 中原有的人员查询、取餐和网络日志不受影响。
/Log/ 下的所有 TXT,因此无需新增查看页面,报警日志会自动出现在文件列表中并沿用现有分页读取。local_log_yyyyMMdd.txt 时,同步删除同日期的 alarm_log_yyyyMMdd.txt。| 设置项 | 默认值 | 作用 | 审计 |
|---|---|---|---|
| A01 余额不足报警开关 | 开启 | 控制 A01 是否进入正式报警 | 记录旧值、新值 |
| A02 未放餐盘取餐报警开关 | 开启 | 控制 A02 检测器和正式报警 | 记录旧值、新值 |
| A03 餐盘未绑定报警开关 | 开启 | 控制 A03 是否进入正式报警 | 记录旧值、新值 |
| A02 未放餐盘取餐报警阈值 | 5g | 稳定减重达到阈值时触发 A02 | 合法范围 1–50g,记录旧值、新值 |
关闭 A01/A03 时保留原有普通提示回退;关闭 A02 时重置检测基线,不产生新的 A02 报警。
| 类型 | 关闭后的行为 | 声光与记录 |
|---|---|---|
| A01 | 不创建活动报警,不锁页;复用 WarnPop 显示约 1.5 秒“余额不足”和余额/累计金额 | 红灯短闪 3 次;按普通语音开关播放一次余额不足语音;不写 TRIGGER/RESOLVE |
| A02 | 不创建正式报警;重量链路恢复原有约 1.5 秒“请先放置餐盘”提示 | 红灯短闪 3 次;按普通语音开关播放一次放盘语音;保留原重量变化日志 |
| A03 | 不创建全屏报警;保留“餐盘未绑定”Toast、人员查询日志和既有上报 | 按既有逻辑播放一次绑定语音并持续闪红灯,至 3 个空扫码帧确认拿盘后停止 |
关闭开关不会自动解除已经活动的正式报警;设置页也不会在报警锁页期间进入,因此开关仅影响后续报警判定。
HomeActivity.onStop() 会以 APP_EXIT 解除活动报警;若进程被强制终止,Android 不保证执行生命周期回调。下次启动如发现遗留报警快照,会记录 PROCESS_INTERRUPTED 并清除快照。本次明确保持该行为不变。PROCESS_INTERRUPTED 的记录时间是下次启动时的补偿时间,不是进程终止时间。如后续需要防止杀进程绕过报警,应另行评审“保留快照并在下次启动恢复拦截”的方案。
| 方式 | 记录值 | 行为 |
|---|---|---|
| 有效解除码 | UNLOCK_CARD | 按 A01/A02/A03 前置条件解除,停止语音和红灯、关闭页面、清除快照 |
| 首页停止 | APP_EXIT | 当前实现解除活动报警,停止声光并清除快照 |
| 报警页展示失败 | DIALOG_SHOW_FAILED | 安全回滚并记录解除 |
| 下次启动发现遗留快照 | PROCESS_INTERRUPTED | 补记解除并清除快照,不恢复报警页面 |
HomeActivity:报警触发与解除改写入报警 TXT。SetActivity:三类报警开关和 A02 阈值变更写入报警 TXT。LocalFileRecorder:低存储时同步删除同日期报警 TXT。UnlockCodePolicy:解除码范围改为 888880–888899。UnlockCodePolicyTest:覆盖解除码范围边界。AntiEscapeAlarmDialogFragment、AntiEscapeAlarmSignalController、LightController:提供全屏锁定、循环语音和报警优先红灯能力。TRIGGER,普通日志不再出现该记录。RESOLVE 内容与解除时间;A01/A03 在未移盘时不得解除。CONFIG 的旧值、新值、来源和单位。888880、888899 有效,888879、888900 无效。./gradlew testDebugUnitTest assembleDebug,构建和单测通过。git diff --check,无空白错误。结论:A01/A02/A03 的报警规则、独立 TXT 审计、配置记录、查看清理策略与 20 个连续解除码已形成完整方案并完成代码落地;进程终止绕过报警问题按当前决定暂不处理。