# 蓝牙BLE模块集成说明

## 目录结构

    capability-ble/src/
    └── main/
        ├── AndroidManifest.xml          # Android 清单文件（权限声明）
        └── java/
            └── com/narutohuo/xindazhou/ble/
                ├── api/                  # API 接口层
                │   └── BLEService.kt    # 蓝牙服务接口定义
                ├── factory/              # 工厂类层
                │   └── BLEServiceFactory.kt  # 服务工厂（统一入口）
                ├── impl/                 # 实现层
                │   └── BLEServiceImpl.kt     # 蓝牙服务具体实现（单例模式）
                ├── callback/             # 回调接口层
                │   └── BLECallback.kt         # 蓝牙回调接口（包含 ConnectCallback、HandshakeCallback、CommandCallback、DataCallback）
                ├── config/               # 配置层
                │   └── BLEConstants.kt         # 蓝牙常量定义（用户类型、功能码、UUID等）
                ├── model/                # 数据模型层
                │   ├── BLEDevice.kt          # BLE设备模型
                │   ├── BLECommand.kt          # BLE指令模型（包含 AppControlInstruction、SystemControlInstruction）
                │   ├── BLEResponse.kt         # BLE响应模型
                │   └── Command.kt             # 指令协议数据类
                └── util/                 # 工具类层
                    ├── BleScanner.kt          # BLE扫描工具
                    ├── BleConnector.kt         # BLE连接工具
                    ├── BLECrypto.kt            # 加密解密工具（AES）
                    ├── BLEPacketBuilder.kt    # 协议包构建工具
                    ├── BLEPacketParser.kt     # 协议包解析工具
                    ├── BLEPacketSplitter.kt   # 协议包分包工具
                    └── BlePacketSender.kt     # 协议包发送工具

## 功能说明

### 1. api/ 层 - 接口定义

- 职责：定义蓝牙服务的公共接口，业务层只依赖接口
- 内容：`BLEService` 接口
  - 基础连接功能：
    - `startScan()` - 开始扫描BLE设备
    - `stopScan()` - 停止扫描
    - `connect()` - 连接设备（自动完成握手）
    - `disconnect()` - 断开连接
    - `isConnected()` - 检查连接状态
  - 协议封装功能：
    - `sendCommand()` - 发送自定义指令
    - `sendAppControlCommand()` - 发送应用控制指令
    - `sendSystemControlCommand()` - 发送系统控制指令
    - `queryVehicleInfo()` - 查询车辆信息
  - 便捷方法：
    - `setDefense()`, `powerOn()`, `powerOff()`, `findCar()`
    - `unlockSeat()`, `unlockHandlebar()`, `lockHandlebar()`
    - `unlockTrunk()`, `lockTrunk()`
    - `setSensorUnlock()`, `setAmbientLight()`, `setAmbientLightColor()`
    - `setAutoPowerOffTime()`, `setSpeakerVolume()`
  - 数据接收监听：
    - `setDataReceivedListener()` - 设置数据接收监听器

### 2. factory/ 层 - 工厂类

- 职责：提供统一的服务实例获取方式
- 内容：`BLEServiceFactory` 对象（单例）
- 作用：
  - 隐藏实现细节，统一入口
  - 提供 `create(context)` 方法获取服务实例

### 3. impl/ 层 - 具体实现

- 职责：实现 `BLEService` 接口的具体逻辑
- 内容：`BLEServiceImpl` 单例实现类
- 功能：
  - 封装 Android BLE SDK 调用
  - 封装 GATT 连接管理
  - 封装握手认证（连接时自动完成）
  - 封装数据分包和组包
  - 封装 AES 加密/解密
  - 封装协议包构建和解析

### 4. model/ 层 - 数据模型

- 职责：定义蓝牙相关的数据模型
- 内容：
  - `BLEDevice` - BLE设备模型
  - `BLECommand` - BLE指令模型
  - `BLEResponse` - BLE响应模型
  - `Command` - 指令协议数据类
  - `AppControlInstruction` - 应用控制指令常量（对象）
  - `SystemControlInstruction` - 系统控制指令常量（对象）

### 5. callback/ 层 - 回调接口

- 职责：定义蓝牙相关的回调接口
- 内容：
  - `BLECallback.kt` 文件中包含：
    - `ConnectCallback` - 连接回调接口
    - `HandshakeCallback` - 握手指令回调接口
    - `CommandCallback` - 指令发送回调接口
    - `DataCallback` - 数据接收回调接口

### 6. config/ 层 - 配置

- 职责：定义蓝牙相关的常量配置
- 内容：
  - `BLEConstants` - 蓝牙常量定义（用户类型、功能码、UUID等）

### 7. util/ 层 - 工具类

- 职责：提供蓝牙相关的工具方法
- 内容：
  - `BleScanner` - BLE扫描工具
  - `BleConnector` - BLE连接工具
  - `BLECrypto` - 加密解密工具
  - `BLEPacketBuilder` - 协议包构建工具
  - `BLEPacketParser` - 协议包解析工具
  - `BLEPacketSplitter` - 协议包分包工具
  - `BlePacketSender` - 协议包发送工具

## 架构设计

- 接口隔离：业务层只依赖接口，不依赖实现
- 工厂模式：统一入口，隐藏创建逻辑
- 单例模式：`BLEServiceImpl` 使用单例模式，全局共享同一个连接状态
- 完全封装：所有底层细节（连接、握手、分包、加密等）都在能力层内部完成

## 使用方式

### 完整示例（单例模式）

    import androidx.fragment.app.Fragment
    import android.widget.Toast
    import com.narutohuo.xindazhou.ble.factory.BLEServiceFactory
    import com.narutohuo.xindazhou.ble.api.BLEService
    import com.narutohuo.xindazhou.ble.config.BLEConstants

    class VehicleFragment : Fragment() {

        // 1. 获取单例实例（全局只有一个，在任何地方获取的都是同一个）
        private val bleService: BLEService = BLEServiceFactory.create(requireContext())

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)

            // 2. 连接设备（一键完成扫描+连接+握手）
            connectDevice()
        }

        private fun connectDevice() {
            // 获取用户信息（实际项目中从用户认证信息中获取）
            val userId = getUserId() // 16字节
            val userType = BLEConstants.USER_TYPE_OWNER // 0x02=车主

            bleService.initializeAndConnect(
                userId = userId,
                userType = userType,
                onConnected = {
                    activity?.runOnUiThread {
                        // 连接成功，可以直接使用指令了
                        Toast.makeText(context, "连接成功", Toast.LENGTH_SHORT).show()
                    }
                },
                onError = { error ->
                    activity?.runOnUiThread {
                        Toast.makeText(context, "连接失败: $error", Toast.LENGTH_SHORT).show()
                    }
                }
            )
        }

        // 3. 发送指令（连接成功后调用）
        private fun lockCar() {
            // 设防
            bleService.setDefense(enabled = true) { response ->
                activity?.runOnUiThread {
                    if (response.success) {
                        Toast.makeText(context, "设防成功", Toast.LENGTH_SHORT).show()
                    } else {
                        Toast.makeText(context, "设防失败: ${response.errorMessage}", Toast.LENGTH_SHORT).show()
                    }
                }
            }
        }

        private fun powerOn() {
            // 上电
            bleService.powerOn { response ->
                activity?.runOnUiThread {
                    if (response.success) {
                        Toast.makeText(context, "上电成功", Toast.LENGTH_SHORT).show()
                    }
                }
            }
        }

        private fun findCar() {
            // 寻车
            bleService.findCar { response ->
                activity?.runOnUiThread {
                    if (response.success) {
                        Toast.makeText(context, "寻车成功", Toast.LENGTH_SHORT).show()
                    }
                }
            }
        }

        private fun getUserId(): ByteArray {
            // 实际项目中从用户认证信息中获取
            return ByteArray(16) { it.toByte() } // 示例数据
        }

        override fun onDestroyView() {
            super.onDestroyView()
            // 4. 断开连接（可选，单例会保持连接状态）
            if (bleService.isConnected()) {
                bleService.disconnect()
            }
        }
    }

### 步骤说明

1. 获取单例实例：使用 `BLEServiceFactory.create(context)` 获取服务实例（全局只有一个）
2. 连接设备：调用 `initializeAndConnect()` 连接设备（自动完成扫描+连接+握手）
3. 发送指令：连接成功后，调用各种指令方法（如 `setDefense()`、`powerOn()`、`findCar()` 等）
4. 断开连接：在 `onDestroyView()` 中断开连接（可选）

### 重要说明

1. 单例模式：`BLEService` 是单例，全局只有一个实例，在任何地方获取的都是同一个
2. 连接状态共享：所有使用该服务的地方共享同一个连接状态
3. 第一次需要 Context：第一次获取单例时需要传入 Context，后续获取可以不带（但建议统一使用工厂类）
4. 连接是必须的：蓝牙不是自动连接的，需要手动调用 `initializeAndConnect()` 连接设备

### 两种连接方式的区别

#### 方式一：一键连接（推荐，最简单）

使用 `initializeAndConnect()` - 自动完成所有步骤：

- ✅ 自动扫描设备
- ✅ 自动找到设备后连接
- ✅ 自动完成握手和配对
- ✅ 一个方法搞定，无需手动控制

适用场景：大多数情况，直接连接即可

    // 一键完成：扫描 + 连接 + 握手
    bleService.initializeAndConnect(
        userId = userId,
        userType = userType,
        onConnected = {
            // 连接成功，可以直接使用指令了
        },
        onError = { error ->
            // 连接失败
        }
    )

#### 方式二：手动控制（需要选择设备时使用）

使用 `startScan()` + `connect()` - 手动控制每个步骤：

- 1️⃣ 手动开始扫描
- 2️⃣ 手动选择要连接的设备（可以显示设备列表让用户选择）
- 3️⃣ 手动停止扫描
- 4️⃣ 手动连接选中的设备

适用场景：需要显示设备列表让用户选择，或者需要控制扫描过程

    // 1. 开始扫描
    bleService.startScan { device: BLEDevice ->
        // 找到设备，可以显示在列表中让用户选择
        println("找到设备: ${device.name}, 地址: ${device.address}")
        // 可以添加到设备列表，让用户选择
    }

    // 2. 停止扫描（用户选择设备后）
    bleService.stopScan()

    // 3. 连接用户选择的设备
    val userId = getUserId() // 16字节
    val userType = BLEConstants.USER_TYPE_OWNER
    val selectedDevice = BLEDevice(name = "用户选择的设备", address = "MAC地址", rssi = 0)
    bleService.connect(selectedDevice, userId, userType) { response ->
        if (response.success) {
            // 连接成功，已自动完成握手
        } else {
            // 连接失败
        }
    }

总结：

- 一键连接：最简单，自动完成所有步骤，推荐使用
- 手动控制：需要用户选择设备时使用，可以显示设备列表

## API 参考

### 基础连接功能

#### `startScan(callback: (BLEDevice) -> Unit)`

开始扫描 BLE 设备

#### `stopScan()`

停止扫描设备

#### `connect(device: BLEDevice, userId: ByteArray, userType: Byte, callback: (BLEResponse) -> Unit)`

连接设备（自动完成握手和配对）

#### `disconnect()`

断开连接

#### `isConnected(): Boolean`

检查是否已连接

### 高级连接功能（推荐使用）

#### `initializeAndConnect()`

一键完成扫描+连接+握手（最简单的方式）

    fun initializeAndConnect(
        userId: ByteArray,
        userType: Byte,
        onConnected: () -> Unit,
        onDisconnected: (() -> Unit)? = null,
        onDataReceived: ((ByteArray) -> Unit)? = null,
        onError: ((String) -> Unit)? = null,
        scanTimeoutMs: Long = 10000
    )

参数说明：

- `userId`: 用户ID（16字节），用于握手认证
- `userType`: 用户类型（0x01=最高权限, 0x02=车主, 0x03=分享用户）
- `onConnected`: 连接成功回调（已自动完成握手和配对）
- `onDisconnected`: 断开连接回调（可选）
- `onDataReceived`: 数据接收回调（可选）
- `onError`: 错误回调（可选）
- `scanTimeoutMs`: 扫描超时时间（毫秒），默认10秒

#### `scanAndConnect()`

扫描并连接设备（一键完成扫描+连接）

    fun scanAndConnect(
        userId: ByteArray,
        userType: Byte,
        scanTimeoutMs: Long = 10000,
        onScanning: (() -> Unit)? = null,
        onDeviceFound: ((BLEDevice) -> Unit)? = null,
        onConnected: () -> Unit,
        onError: (String) -> Unit
    )

#### `setConnectionListener()`

设置连接状态监听器（连接/断开时自动回调）

    fun setConnectionListener(
        onConnected: () -> Unit,
        onDisconnected: () -> Unit,
        onError: (String) -> Unit
    )

### 便捷方法

#### `setDefense(enabled: Boolean, callback: (BLEResponse) -> Unit)`

设防/撤防

#### `powerOn(callback: (BLEResponse) -> Unit)`

上电

#### `powerOff(callback: (BLEResponse) -> Unit)`

下电

#### `findCar(callback: (BLEResponse) -> Unit)`

寻车

#### `unlockSeat(callback: (BLEResponse) -> Unit)`

打开座桶锁

#### `unlockHandlebar(callback: (BLEResponse) -> Unit)`

打开龙头锁

#### `lockHandlebar(callback: (BLEResponse) -> Unit)`

关闭龙头锁

#### `unlockTrunk(callback: (BLEResponse) -> Unit)`

打开尾箱锁

#### `lockTrunk(callback: (BLEResponse) -> Unit)`

关闭尾箱锁

#### `setSensorUnlock(enabled: Boolean, callback: (BLEResponse) -> Unit)`

设置感应解锁开关

#### `setAmbientLight(enabled: Boolean, callback: (BLEResponse) -> Unit)`

设置氛围灯开关

#### `setAmbientLightColor(r: Int, g: Int, b: Int, callback: (BLEResponse) -> Unit)`

设置氛围灯颜色

#### `setAutoPowerOffTime(timeSeconds: Int, callback: (BLEResponse) -> Unit)`

设置自动下电时间

#### `setSpeakerVolume(volume: Int, callback: (BLEResponse) -> Unit)`

设置蓝牙音箱音量

### 通用方法

#### `sendAppControlCommand(instructionType: Byte, data: ByteArray, callback: (BLEResponse) -> Unit)`

发送应用控制指令

指令类型（`AppControlInstruction` 对象）：

- `AppControlInstruction.SET_DEFENSE` - 设撤防
- `AppControlInstruction.POWER_ON_OFF` - 上下电
- `AppControlInstruction.FIND_CAR` - 寻车
- `AppControlInstruction.SEAT_LOCK` - 座桶锁
- `AppControlInstruction.HANDLEBAR_LOCK` - 龙头锁
- `AppControlInstruction.TRUNK_LOCK` - 尾箱锁

#### `sendSystemControlCommand(instructionType: Byte, data: ByteArray, callback: (BLEResponse) -> Unit)`

发送系统控制指令

指令类型（`SystemControlInstruction` 对象）：

- `SystemControlInstruction.SENSOR_UNLOCK` - 感应解锁开关
- `SystemControlInstruction.AMBIENT_LIGHT` - 氛围灯开关
- `SystemControlInstruction.AMBIENT_LIGHT_COLOR` - 氛围灯颜色
- `SystemControlInstruction.AUTO_POWER_OFF_TIME` - 自动下电时间
- `SystemControlInstruction.SPEAKER_VOLUME` - 蓝牙音箱音量
- 更多指令类型请查看 `SystemControlInstruction` 对象

#### `queryVehicleInfo(callback: (BLEResponse) -> Unit)`

查询车辆信息

#### `sendCommand(command: BLECommand, callback: (BLEResponse) -> Unit)`

发送自定义指令

#### `setDataReceivedListener(listener: DataCallback)`

设置数据接收监听器

## 常量定义

### 用户类型

    BLEConstants.USER_TYPE_HIGHEST  // 0x01 - 最高权限
    BLEConstants.USER_TYPE_OWNER    // 0x02 - 车主
    BLEConstants.USER_TYPE_SHARED   // 0x03 - 分享用户

### 功能码

    BLEConstants.FUNCTION_CODE_HANDSHAKE        // 0x01 - 握手
    BLEConstants.FUNCTION_CODE_APP_CONTROL      // 0x02 - 应用控制
    BLEConstants.FUNCTION_CODE_SYSTEM_CONTROL   // 0x03 - 系统控制
    BLEConstants.FUNCTION_CODE_SYSTEM_QUERY     // 0x04 - 系统查询
    BLEConstants.FUNCTION_CODE_SYSTEM_SETTING   // 0x05 - 系统设置

## 注意事项

1. 单例模式：`BLEServiceImpl` 使用单例模式，全局共享同一个连接状态

2. 自动握手：`connect()` 方法内部自动完成握手，无需单独调用握手方法

3. 线程安全：BLE 回调可能在非主线程执行，需要在回调中使用 `activity?.runOnUiThread {}` 切换到主线程更新 UI

4. 错误处理：所有 API 都通过 `BLEResponse` 返回结果，需要检查 `response.success` 判断是否成功

5. 生命周期管理：建议在 `onDestroyView()` (Fragment) 或 `onDestroy()` (Activity) 中调用 `disconnect()` 断开连接

6. 获取服务实例：推荐使用 `BLEServiceFactory.create(context)` 获取服务实例（工厂方法内部使用单例模式）

7. Fragment 中使用：在 Fragment 中使用时，使用 `requireContext()` 获取 Context，回调中使用 `activity?.runOnUiThread {}` 更新 UI