# 蓝牙电刺激控制应用 - 工作交接文档

## 项目概述

### 项目名称
蓝牙电刺激控制应用 (SDK_APP)

### 项目功能
基于Android的蓝牙电刺激设备控制应用，支持多种设备类型（ESP32S3 SPP、轻迅设备、新设备），提供完整的电刺激参数控制和数据采集功能。

### 技术栈
- **开发语言**: Kotlin
- **构建工具**: Gradle
- **最低支持**: Android 5.1 (API 21)
- **目标支持**: Android 15 (API 35)
- **蓝牙协议**: BLE + Classic Bluetooth

---

## 核心功能模块

### 1. 蓝牙连接管理 (`BluetoothManager.kt`)

#### 1.1 设备兼容性
```kotlin
// 支持的设备类型
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 连接流程
1. 权限检查
2. 蓝牙适配器初始化
3. 设备扫描
4. 服务发现
5. 特征值订阅
6. 数据通信

### 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 权限管理
```kotlin
// 动态权限请求
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. 应用启动流程

```mermaid
graph TD
    A[应用启动] --> B[MainActivity.onCreate]
    B --> C[权限检查]
    C --> D[蓝牙初始化]
    D --> E[UI初始化]
    E --> F[等待用户操作]
```

### 2. 蓝牙连接流程

```mermaid
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. 电刺激控制流程

```mermaid
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. 数据包构建流程

```mermaid
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`: 主界面Activity
- `showAdvancedStimDialog()`: 高级电刺激控制对话框
- `showPresetStimDialog()`: 预设模式选择
- `createSimpleInputField()`: 创建输入字段
- `checkAndRequestPermissions()`: 权限检查

#### 关键特性：
- 动态权限管理
- 滑动对话框界面
- 参数输入验证
- 状态实时反馈

### 3. `DynamicChartView.kt` - 动态图表显示

#### 主要类和方法：
- `DynamicChartView`: 自定义图表视图
- `updateData()`: 更新单通道数据
- `updateMultiChannelData()`: 更新多通道数据
- `startConsumer()`: 启动消费者线程
- `stopConsumer()`: 停止消费者线程

#### 关键特性：
- 生产者-消费者模式
- 60fps实时绘制
- 多通道数据支持
- 内存管理优化

### 4. `DynamicChartManager.kt` - 图表管理器

#### 主要类和方法：
- `DynamicChartManager`: 图表管理主类
- `createChartsForDevice()`: 根据设备类型创建图表
- `updateChartsData()`: 更新所有图表数据
- `getDeviceConfig()`: 获取设备配置

#### 关键特性：
- 动态图表创建
- 设备类型适配
- 全屏模式支持

### 5. `FullscreenChartActivity.kt` - 全屏图表

#### 主要类和方法：
- `FullscreenChartActivity`: 全屏图表Activity
- `setupFullscreen()`: 设置全屏模式
- `setupFullscreenCharts()`: 设置全屏图表
- `setupVitalSignsDisplay()`: 设置生命体征显示

#### 关键特性：
- 全屏显示模式
- 生命体征实时显示
- 滤波器集成
- Y轴范围自定义

### 6. `DataManager.kt` - 数据管理

#### 主要类和方法：
- `DataManager`: 数据管理主类
- `processData()`: 处理原始数据
- `setRealTimeCallback()`: 设置实时数据回调
- `addRealTimeCallback()`: 添加数据回调

#### 关键特性：
- 原生方法调用
- 多回调支持
- 数据缓冲管理

### 7. `AndroidManifest.xml` - 权限配置

#### 权限声明：
```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. 应用启动
1. 安装APK到Android设备
2. 启动应用
3. 检查权限状态
4. 点击"连接蓝牙"开始扫描

### 2. 设备连接
1. 确保目标设备处于可发现模式
2. 点击"连接蓝牙"按钮
3. 等待设备扫描完成
4. 选择目标设备进行连接

### 3. 电刺激控制
1. 连接成功后，点击"电刺激开关"
2. 选择控制方式：
   - **高级控制**: 自定义所有参数
   - **预设模式**: 选择预设方案
   - **简单控制**: 使用默认参数
3. 设置参数并确认
4. 查看状态反馈

### 4. 图表操作
1. **查看实时数据**: 连接设备后自动显示图表
2. **全屏模式**: 点击图表右上角全屏按钮
3. **数据导出**: 
   - 点击"导出数据"按钮
   - 选择导出类型（单通道/多通道/完整数据）
   - 文件保存到外部存储
4. **滤波器设置**: 在全屏模式下使用滤波器控制
5. **Y轴范围**: 在全屏模式下可自定义Y轴范围

### 5. 数据导出
1. **单通道数据导出**:
   - 点击"导出数据" → "单通道数据"
   - 选择要导出的通道
   - 文件格式：CSV
2. **多通道数据导出**:
   - 点击"导出数据" → "多通道数据"
   - 导出所有通道的同步数据
3. **完整数据导出**:
   - 点击"导出数据" → "完整数据"
   - 包含所有图表和统计信息
4. **文件分享**: 导出完成后可选择分享或保存

### 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. 构建命令
```bash
# 编译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月  
**维护人员**: 开发团队
