1. 新增应用前后台状态监听,仅前台执行轮询 2. 调整轮询间隔为3秒,增加轮询空值校验 3. 新增设备配置变更检测,自动刷新主页UI
killapp —— 激光灭蚊设备控制 App
控制「激光灭害虫设备」(photonmatrix)的配套手机 App,Unity 制作,Android + iOS 双平台。 用户通过 App 完成设备绑定(BLE 扫描 + 扫码)、配网、日常控制(工作模式 / FOV / 透镜 / 补光灯 / 定时任务)、 杀蚊数据统计(柱状图 / 雷达热力图 / 杀蚊视频)、固件 OTA 升级、设备共享等。
技术栈与环境
| 项 | 值 |
|---|---|
| Unity | 2022.3.62f3c1 |
| 应用包名 | com.photonmatrix.photonmatrix(Android / iOS 相同) |
| 当前版本 | bundleVersion 1.0.7,AndroidBundleVersionCode 4(均在 ProjectSettings/ProjectSettings.asset) |
| UI 方案 | UGUI + DOTween,无 Addressables |
| 热更方案 | 自研 AssetBundle 热更(LoadRes + NetworkCtrl) |
| 第三方 | Firebase SDK(仅 Auth)、apple-signin-unity、Shatalmic BLE 插件、zxing、NativeGallery、ExternalDependencyManager |
| 主场景 | Assets/Scenes/MainScene.unity(唯一业务场景);BlueToothTest.unity 为蓝牙调试场景 |
Packages/manifest.json 非常精简(ugui、timeline、visualscripting、assetbundlebrowser、android-logcat 等),
Firebase 是以 Assets 方式导入而非 UPM。
整体架构
单场景 + 常驻 Manager + AssetBundle 动态页面:
MainScene的Manager节点挂载全部管理器:NetworkCtrl、DataManager、UIManager、LoadRes、LanguageManager、FirebaseAuthManager。Canvas/bg是页面容器,页面按 prefab 从 AssetBundle 动态加载实例化(旧的销毁、新的实例化)。- 页面逻辑全部写在 prefab 挂的 Ctrl 类里,各单例之间直接互相引用(
HomePageCtrl.Instance、DataManager.Instance等)。
启动流程(NetworkCtrl.Init()):
LoadRes.Init(AB 环境)→ 创建 HttpRequestManager / RequestQueueManager / NetworkStateManager →
从服务器查 AB 版本并差量热更下载(MD5 校验)→ DataManager.Init(token 自动登录)→ UIManager.Init(有 token 进主页,否则进登录页)。
目录结构
Assets/
├── Scenes/ MainScene(主场景)、BlueToothTest(蓝牙调试)
├── Scripts/
│ ├── Bluetooth/ BLE 核心(当前开发重点)
│ │ ├── BluetoothManager.cs Shatalmic 插件封装:扫描/连接/断开事件
│ │ ├── BLECommunicationManager.cs 协议层:指令收发、事件分发(全项目最大文件)
│ │ ├── BLEDeviceState.cs 按 MAC 隔离的设备运行状态模型
│ │ ├── OTAManager.cs 固件版本解析与升级传输
│ │ ├── Protocol/ 帧结构体 BLEProtocolStructs.cs + CRC16.cs
│ │ └── BLE通信方案V2.2.md BLE 协议文档(App ↔ BLE 透传 ↔ STM32H7 MCU)
│ ├── Core/ Loom(BLE 回调线程切主线程)、状态栏沉浸、安卓文件选择
│ ├── Managers/ DataManager / DataBase(DTO) / FirebaseAuthManager / LanguageManager / LoadRes / FireBaseCtrl(死代码)
│ ├── Network/ NetworkCtrl(门面+启动编排) / HttpRequestManager / RequestQueueManager / NetworkStateManager
│ ├── UI/
│ │ ├── UIManager.cs 页面管理、安卓返回键、token 自动登录
│ │ ├── Pages/ 各页面逻辑(Home / Login / ConnectDevice / DeviceInfo / Video / Self / Rank / Safetylearning)
│ │ └── Components/ Toast / Loading / Barchart / RadarHeatmap / SectorScanEffect / QRCode 等通用控件
│ └── Utils/ MainThread、ValidationUtils、iOSWiFiHelper
├── Res/ AB 包源资源(bluetooth / common / language / ui)
├── StreamingAssets/ 首包 AB:common.ab、language.ab、ui_common.ab + list.json
├── Plugins/ Shatalmic 运行脚本、NativeGallery、DOTween、zxing、iOS 原生桥(.mm)
├── AppleAuth/ Sign in with Apple
└── Firebase/ Firebase SDK(实际只用 Auth)
核心模块备忘
蓝牙 BLE(开发重点)
- 链路:App ↔ BLE 模块(透传,Service
FFE0,读/写/Notify 均走FFE1)↔ MCU(UART9)。 BLECommunicationManager是几十条指令的收发与事件分发中心: 注册/指纹认证、定时任务、语言、LCD/RGB、WiFi 配网、补光灯、激光、角度/距离、 毫米波雷达、视觉检测、工作模式、硬件状态、统计数据、蚊子数据等。 每条指令对应XxxRead/XxxWrite方法 +OnXxxReceived事件。- 设备主动通知(状态变化 0x01 / 错误 0x02 / 参数变化 0x06 / 蓄能 0x08 / 补光灯连接 0x09 等)
汇入
OnDeviceNotificationReceived,再按设备 MAC 隔离后广播;分支名feature/ble-config-notification即指这套「配置变更主动上报」机制。 - 设备状态保存在
BLEDeviceState(按 MAC 为边界),统一通过OnDeviceStateChanged(BLEDeviceState, BLEDeviceStateField)通知 UI。 - Shatalmic 回调来自非主线程,UI 相关处理必须
Loom.QueueOnMainThread切回主线程。 - Android/iOS 无法直接取 BLE 真实 MAC,设备 MAC 通过 BLE 命令从设备端获取(设备序列号用于绑定)。
网络与后端
- 服务器地址(配置在 MainScene 里
NetworkCtrl.serverBaseUrls): 测试https://nextreal.cn/photon-matrix-api,正式https://api.photonmatrixlab.com。 切换后门:首页左下角连点 5 次(enableServerBackdoor控制开关,发布前应置 0); 环境持久化在 PlayerPrefsnetwork_server_env。 HttpRequestManager:UnityWebRequest 封装,重试(指数退避)、SSE 流式(WiFi OTA 进度)、多平台超时。RequestQueueManager:优先级请求队列,并发上限 5。NetworkStateManager:每 3 秒轮询internetReachability,发连接/断开事件。ResponseCode:业务码统一处理,601 = Token 失效 → 全局登出。- 主要接口(
{Base}/api/v1/...):认证(login/register/email-code/token-login/firebase-bind)、 设备(bind/list/config/schedule-tasks/fingerprints/share/command)、统计上报与查询 (kill-count/records/videos/heatmap/leaderboard)、通知、OTA(latest/push/transfer 进度 SSE)、 考试、反馈、app/version/bundle(AB 热更清单)。
数据与账号
DataManager:运行时数据中枢(token、用户信息、自有/共享设备、当前选中设备、设备配置、指纹、定时任务)。 PlayerPrefs 持久化:token、userData、selectedDeviceMac、设备列表缓存ownedDevicesCache_<userId>等。DataBase.cs:纯 DTO 定义(登录/用户/设备/配置/OTA/消息/统计/考试…),非 Mono。- 第三方登录:
FirebaseAuthManager(Google 用 FederatedOAuthProvider,Apple 用 apple-signin-unity + nonce), 结果换自家后端 token(auth/firebase/bind)。旧版FireBaseCtrl.cs已无任何引用,属死代码。
UI 框架
UIManager.PageName枚举 8 个主页面:login / safetylearning / home / connectDevice / deviceInfo / self / video / rank。- 页面 prefab 按 bundle 名
ui_xxxpage从 AB 加载(配置在 MainScene 的 UIManagerpages列表)。 - 设置类子弹窗不走 UIManager,由各 Ctrl 自己 Instantiate +
RegisterBackAction(返回键栈,双击退出)。 - 首页
HomePageCtrl是功能核心:蓝牙/WiFi 双通道控制、状态订阅、 锁扣防误触(LockButtonPlane,180 秒无操作自动上锁)、下拉刷新、统计上报、跳转子页面。
资源与热更
LoadRes:编辑器「本地」模式直读Assets/Res/;真机「资源包」模式优先persistentDataPath/*.ab(热更落盘), 回退 StreamingAssets 首包;bundle 缓存在内存字典。- 热更清单来自
app/version/bundle,由NetworkCtrl做差量下载 + MD5 校验,进度显示在updateLoading。 - 语言词条也在 AB 里:
language/language.json、country.json(LanguageManager读取,PlayerPrefsLanguageType)。
其他关键组件
Loom:线程池 + 主线程队列派发(BLE 回调切主线程用)。Utils/MainThread.cs功能重复,并存。RadarHeatmap:按角度(0-180)+距离换算极坐标摆放热力点(数据来自stats/device/heatmap)。SectorScanEffect:首页扇形扫描波纹动画(fillAmount 表现 FOV、缩放表现探测距离)。iOSWiFiHelper:iOS14+ 取当前 WiFi SSID(需定位权限),配网页自动填 SSID;Android 直接读。NativeGallery:杀蚊视频保存到系统相册。
构建与发布备忘
- 版本号:
ProjectSettings/ProjectSettings.asset的bundleVersion/AndroidBundleVersionCode。 - Android 签名:
user.keystore(项目根目录)。 - iOS:
ITSAppUsesNonExemptEncryption已配置,避免每次手动答加密问卷(commit 457fee5)。 - 根目录的
*.apk/*_mapping.txt为历史构建产物(含 Release 符号表),命名习惯如photonmatrix_1.0.7_0903.apk;测试构建会带后缀如ota蓝牙优先。 - 打正式包前检查:
NetworkCtrl.enableServerBackdoor应为 0(场景内字段)。
Description