AndroidBLE读写开发回顾

Android BLE 读写开发回顾

这里主要记录BLE的通讯方面的笔记

1.发现BluetoothGattService回调

BLE 调用gatt.connect()连接成功之后调用:

gatt.discoverServices()

触发回调void onServicesDiscovered(BluetoothGatt gatt, int status)

通过硬件规定的uuid获取对应的BluetoothGattService:

BluetoothGattService service = gatt.getService(mServiceUuid);

BluetoothGattService中包含一个或多个BluetoothGattCharacteristic,这些特征字将是后续用来读写数据的载体,而

通过硬件给定的uuid筛选出对应的特征字,譬如有些特征字用于收发简单命令,而有些特征字用于批量发送数据:

if (characteristic.getUuid().equals(UUID.fromString(String.format(MEDTRUM_BASE_UUID, MEDTRUM_UUID_CHARACTERISTIC_BULK)))) {
    //获取批量发送数据特征字
    mBulkCharacteristics = characteristic;
} else if (characteristic.getUuid().equals(UUID.fromString(String.format(MEDTRUM_BASE_UUID, MEDTRUM_UUID_CHARACTERISTIC_CTRLPT)))) {
    //获取收发命令特征字
    mCommandCharacteristics = characteristic;
}

在拿到特征字之后并不能直接使用,如果特征字具有通知功能,那么还需要对其进行设置:

Log.d(TAG, "setCharacteristicNotification: "+gatt.setCharacteristicNotification(characteristic, true));

当然,这还不够,你会发现这个特征字可以正常的发送数据,但是接受不到返回数据,划重点,这里别忘了对特征字描述符BluetoothGattDescriptor进行设置:

BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG));
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
    descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
    mBluetoothGatt.writeDescriptor(descriptor);
} else if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) > 0) {
    descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
    mBluetoothGatt.writeDescriptor(descriptor);
}

设置描述符调用了mBluetoothGatt.writeDescriptor(descriptor)方法,对应的回调为:

void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status)

在回调中可以对对应的描述符进行验证是否设置成功,然后就可以正常的使用特征字收发命令了;

注意,通常BluetoothGattService并不只包含一个特征字,而对特征字的设置动作底层其实也是一个写的命令,理论上也会触发:

void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)

但是在开发过程中通常并不能在这一步接收到回调,这里的原因我还不是很清楚,大牛看到请,烦请指点一二,嘻嘻。

既然是写的操作,就必须遵循串行操作的原则,有序的写,设置一个特征字之后延迟一段时间,再设置下一个。

这里的延迟时间比较讲究,Android手机厂家众多,所以需要给定的延迟时间也各不相同,开发经验发现如果间隔时间超过250ms SAMSUNG 2s内连接不上会被动断开,最终测试结果定在了700ms,可以适配目前所有的测试机型,如果有大牛有更好的解决办法,烦请指点一二,嘻嘻。

2.读写数据

在拿到了特征字之后,就可以进行读写操作了,写:

if (mCommandCharacteristics != null) {
    if (value.length > 0) {
        mCommandCharacteristics.setValue(value);
        mBluetoothGatt.writeCharacteristic(mCommandCharacteristics);
    }
}

发送数据之后,可以通过回调:

onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)

接收反馈,判断命令是否发送成功。

对于数据的读取,通过回调:

void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)

来获取到反馈的内容,可以看到这个回调中包含了特征字BluetoothGattCharacteristic很显然,我么您可以通过特征字的uuid来判断反馈的数据是命令返回,或者是通知消息;

注意,在读写交互中,请一定遵守串行传输的准则,有序的收发命令,避免出现奇奇怪怪的bug;

推荐阅读更多精彩内容