蓝牙-BLE协议

497 阅读2分钟

BLE整体流程

扫描设备->配对/绑定设备->连接设备->读写数据

核心类

  • BluetoothManager
  • BluetoothAdapter
  • BluetoothLeScanner
  • BluetoothGatt
  • BluetoothGattCallback
  • ScanCallback

核心方法

// 获取BluetoothManager对象
(BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
// 获取BluetoothAdapter对象
bluetoothManager.getAdapter()
// 获取BluetoothLeScanner对象
bluetoothAdapter.getBluetoothLeScanner()

// 开启扫描并设置扫描回调
bluetoothLeScanner.startScan(bleScanCallback)

// 连接设备
BluetoothDevice remoteDevice = bluetoothAdapter.getRemoteDevice(address);
bluetoothGatt = remoteDevice.connectGatt(context, false, bleConnectGattCallback, BluetoothDevice.TRANSPORT_LE);

扫描回调

ScanCallback
/**
 * 当发现设备时就会触发此回调函数
 *
 * @param result BLE设备信息
 */
public void onScanResult(int callbackType, ScanResult result) {
    // 获取BLE扫描到的设备相关信息
    ScanRecord scanRecord = result.getScanRecord();
}

/**
 * 扫描失败时发生的回调
 *
 * @param errorCode 错误码 
 */
public void onScanFailed(int errorCode) {
switch (errorCode) {
    // 一般会发生在上一次扫描未完成时重复调用startScan()函数
    case SCAN_FAILED_ALREADY_STARTED:
        Log.d(TAG, "[ScanCallbackImpl] -  onScanFailed: SCAN_FAILED_ALREADY_STARTED = " + errorCode);
        break;
    case SCAN_FAILED_APPLICATION_REGISTRATION_FAILED:
        Log.d(TAG, "[ScanCallbackImpl] - onScanFailed: SCAN_FAILED_APPLICATION_REGISTRATION_FAILED = " + errorCode);
        break;
    case SCAN_FAILED_INTERNAL_ERROR:
        Log.d(TAG, "[ScanCallbackImpl] - onScanFailed: SCAN_FAILED_INTERNAL_ERROR = " + errorCode);
        break;
    case SCAN_FAILED_FEATURE_UNSUPPORTED:
        Log.d(TAG, "[ScanCallbackImpl] - onScanFailed: SCAN_FAILED_FEATURE_UNSUPPORTED = " + errorCode);
        break;
    default:
        break;
}

连接回调

BluetoothGattCallback
/**
 * Callback indicating when GATT client has connected/disconnected to/from a remote
 * GATT server.
 *
 * @param gatt     GATT client
 * @param status   连接或断开连接操作的状态. {@link
 *                 BluetoothGatt#GATT_SUCCESS} 如果是GATT_SUCCESS则连接成功
 * @param newState 返回新的连接状态,可以是以下几种
 *                 {@link BluetoothProfile#STATE_DISCONNECTED} or
 *                 {@link BluetoothProfile#STATE_CONNECTING} or
 *                 {@link BluetoothProfile#STATE_CONNECTED} or
 *                 {@link BluetoothProfile#STATE_DISCONNECTING}
 */
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
    // 当前为子线程,如需更新UI则需要进行切换到主线程中
        case STATE_CONNECTING:
        Log.d(TAG, "[BLEClientImpl] - onConnectionStateChange: " + deviceName + " STATE_CONNECTING");
        break;
    case STATE_DISCONNECTING:
        Log.d(TAG, "[BLEClientImpl] - onConnectionStateChange: " + deviceName + " STATE_DISCONNECTING");
        break;
    case STATE_DISCONNECTED:
        Log.d(TAG, "[BLEClientImpl] - onConnectionStateChange: " + deviceName + " STATE_DISCONNECTED");
        // 与BLE设备断开则需要先进行关闭连接
        closeConnection(gatt);
        if (status == 133) {
            Log.d(TAG, "[BLEClientImpl] - STATE_DISCONNECTED with error status: " + status);
        } else {
            Log.d(TAG, "[BLEClientImpl] - STATE_DISCONNECTED: deviceName " + deviceName);
        }
        break;
    default:
        break;
        
    if (status == GATT_SUCCESS && newState == STATE_CONNECTED) {
        Log.d(TAG, "[BLEClientImpl] - GATT_SUCCESS 连接成功");
        // 开始读写数据
        gatt.discoverServices();
    }
}

public void onServicesDiscovered(BluetoothGatt gatt, int status) {
    super.onServicesDiscovered(gatt, status);
    
    if (status == GATT_SUCCESS) {
        // 获取服务
        Service service = gatt.getServices()
        for (BluetoothGattService gattService : service) {
            // 获取 serviceUUID
            UUID serviceUuid = gattService.getUuid();
            // 获取特征id集合
            Characteristics characteristics = gattService.getCharacteristics()
            for(Characteristics characteristics : characteristic){
                // 给每一个特征设置发生变化时通知
                boolean notification = gatt.setCharacteristicNotification(characteristic, true);
                if (notification) {
                    List<BluetoothGattDescriptor> descriptorList = characteristic.getDescriptors();
                    for (BluetoothGattDescriptor descriptor : descriptorList) {
                        descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                        gatt.writeDescriptor(descriptor);
                    }
                }
            }
        }
    }
}

/**
 * 特征发生改变时回调
 */
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
    // 获取特征数组
    byte[] characteristicValue = characteristic.getValue();
}

 /**
  * 在建立新连接之前,必须释放旧的连接资源,否则容易出现连接错误 133
  */
 private void closeConnection(BluetoothGatt gatt) {
     Log.i(TAG, "[BLEClientImpl] - closeConnection()!");
     if (gatt == null) {
         Log.e(TAG, "[BLEClientImpl] - closeConnection() BluetoothGatt ==> close: gatt == null !");
         return;
     }
     gatt.close();
     bluetoothGatt = null;
 }