15 KiB
15 KiB
蓝牙电刺激控制应用 - 工作交接文档
项目概述
项目名称
蓝牙电刺激控制应用 (SDK_APP)
项目功能
基于Android的蓝牙电刺激设备控制应用,支持多种设备类型(ESP32S3 SPP、轻迅设备、新设备),提供完整的电刺激参数控制和数据采集功能。
技术栈
- 开发语言: Kotlin
- 构建工具: Gradle
- 最低支持: Android 5.1 (API 21)
- 目标支持: Android 15 (API 35)
- 蓝牙协议: BLE + Classic Bluetooth
核心功能模块
1. 蓝牙连接管理 (BluetoothManager.kt)
1.1 设备兼容性
// 支持的设备类型
enum class DeviceType {
ESP32S3_DEVICE, // ESP32S3 SPP设备
QINGXUN, // 轻迅设备
NEW_DEVICE // 新设备
}
1.2 扫描策略
- Android 8/8.1: 混合扫描模式(BLE + 传统蓝牙)
- Android 6-11: 优先BLE,失败时回退到传统蓝牙
- Android 12+: 完整BLE扫描支持
1.3 连接流程
- 权限检查
- 蓝牙适配器初始化
- 设备扫描
- 服务发现
- 特征值订阅
- 数据通信
2. 电刺激控制协议
2.1 协议格式(19字节)
[0-1] 功能码 (0x0003)
[2-3] 数据长度 (0x000D = 13字节)
[4] 开关状态及电刺激类型
[5] 强度值
[6-7] 频率值 (小端格式)
[8-9] 总持续时间 (小端格式)
[10-11] 休息时间 (小端格式)
[12-13] 静默时间 (小端格式)
[14] 缓进时间
[15] 保持时间
[16] 缓出时间
[17-18] CRC16校验
2.2 参数控制
| 参数 | 范围 | 默认值 | 单位 | 说明 |
|---|---|---|---|---|
| 刺激类型 | 0-15 | 1 | - | 电刺激类型选择 |
| 强度 | 1-100 | 50 | % | 刺激强度百分比 |
| 频率 | 1-200 | 100 | Hz | 刺激频率 |
| 总时长 | 1-3600 | 10 | 秒 | 总刺激持续时间 |
| 休息时间 | 100-10000 | 1000 | 毫秒 | 刺激间隔休息时间 |
| 静默时间 | 100-5000 | 500 | 毫秒 | 刺激间隔静默时间 |
| 缓进时间 | 1-30 | 2 | 秒 | 刺激强度逐渐增加时间 |
| 保持时间 | 1-300 | 5 | 秒 | 刺激强度保持时间 |
| 缓出时间 | 1-30 | 2 | 秒 | 刺激强度逐渐减少时间 |
3. 数据存储功能
3.1 数据导出功能
- CSV格式导出: 支持多通道生理信号数据导出
- 文件存储: 保存到外部存储目录
- 数据格式: 包含时间戳、通道数据、统计信息
3.2 导出类型
| 导出类型 | 文件名格式 | 内容说明 |
|---|---|---|
| 单通道数据 | ECG_ChannelData_YYYYMMDD_HHMMSS.csv |
单个通道的完整数据 |
| 多通道数据 | ECG_MultiChannelData_YYYYMMDD_HHMMSS.csv |
所有通道的同步数据 |
| 波形视图数据 | ECG_WaveformData_YYYYMMDD_HHMMSS.csv |
2.5秒显示窗口数据 |
| 完整图表数据 | ECG_AllChartData_YYYYMMDD_HHMMSS.csv |
所有图表数据汇总 |
3.3 数据管理 (DataManager.kt)
- 数据解析: 使用原生方法解析蓝牙数据流
- 缓冲管理: 实时数据缓冲和回调管理
- 多回调支持: 支持多个数据接收器
4. 图表显示功能
4.1 动态图表系统 (DynamicChartView.kt)
- 实时绘制: 60fps实时数据绘制
- 多通道支持: 支持单通道和多通道数据显示
- 生产者-消费者模式: 使用队列缓冲数据,分离数据接收和显示
4.2 图表管理器 (DynamicChartManager.kt)
- 动态创建: 根据设备类型自动创建图表
- 设备配置: 不同设备类型的图表配置
- 全屏支持: 支持图表全屏显示
4.3 全屏图表 (FullscreenChartActivity.kt)
- 全屏模式: 隐藏状态栏和导航栏
- 生命体征显示: 实时显示心率和血氧
- 滤波器控制: 集成滤波器管理器
- Y轴范围设置: 支持自定义Y轴范围
4.4 图表特性
| 特性 | 说明 | 技术实现 |
|---|---|---|
| 实时更新 | 60fps刷新率 | ScheduledThreadPoolExecutor |
| 数据缓冲 | 队列容量10000点 | LinkedBlockingQueue |
| 内存管理 | 自动清理旧数据 | 定期内存检查 |
| 多通道 | 支持PPG等多通道设备 | 多通道数据队列 |
| 交互控制 | 缩放、平移 | 手势识别 |
5. 滤波器系统
5.1 滤波器管理器 (FullscreenFilterManager.kt)
- 实时滤波: 支持多种滤波器类型
- 参数调节: 可调节滤波器参数
- 性能优化: 高效的数据处理算法
5.2 支持的滤波器
- 低通滤波器: 去除高频噪声
- 高通滤波器: 去除低频漂移
- 带通滤波器: 保留特定频率范围
- 陷波滤波器: 去除工频干扰
6. 用户界面 (MainActivity.kt)
6.1 权限管理
// 动态权限请求
private val REQUIRED_PERMISSIONS: Array<String> = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// Android 12+ 使用新的蓝牙权限
arrayOf(
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_CONNECT,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Android 6-11 只需要位置权限
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
} else {
// Android 5.1及以下不需要动态权限
emptyArray()
}
6.2 电刺激控制界面
- 高级电刺激控制: 完整参数自定义
- 预设模式选择: 快速选择预设方案
- 简单开关控制: 使用默认参数
- 滑动对话框: 支持滚动查看所有参数
代码运行机制
1. 应用启动流程
graph TD
A[应用启动] --> B[MainActivity.onCreate]
B --> C[权限检查]
C --> D[蓝牙初始化]
D --> E[UI初始化]
E --> F[等待用户操作]
2. 蓝牙连接流程
graph TD
A[用户点击连接] --> B[权限检查]
B --> C{权限是否通过?}
C -->|否| D[请求权限]
C -->|是| E[开始扫描]
D --> E
E --> F[设备发现]
F --> G[选择设备]
G --> H[建立连接]
H --> I[服务发现]
I --> J[特征值订阅]
J --> K[数据通信就绪]
3. 电刺激控制流程
graph TD
A[用户选择电刺激控制] --> B[选择控制方式]
B --> C{控制方式}
C -->|高级控制| D[参数输入对话框]
C -->|预设模式| E[预设选择]
C -->|简单控制| F[快速开关]
D --> G[参数验证]
E --> G
F --> G
G --> H[构建数据包]
H --> I[发送指令]
I --> J[状态反馈]
4. 数据包构建流程
graph TD
A[接收参数] --> B[创建19字节数组]
B --> C[写入功能码]
C --> D[写入数据长度]
D --> E[写入开关状态]
E --> F[写入强度]
F --> G[写入频率]
G --> H[写入持续时间]
H --> I[写入休息时间]
I --> J[写入静默时间]
J --> K[写入缓进时间]
K --> L[写入保持时间]
L --> M[写入缓出时间]
M --> N[计算CRC16]
N --> O[发送数据包]
关键代码文件说明
1. BluetoothManager.kt - 蓝牙管理核心
主要类和方法:
BluetoothManager: 蓝牙连接管理主类startScan(): 启动设备扫描connectToDevice(): 连接指定设备stimSwitch(): 发送电刺激控制指令handleProtocolData(): 处理接收到的数据
关键特性:
- 多设备类型支持
- Android版本兼容性处理
- 混合扫描策略
- 协议数据包构建
2. MainActivity.kt - 用户界面控制
主要类和方法:
MainActivity: 主界面ActivityshowAdvancedStimDialog(): 高级电刺激控制对话框showPresetStimDialog(): 预设模式选择createSimpleInputField(): 创建输入字段checkAndRequestPermissions(): 权限检查
关键特性:
- 动态权限管理
- 滑动对话框界面
- 参数输入验证
- 状态实时反馈
3. DynamicChartView.kt - 动态图表显示
主要类和方法:
DynamicChartView: 自定义图表视图updateData(): 更新单通道数据updateMultiChannelData(): 更新多通道数据startConsumer(): 启动消费者线程stopConsumer(): 停止消费者线程
关键特性:
- 生产者-消费者模式
- 60fps实时绘制
- 多通道数据支持
- 内存管理优化
4. DynamicChartManager.kt - 图表管理器
主要类和方法:
DynamicChartManager: 图表管理主类createChartsForDevice(): 根据设备类型创建图表updateChartsData(): 更新所有图表数据getDeviceConfig(): 获取设备配置
关键特性:
- 动态图表创建
- 设备类型适配
- 全屏模式支持
5. FullscreenChartActivity.kt - 全屏图表
主要类和方法:
FullscreenChartActivity: 全屏图表ActivitysetupFullscreen(): 设置全屏模式setupFullscreenCharts(): 设置全屏图表setupVitalSignsDisplay(): 设置生命体征显示
关键特性:
- 全屏显示模式
- 生命体征实时显示
- 滤波器集成
- Y轴范围自定义
6. DataManager.kt - 数据管理
主要类和方法:
DataManager: 数据管理主类processData(): 处理原始数据setRealTimeCallback(): 设置实时数据回调addRealTimeCallback(): 添加数据回调
关键特性:
- 原生方法调用
- 多回调支持
- 数据缓冲管理
7. AndroidManifest.xml - 权限配置
权限声明:
<!-- 基础蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- Android 12+ 新蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- 位置权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
设备支持
1. ESP32S3 SPP设备
- 服务UUID: 0xABF0
- 特征值:
- 数据发送: 0xABF1, 0xABF3
- 数据接收: 0xABF2, 0xABF4
- 设备名称: ESP_SPP_SERVER
2. 轻迅设备
- 服务UUID: Nordic UART Service
- 特征值: TX/RX特征值
- 协议: 轻迅自定义协议
3. 新设备
- 服务UUID: 自定义UUID
- 特征值: 自定义特征值
- 协议: 扩展协议支持
操作指南
1. 应用启动
- 安装APK到Android设备
- 启动应用
- 检查权限状态
- 点击"连接蓝牙"开始扫描
2. 设备连接
- 确保目标设备处于可发现模式
- 点击"连接蓝牙"按钮
- 等待设备扫描完成
- 选择目标设备进行连接
3. 电刺激控制
- 连接成功后,点击"电刺激开关"
- 选择控制方式:
- 高级控制: 自定义所有参数
- 预设模式: 选择预设方案
- 简单控制: 使用默认参数
- 设置参数并确认
- 查看状态反馈
4. 图表操作
- 查看实时数据: 连接设备后自动显示图表
- 全屏模式: 点击图表右上角全屏按钮
- 数据导出:
- 点击"导出数据"按钮
- 选择导出类型(单通道/多通道/完整数据)
- 文件保存到外部存储
- 滤波器设置: 在全屏模式下使用滤波器控制
- Y轴范围: 在全屏模式下可自定义Y轴范围
5. 数据导出
- 单通道数据导出:
- 点击"导出数据" → "单通道数据"
- 选择要导出的通道
- 文件格式:CSV
- 多通道数据导出:
- 点击"导出数据" → "多通道数据"
- 导出所有通道的同步数据
- 完整数据导出:
- 点击"导出数据" → "完整数据"
- 包含所有图表和统计信息
- 文件分享: 导出完成后可选择分享或保存
6. 参数设置示例
刺激类型: 1
强度: 70%
频率: 120Hz
总时长: 30秒
休息时间: 1000ms
静默时间: 500ms
缓进时间: 2秒
保持时间: 26秒
缓出时间: 2秒
故障排除
1. 权限问题
- 现象: 显示"权限被拒绝"
- 解决: 检查应用权限设置,确保蓝牙和位置权限已授予
2. 设备扫描失败
- 现象: 找不到目标设备
- 解决:
- 确保设备处于可发现模式
- 检查蓝牙是否开启
- 尝试重启蓝牙服务
3. 连接失败
- 现象: 连接超时或失败
- 解决:
- 检查设备距离
- 确认设备未被其他应用占用
- 尝试重新扫描
4. 数据发送失败
- 现象: 电刺激指令发送失败
- 解决:
- 检查连接状态
- 验证参数范围
- 查看日志输出
5. 图表显示问题
- 现象: 图表不显示数据或显示异常
- 解决:
- 检查数据连接状态
- 重启图表显示
- 检查内存使用情况
- 查看队列大小日志
6. 数据导出失败
- 现象: 无法导出数据或文件保存失败
- 解决:
- 检查存储权限
- 确保有足够存储空间
- 检查文件路径权限
- 重启应用后重试
7. 全屏模式问题
- 现象: 全屏模式无法正常显示
- 解决:
- 检查设备屏幕方向
- 重启全屏Activity
- 检查系统UI设置
开发环境配置
1. 开发工具
- Android Studio
- Gradle 7.0+
- Android SDK API 21-35
2. 构建命令
# 编译Kotlin代码
.\gradlew.bat compileDebugKotlin
# 构建APK
.\gradlew.bat assembleDebug
# 清理项目
.\gradlew.bat clean
3. 调试方法
- 日志监控: 使用Logcat查看详细日志输出
- 蓝牙状态: 监控蓝牙连接和扫描状态
- 权限检查: 查看权限请求和授权日志
- 数据包: 监控电刺激指令发送日志
- 图表数据: 查看队列大小和数据流日志
- 内存使用: 监控内存占用和清理日志
- 数据导出: 查看文件保存和分享日志
- 全屏模式: 监控全屏切换和UI状态
版本历史
当前版本特性
- ✅ 支持Android 5.1-15
- ✅ ESP32S3 SPP设备支持
- ✅ 完整电刺激参数控制
- ✅ 滑动对话框界面
- ✅ 多设备类型兼容
- ✅ 混合扫描策略
- ✅ 权限动态管理
- ✅ 实时图表显示系统
- ✅ 多通道数据支持
- ✅ 数据导出功能
- ✅ 全屏图表模式
- ✅ 滤波器集成
- ✅ 生产者-消费者数据模式
- ✅ 内存管理优化
已知问题
7.1 动态图标显示Bug
- 问题描述: 动态图标显示的是队列大小而不是实际数据值
- 影响范围: 图表状态显示
- 技术原因: 状态更新逻辑中错误地使用了队列大小作为显示值
- 代码位置:
DynamicChartView.kt中的日志输出和状态更新 - 临时解决方案: 当前通过日志输出队列大小,需要修正为显示实际数据值
7.2 其他已知问题
- Android 8.1扫描兼容性: 部分设备扫描兼容性问题
- 设备连接稳定性: 部分设备连接稳定性待优化
- 内存使用: 长时间运行可能导致内存占用过高
- 数据同步: 多通道数据同步可能存在延迟
联系方式
如有技术问题或需要支持,请联系开发团队。
文档版本: 1.0
最后更新: 2025年1月
维护人员: 开发团队