本页跟踪三类事项:
- 7 个信息缺口 —— 先通过 grep 代码库回答;code 答不出来的标 "需要 Liang 确认"
- 4 个代码 vs 规范差异 —— 代码实现与 v4.2 规范不一致的地方,需要决策:改代码 or 改规范
- v4.2 遗留的开放项 —— 即 v4.2 §九里尚未关闭的问题
图例:
- ✅ = 代码已确认答案(带文件/行号引用)
- 🟡 = 部分回答,待人跟进
- 🔴 = 需要 Liang 确认 / 代码无法回答
- ⏳ = 长期待定
- ✅ iOS 16.0
- 来源:
ios/Podfile:2 —— platform :ios, '16.0'
¶ 2. Android 最低 SDK
- ✅
flutter.minSdkVersion(由 Flutter 工具链决定;Flutter 3.41.7 当前默认 = API 21 / Android 5.0 Lollipop)
- 来源:
android/app/build.gradle.kts:28 —— minSdk = flutter.minSdkVersion
- 注:若要显式 pin(防 Flutter 升级后漂移),可改为
minSdk = 21
- ✅ China(作为所有地理定位 API 失败时的 fallback 默认)
- 流程:
- IP 地理定位 API → 解析洲 → 映射到 China / US / EU broker
- 若全部 API 失败 → 默认 China
- 用户可在 Settings 页手动覆盖
- 来源:
lib/core/services/region_service.dart:148 —— debugPrint('[REGION] All APIs failed — defaulting to China')
- ✅ FIFO cap at 50 sessions
- 常量:
_maxCookLogSessions = 50
- 来源:
lib/core/providers/device_providers.dart:1144
- 语义:超过 50 条后最早的 session 被剔除
- 🔴 需要 Liang 确认
- 代码仅说明范围 0–120 °C(121 个整点值),没有解释为什么是这个范围而不是其他(例:0–150 或 0–100)
- 怀疑点:与中继盒固件的 NTC 查表对齐,或是探针物理量程
- 附注:
tempExtArray 是 275 条(0–274 °C),与 275 °C 的"全屏报警钳位"一致
- ✅ 并行直连所有已知设备,没有 last-cooked 优先级
- 语义:
- 有保存 MAC 的已知设备:并行 direct connect,不等扫描
- 没 MAC 的设备:回落到扫描重连循环
- 连上最先响应的(无任何优先级排序)
- 来源:
lib/core/services/ble_device_service.dart:468-498(seedReconnectQueue → _directConnectAll)
- ✅ 可以,当前代码未做任何限制
- 入口:
- 配对后的引导流程(
connection_mode_page.dart:113)
- Settings 页手动入口(
settings_page.dart:678)
- 两个入口都没有检查
cookingSessionsProvider 的活跃会话
- 设计决策未知:是否应该在活跃烹饪期间 warn 用户会短暂失去遥测?—— 待 Kevin 决定
- 代码当前:5s / 15s / 60s / 5min,在 attempts 1-3 / 4-8 / 9-18 / 19+ 分段
- 定义:
ble_device_service.dart:307-310(_reconnectDelayUltraFast/Fast/Medium/Slow)
- docstring:
ble_device_service.dart:297-300
- v4.2 规范(v4.2 第二轮):15s / 60s / 5min,在 attempts 1-5 / 6-30 / 31+ 分段
- 差异:
- 代码有额外的 ultra-fast 5s 头段(协议里没有)
- 阶段切换阈值不同(3/8/18 vs 5/30/31)
- 需决策:
- (a) 保留代码的 5s 头段(因为命中率高) → 在 v4.3 补充到规范
- (b) 改代码向规范靠拢 → 提 PR
- 🟡 待 Kevin 与 Liang 讨论
- v4.2 规范:App 在后台连续 4 小时无连接 → 降级为被动模式(不主动扫描,仅监听断开事件,锁刷新 45s 一次)
- 代码当前:grep 无
4h / 4 hour / passive.*mode 相关实现
- 🔴 待实现
¶ 3. Android onTaskRemoved 钩子 —— 未实现
- v4.2 规范 / TAPD #9:用户从最近任务划掉 App 时,应触发清理 BLE/MQTT
- 代码当前:
- Kotlin 侧(
android/.../MainActivity.kt)只重写了 onDestroy,未重写 onTaskRemoved
- Dart 侧 MethodChannel handler(
main.dart:151)已预留对 'onTaskRemoved' 的分支处理
- 原生侧
onTaskRemoved 需要 Service 子类(不是 Activity 直接重写)
- 影响:小米 / 华为 / OPPO 等激进 OEM 手机在 App 被划掉时可能 BLE/MQTT 未清理
- 🔴 待实现(TAPD #9)
- v4.2 §Q17 关切:iOS 静默撤销 BLE 权限,App 几天后连不上
- 代码当前:
BleDeviceService._ensurePermissions 在每次 BLE 操作前 lazy 检查 + 必要时重新请求(permissions_service.dart:9 注释:"re-requesting if a permission was revoked mid-session")
- 差距:
- 不是持续 watcher(不轮询)
- 只在 BLE 路径触发时才检查
- 如果用户一直不触发 BLE 操作,撤销事件不会被及时发现
- 🟡 Kevin 下一步:准备带完整 log 的 iOS 测试 app,交 Liang 诊断具体是哪个权限被撤销,再决定是否需要持续 watcher
- v4.2 §六:声称 "iOS 下 BLE 需要三个权限同时生效:Bluetooth / Location / Background App Refresh"
- 代码实现:
permissions_service.dart 只请求 Permission.bluetooth + Permission.notification
- 注释解释:"iOS uses a single bluetooth runtime permission; no location needed for BLE scan because CoreBluetooth doesn't gate it on location."
- 结论:v4.2 写错了,代码是对的
- 行动:v4.3 更新 §六的 iOS 权限说明;Background App Refresh 是系统 Setting,不是 runtime permission,不应列在 "权限请求" 清单里
- 🟡 待在 v4.3 里澄清
- #17 iOS 权限诊断 🟡
- Kevin 构建带完整协议 log 输出的 iOS 测试 app
- 交 Liang 使用 → 遇到权限撤销时导出日志
- 根据日志定位被撤销的具体权限
- #18 27 秒断线澄清 🟡
- Liang 反问:"你说的心跳指 12B 数据包还是 15B 数据包?"
- Kevin 需回复确认测量基准
- 根据回复 Liang 排查根因
- #10 CM4 设置目标温度——调用点未接线 + Fahrenheit > 99°F 边界 ⏳
- 格式已知:
cm4_protocol.dart:159 的 CM4Command.configureProbe 构造 SET_<probe>=0<unit><temp><meat><doneness>(如 SET_1=0117565)
- 调用点缺失:
cooking_page._pushTargetToDevice:761 对 CM4 早返;全代码库零 configureProbe 调用
- Spec 边界:temp 槽两位数(00-99),不够 Fahrenheit > 99°F(鸡肉 165°F),需 Liang 澄清编码
- 修复路径:transport-split 重构 C4 阶段一并接线。计划详见
REFACTOR_PLAN_TRANSPORT_SPLIT.md §6;进度追踪见 传输层重构
仅列要点,详见 v4.2 §九:
- ✅ #11-15:入仓关机行为全确认(固件硬编码定时器、不可配置、1s 内延迟正常、重开会重广播)
- ✅ #13:12B / 15B MAC 反向是固件侧便利,非错误
- ✅ #14:探针无休眠/唤醒协议,无数据即 4 种情形之一
- ✅ #16:蓝针命令字节 =
0x55B2(覆盖 Beta 先前的 0x55B1 回复)
- ❌ #19:12B 字节 6 作为静音命令 ack —— F2F 后取消,Liang 认为报警声是刚需,不改固件
- ✅ #20:12B 字节 7-8 非权威,App 只用字节 4-5 查表