集成说明.md 17 KB

蓝牙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