跳到主要内容

H07 智能安全帽 Android 应用

欢迎来到 H07 智能安全帽 Android 应用开发文档!

📱 项目概述

H07 (znhaas) 是一款面向智能安全帽的专业级 Android 应用,集成了蓝牙通信视频录制实时音视频文件上传定位追踪等多种先进功能,为工业安全、施工监控等场景提供完整的解决方案。

项目信息

  • 项目名称: H07 Android App
  • 包名: android.znhaas
  • 目标 Android 版本: API 33 (Android 13)
  • 最低 Android 版本: API 24 (Android 7.0)
  • 开发语言: Kotlin (90%+), Java, C/C++
  • 架构模式: MVVM + 分层架构

🏗️ 系统逻辑架构

H07 应用采用模块化分层架构,各模块通过MQTT消息总线本地事件总线进行通信,实现松耦合、高内聚的设计。

整体架构图

┌─────────────────────────────────────────────────────────────────────┐
│ H07 智能安全帽应用 │
│ (MainActivity + Services) │
└───────────────────────────┬─────────────────────────────────────────┘

┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ 通讯层 │ │ 媒体层 │ │ 业务层 │
│ (Communication)│ │ (Media) │ │ (Business) │
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
│ │ │
├─ MQTT通讯 ├─ 拍照模块 ├─ 文件上传
├─ 串口通讯 ├─ 本地录屏 ├─ 性能监控
├─ 蓝牙SPP ├─ 实时音视频 ├─ 语音播报
├─ 蓝牙A2DP │ (LiveKit) ├─ 定位服务
├─ 蓝牙HFP └─ 水印处理 └─ OTA升级
├─ 蓝牙BLE
└─ NTRIP差分

┌───────────┴───────────┐
│ │
▼ ▼
┌───────────────┐ ┌───────────────┐
│ 消息总线 │ │ 数据存储 │
│ (Message Bus) │ │ (Storage) │
└───────────────┘ └───────────────┘
│ │
├─ MQTT Broker ├─ SharedPreferences
├─ EventBus ├─ 文件系统
└─ Handler/Callback └─ 数据库(可选)

核心组件及其关系

1. 中央控制器 (MainActivity)

MainActivity 是整个应用的核心枢纽,负责:

  • 🎯 初始化所有模块 (MQTT、录制、上传、定位等)
  • 📡 MQTT消息路由 (接收远程指令并分发到对应模块)
  • 🔄 模块间协调 (录像时暂停上传、推流时暂停录制等)
  • 📊 状态管理 (LiveData/StateFlow)
MainActivity
├─ 初始化 MqttClient // MQTT消息总线
├─ 初始化 RecordingService // 视频录制服务
├─ 初始化 UploadUtil // 文件上传管理
├─ 初始化 LiveKitManager // 实时音视频
├─ 初始化 LocationService // 定位服务
├─ 初始化 TtsManager // 语音播报
└─ 监听 MQTT消息 // 远程指令分发

2. 通讯层:消息总线与数据传输

通讯层是所有模块的神经中枢,负责设备与云端、设备与外设之间的通信。

MQTT通讯 - 核心消息总线

云端服务器 (MQTT Broker)

│ MQTT协议 (QoS 0/1/2)

MqttClient (设备端)

├─→ 订阅主题 (Subscribe)
│ ├─ cmd/{deviceId} // 远程指令
│ ├─ config/{deviceId} // 配置更新
│ └─ broadcast/all // 广播消息

└─→ 发布主题 (Publish)
├─ device/{deviceId}/location // GPS位置上报
├─ device/{deviceId}/status // 设备状态
├─ alarm/{deviceId} // 报警事件
├─ ack/{deviceId} // 指令响应
└─ MINIO/{clientName}/{deviceId} // 上传Token请求

远程指令处理流程:

1. 云端发送指令 → MQTT Broker
2. MqttClient 接收消息 → MainActivity.messageArrived()
3. 解析指令码 (command)
4. 分发到对应模块:
- 8001 → RecordingService.startRecording() // 开始/停止录像
- 8003 → CameraUtil.takePhoto() // 拍照
- 9527/9528 → LiveKitManager.startStream() // 推流
- 8006 → TtsManager.speak() // TTS播报
- 8007 → OTAUpdateManager.startUpdate() // OTA升级
- 8002 → ConfigManager.updateConfig() // 配置更新
5. 执行完成后发送响应 → ack/{deviceId}

蓝牙通讯 - 本地外设连接

外部设备 (蓝牙设备)

├─ SPP串口 → BluetoothSppManager
│ ├─ 读取外设数据
│ └─ 发送控制指令

├─ A2DP音频 → BluetoothA2dpManager
│ └─ 音频流传输

├─ HFP免提 → BluetoothHfpManager
│ └─ 电话功能

└─ BLE低功耗 → BluetoothBleManager
└─ 低功耗设备通信

串口通讯 - 硬件直连

硬件设备 (/dev/ttyS*)

├─ 串口读取 → SerialPort.read()
│ └─ 解析硬件数据

└─ 串口写入 → SerialPort.write()
└─ 发送控制指令

NTRIP差分数据 - RTK高精度定位

NTRIP Caster (差分数据服务器)

├─ GGA位置报告 → NtripClient.sendGGA()

└─ RTCM差分数据 ← NtripClient.receiveRTCM()
└─ 传递给GPS模块 (通过串口/蓝牙)

3. 媒体层:视频、音频、图像处理

媒体层负责所有多媒体数据的采集、处理和传输。

拍照模块

CameraX (Camera API)

├─ 初始化相机 → CameraUtil.initCamera()
├─ 拍照 → CameraUtil.takePhoto()
│ ├─ 添加GPS水印 (Overlay)
│ ├─ 添加设备ID水印
│ └─ 保存到文件系统

└─ 照片文件 → /storage/Photo/20250119_143022.jpg
└─ 触发自动上传

本地录屏模块

RecordingService (前台服务)

├─ 启动录像 → startRecording()
│ ├─ CameraX视频录制
│ ├─ MediaRecorder音频录制
│ ├─ OpenGL水印渲染
│ │ ├─ 设备ID
│ │ ├─ 时间戳
│ │ └─ GPS坐标
│ └─ 分段保存 (5分钟/段)

├─ 停止录像 → stopRecording()
│ └─ 合并分段视频(可选)

└─ 录像文件 → /storage/Video/20250119_143520.mp4
└─ 触发自动上传

实时音视频 (LiveKit)

LiveKit Room (WebRTC SFU)

├─ 连接房间 → LiveKitManager.connect()
│ ├─ 获取Token (MQTT 9527指令)
│ ├─ 连接WebSocket
│ └─ 建立P2P连接

├─ 发布音视频流 → publishTracks()
│ ├─ 视频轨道 (CameraX)
│ │ ├─ 自定义水印处理器
│ │ │ ├─ GPU加速 (OpenGL)
│ │ │ ├─ 设备ID + GPS + 时间
│ │ │ └─ 自适应码率/分辨率
│ │ └─ 硬件编码 (H.264)
│ │
│ └─ 音频轨道 (Microphone)
│ ├─ 回声消除 (AEC)
│ ├─ 噪声抑制 (NS)
│ └─ 反馈检测与抑制

├─ 订阅远端流 → subscribeToRemoteTracks()
│ └─ 播放远端音视频

└─ 断开连接 → disconnect()

音视频处理流程对比

场景本地录屏实时音视频 (LiveKit)
用途事后回放、证据保存实时通信、远程协作
延迟无关小于500ms
存储本地文件系统不保存(可选云端录制)
网络离线可用需要稳定网络
处理OpenGL水印GPU水印 + 自适应码率
触发MQTT 8001指令MQTT 9527/9528指令

4. 业务层:文件管理、定位、监控

业务层提供各种辅助功能,支撑核心业务流程。

文件上传 - 自动化数据同步

UploadUtil + GlobalTimerManager

├─ 定时检查 (每60秒)
│ ├─ 检查上传开关 (WiFi/数据)
│ ├─ 检查录像/推流状态 (高内存模式时暂停)
│ └─ 扫描本地文件 (Photo/Video目录)

├─ 请求上传Token (MQTT 0017)
│ └─ 接收Token (MQTT 8017)

├─ 小文件上传 (照片 <5MB)
│ └─ 单次HTTP Multipart上传

├─ 大文件上传 (视频 >10MB)
│ ├─ 分片上传 (ResumableUploadUtil)
│ │ ├─ 文件切分 (2MB/片)
│ │ ├─ 顺序上传分片
│ │ ├─ 进度持久化 (SharedPreferences)
│ │ └─ 断点续传 (网络恢复后继续)
│ ├─ 合并分片 (服务器端)
│ └─ MQTT确认 (8018)

├─ 并发控制 (最多5个文件同时上传)

└─ 上传成功处理
├─ 删除文件 (deleteAfterUpload=true)
└─ 添加标识 (_uploaded后缀)

上传与录制的协调机制:

状态检查 → RecordingService.isRecording?

├─ Yes → UploadUtil.setRecordingState(true)
│ ├─ 取消当前上传
│ ├─ 清空上传队列
│ └─ 定时任务跳过

└─ No → UploadUtil.setRecordingState(false)
└─ 恢复自动上传

定位服务 - 位置追踪与上报

多源定位系统 (按优先级)

├─ 1. UWB室内定位 (最高优先级)
│ ├─ 精度: 10-50厘米
│ ├─ 通过串口接收外接UWB设备数据
│ ├─ 三维定位: 经纬度 + 相对坐标(X,Y,Z)
│ ├─ 一维定位: 基站距离测量
│ ├─ 数据有效期: 20秒
│ └─ locationType = 7

├─ 2. RTK高精度定位 (室外)
│ ├─ 精度: 厘米级
│ ├─ NTRIP差分数据
│ ├─ GGA位置报告
│ └─ locationType = 4

├─ 3. GPS定位 (标准)
│ ├─ 精度: 5-10米
│ ├─ LocationManager (GNSS)
│ ├─ 更新频率: 1秒
│ └─ locationType = 1

├─ 4. 网络定位 (备用)
│ ├─ 精度: 50-500米
│ ├─ 基站 + WiFi
│ └─ locationType = 6

└─ 位置上报 (MQTT)
├─ 定时上报 (每10秒)
├─ Topic: device/{deviceId}/location
├─ 包含: lat, lon, alt, accuracy, speed
├─ UWB扩展: uwbPos, uwbRange, floor
└─ 自动降级: UWB→RTK→GPS→Network

语音播报 - 事件通知

TtsManager + SoundPlayer

├─ TTS语音播报
│ ├─ 远程TTS (MQTT 8006)
│ │ └─ 云端下发文本 → 本地播报
│ └─ 本地TTS
│ └─ TextToSpeech.speak()

└─ 音频播报
├─ 跌倒报警 → SoundPlayer.playWav(FALL_WAV)
├─ 脱帽报警 → SoundPlayer.playWav(HAT_OFF_WAV)
├─ 高温报警 → SoundPlayer.playWav(HIGH_TEMP_WAV)
└─ 系统提示音 → SoundPlayer.playWav(SYSTEM_WAV)

性能监控 - 硬件降本分析

PerformanceMonitor

├─ 实时采样 (每5秒)
│ ├─ 内存指标
│ │ ├─ Total PSS (进程实际占用)
│ │ ├─ Java Heap (JVM堆内存)
│ │ └─ Native Heap (C/C++内存)
│ │
│ └─ CPU指标
│ ├─ CPU使用率 (/proc/stat)
│ └─ 线程数 (Thread.activeCount)

├─ 阈值报警
│ ├─ 内存 > 512MB → 警告
│ ├─ 内存 > 1024MB → 严重警告
│ ├─ CPU > 50% → 警告
│ └─ CPU > 80% → 严重警告

├─ 性能报告
│ ├─ 平均值、峰值
│ └─ 警告次数

└─ 硬件降本建议
├─ 内存峰值 + 30%安全余量
├─ CPU峰值判断核心数
└─ 评估风险等级 (LOW/MEDIUM/HIGH)

典型业务流程

流程1: 远程启动录像

1. 云端发送指令
├─ MQTT Publish: cmd/{deviceId}
└─ Payload: {"cmd": "8001", "action": "start"}

2. MainActivity接收消息
├─ messageArrived() 回调
└─ 解析command = "8001"

3. 分发到录像服务
├─ RecordingService.startRecording()
├─ 暂停文件上传 (避免资源竞争)
│ └─ UploadUtil.setRecordingState(true)
├─ 初始化CameraX
├─ 开始视频录制
│ ├─ 添加OpenGL水印
│ └─ 5分钟自动分段
└─ 显示录像通知

4. 发送响应
├─ MQTT Publish: ack/{deviceId}
└─ Payload: {"cmd": "8001", "status": "success"}

5. 录像停止
├─ MQTT指令: {"cmd": "8001", "action": "stop"}
├─ RecordingService.stopRecording()
├─ 保存视频文件
├─ 恢复文件上传
│ └─ UploadUtil.setRecordingState(false)
└─ 自动上传录像文件

流程2: 文件自动上传

1. 定时任务触发 (每60秒)
└─ GlobalTimerManager → FileUploadTimerTask

2. 检查上传条件
├─ 上传开关已启用? (WiFi/数据)
├─ 不在录像中? (isRecording = false)
├─ 不在推流中? (isStreaming = false)
└─ 有可上传文件? (扫描Photo/Video目录)

3. 请求上传Token
├─ MQTT Publish: MINIO/{clientName}/{deviceId}
├─ Command: 0017
└─ 等待响应 (8017)

4. 接收Token
├─ MQTT消息: command = "8017"
├─ 保存Token
└─ 开始批量上传

5. 上传文件
├─ 照片 (<5MB) → 单次上传
│ └─ HTTP Multipart to https://server:2443/resumabletransfer/singleupload

└─ 视频 (>10MB) → 分片上传
├─ 切分文件 (2MB/片)
├─ 逐片上传 (顺序)
│ └─ POST https://server:2443/resumabletransfer/upload
├─ 合并分片
│ └─ POST https://server:2443/resumabletransfer/merge
└─ 等待MQTT确认 (8018)

6. 上传完成
├─ 删除本地文件 (deleteAfterUpload=true)
└─ 或添加_uploaded后缀

流程3: 实时音视频通话

1. 云端发起通话
├─ MQTT Publish: cmd/{deviceId}
└─ Payload: {"cmd": "9527", "webrtc_server": "wss://...", "token": "..."}

2. MainActivity接收并启动LiveKit
├─ 暂停录像 (避免资源竞争)
│ └─ RecordingService.stopRecording()
├─ 暂停上传
│ └─ UploadUtil.setStreamingState(true)
└─ LiveKitManager.connect()

3. LiveKit连接流程
├─ 解析WebRTC服务器地址
├─ 连接LiveKit Room
├─ 发布本地音视频轨道
│ ├─ 视频: CameraX + GPU水印
│ │ ├─ 设备ID + GPS + 时间
│ │ └─ H.264硬件编码
│ └─ 音频: Microphone + AEC/NS
└─ 订阅远端音视频轨道

4. 实时通信
├─ 本地视频 → WebRTC → 云端
├─ 云端视频 → WebRTC → 本地播放
├─ 延迟: <500ms (公网), <100ms (局域网)
└─ 自适应码率/分辨率

5. 结束通话
├─ MQTT指令: {"cmd": "9528"}
├─ LiveKitManager.disconnect()
├─ 恢复录像
└─ 恢复上传
└─ UploadUtil.setStreamingState(false)

流程4: 多源定位实时上报 (UWB/RTK/GPS)

1. 定位服务初始化
├─ NativeLocationService.getInstance() (GPS)
├─ SerialPort.open() (UWB设备)
└─ NtripManager.connect() (RTK差分,可选)

2. 多源定位数据采集
├─ UWB定位 (串口接收)
│ ├─ UWB三维数据: 经纬度 + X,Y,Z坐标
│ ├─ UWB一维数据: 基站距离列表
│ ├─ 更新到MqttTimerManager
│ └─ 数据有效期: 20秒

├─ RTK定位 (NTRIP接收)
│ ├─ 接收RTCM差分数据
│ ├─ 计算固定解 (厘米级)
│ └─ 串口输出到GPS模块

└─ GPS定位 (LocationManager)
├─ 卫星定位 (每1秒)
└─ 网络定位 (基站+WiFi)

3. 定位源选择 (按优先级)
├─ 1. UWB有效? (20秒内更新)
│ └─ 使用UWB数据 (locationType=7)

├─ 2. RTK固定解? (fixLevel=4)
│ └─ 使用RTK数据 (locationType=4)

├─ 3. GPS可用?
│ └─ 使用GPS数据 (locationType=1)

└─ 4. 网络定位
└─ 使用Network数据 (locationType=6)

4. 定时上报 (每10秒)
├─ 构造位置数据
│ ├─ 基础字段
│ │ ├─ latitude (纬度)
│ │ ├─ longitude (经度)
│ │ ├─ altitude (海拔)
│ │ ├─ accuracy (精度)
│ │ ├─ speed (速度)
│ │ └─ locationType (定位类型)
│ │
│ └─ UWB扩展字段 (如果使用UWB)
│ ├─ floor: 楼层ID
│ ├─ uwbPos: "X,Y,Z,FloorID" (cm)
│ └─ uwbRange: "基站ID,距离,..." (cm)

└─ MQTT Publish
├─ Topic: device/{deviceId}/location
├─ QoS: 0 (允许丢失,降低网络开销)
└─ 云端接收并存储轨迹

5. 位置数据应用
├─ 录像水印 (显示GPS/UWB坐标)
├─ 推流水印 (显示GPS/UWB坐标)
├─ 照片EXIF (嵌入GPS信息)
├─ 云端地图显示 (实时追踪)
│ ├─ 室外: 使用GPS经纬度
│ └─ 室内: 使用UWB相对坐标(楼层平面图)
└─ 电子围栏 (基于UWB室内定位)

流程5: 报警事件处理

1. 传感器检测到异常
├─ 跌倒检测 (加速度传感器)
├─ 脱帽检测 (接触传感器)
└─ 高温检测 (温度传感器)

2. 触发报警
├─ 播放报警音
│ └─ SoundPlayer.playWav(FALL_WAV)
├─ TTS语音提示
│ └─ TtsManager.speak("检测到跌倒!")
└─ 构造报警数据

3. 上报云端 (MQTT)
├─ Topic: alarm/{deviceId}
├─ QoS: 2 (必须送达,确保报警不丢失)
└─ Payload:
{
"alarmType": "FALL_ALARM",
"alarmCode": "1002",
"latitude": 39.9042,
"longitude": 116.4074,
"timestamp": 1737353000000,
"severity": "HIGH"
}

4. 云端处理
├─ 接收报警
├─ 推送给监控人员
├─ 触发应急响应
└─ 发送MQTT指令 (可选)
├─ 开始录像 (8001)
├─ 开始推流 (9527)
└─ TTS播报 (8006)

5. 失败重试 (指数退避)
├─ 第1次: 延迟1秒重试
├─ 第2次: 延迟2秒重试
└─ 第3次: 延迟3秒重试

✨ 核心功能模块

🔵 通讯模块

子模块功能文档链接
MQTT通讯消息总线,远程指令,数据上报查看文档
串口通讯硬件设备直连查看文档
NTRIP差分RTK高精度定位数据传输查看文档
蓝牙SPP串口协议,外设通信查看文档
蓝牙A2DP高品质音频流传输查看文档
蓝牙HFP免提电话功能查看文档
蓝牙耳机蓝牙音频路由管理查看文档
蓝牙BLE低功耗设备通信查看文档

📷 媒体模块

子模块功能文档链接
拍照CameraX拍照,GPS水印查看文档
本地录屏分段录制,OpenGL水印,自动上传查看文档
实时音视频LiveKit WebRTC实时通信查看文档

🔊 语音播报

子模块功能文档链接
音频播报报警音播放,系统提示音查看文档
TTS语音播报文字转语音,远程播报查看文档

📍 定位模块

子模块功能文档链接
GPS/RTK/UWB多源定位,高精度RTK查看文档

📤 文件上传

子模块功能文档链接
文件上传定时检查,分段上传,断点续传查看文档

📊 性能监控

子模块功能文档链接
性能监控内存/CPU监控,硬件降本分析查看文档

🎯 技术架构

核心技术栈

技术版本用途
Kotlin1.9.0+主要开发语言
Jetpack Compose1.5.0+UI 框架
CameraX1.3.0+相机管理
Hilt2.48+依赖注入
Coroutines1.7.0+异步编程
LiveKit SDK1.1.0+实时通信
Eclipse Paho MQTT1.2.5MQTT客户端
OkHttp4.10.0HTTP客户端
FFmpeg4.4+音视频处理

架构分层

┌─────────────────────────────────────────────┐
│ UI 层 (Compose + MVVM) │
│ - MainActivity, Fragment, Composable │
│ - ViewModel, LiveData, StateFlow │
└─────────────────┬───────────────────────────┘

┌─────────────────┴───────────────────────────┐
│ Service 层 (后台服务) │
│ - RecordingService (录像) │
│ - LocationService (定位) │
│ - GlobalTimerManager (定时任务) │
└─────────────────┬───────────────────────────┘

┌─────────────────┴───────────────────────────┐
│ Business 层 (业务管理器) │
│ - MqttClient, UploadUtil, LiveKitManager │
│ - BluetoothManager, TtsManager │
│ - PerformanceMonitor │
└─────────────────┬───────────────────────────┘

┌─────────────────┴───────────────────────────┐
│ Data 层 (数据模型) │
│ - Models, Entities, DTOs │
│ - SharedPreferences, File Storage │
└─────────────────────────────────────────────┘

设计原则

  1. 模块化: 每个功能模块独立封装,职责单一
  2. 松耦合: 通过MQTT消息总线和回调接口解耦
  3. 高内聚: 相关功能聚合在同一模块内
  4. 可扩展: 易于添加新功能模块
  5. 可测试: 依赖注入,便于单元测试

📋 系统要求

项目要求
Android 版本Android 7.0 (API 24) 及以上
推荐版本Android 13 (API 33) 及以上
相机支持 Camera2 API
蓝牙支持蓝牙 4.0 及以上
网络WiFi 或 4G/5G (推荐WiFi用于视频上传)
GPS支持GPS定位 (RTK需外接设备)

🎯 应用场景

工业安全

  • 🏗️ 施工现场监控 - 实时视频监控,轨迹追踪
  • 👷 工人安全追踪 - 跌倒检测,脱帽报警,定位追踪
  • ⚠️ 危险环境预警 - 高温报警,气体检测,语音播报

远程协作

  • 📹 实时视频通信 - LiveKit低延迟通话
  • 🗣️ 远程技术指导 - 双向音视频,实时标注
  • 👥 团队语音通信 - 多人通话,广播通知

数据记录

  • 🎥 工作视频录制 - 自动分段录制,GPS水印
  • 📍 GPS轨迹追踪 - 实时位置上报,历史轨迹
  • 📊 事件日志管理 - 报警记录,操作日志

智能管理

  • 📤 自动文件上传 - 断点续传,智能调度
  • 📡 远程控制 - MQTT指令,即时响应
  • 📈 性能监控 - 资源使用监控,硬件降本分析

📚 快速导航

新手入门

  1. 快速开始 - 5分钟快速上手

模块文档

🔄 项目状态

模块状态说明
MQTT通讯✅ 完成生产就绪
蓝牙SPP✅ 完成生产就绪
蓝牙A2DP✅ 完成生产就绪
蓝牙HFP✅ 完成生产就绪
蓝牙BLE✅ 完成生产就绪
串口通讯✅ 完成生产就绪
NTRIP差分✅ 完成生产就绪
本地录屏✅ 完成分段录制+水印
拍照功能✅ 完成GPS水印
LiveKit音视频✅ 完成WebRTC实时通信
文件上传✅ 完成断点续传
定位服务✅ 完成GPS/RTK
语音播报✅ 完成TTS+音频播报
性能监控✅ 完成资源监控+降本分析

🤝 贡献

我们欢迎社区贡献!请查看各模块文档了解详细的技术实现。

📞 技术支持

  • 文档问题: 请在文档对应页面提出
  • 功能建议: 欢迎提交功能建议

准备好了吗? 让我们从 快速开始 开始吧! 🚀