最近做的项目是手机端和BLE设备通讯,而BLE设备又做了限制一次包只能传递20个字节的数据,多了就得分包发送,在这里记录一下如何解决这个问题。
(PS:之前链接什么的回调什么的 就不过多说了)
1.发送数据包突破20个字节。
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == GATT_SUCCESS) {
BluetoothHelper.this.gatt = gatt;
gatt.requestMtu(512);
List<BluetoothGattService> services = gatt.getServices();
for (int i = 0; i < services.size(); i++) {
List<BluetoothGattCharacteristic> characteristics = services.get(i).getCharacteristics();
if (services.get(i).getUuid().toString().contains(UUID_service_conn)) {
for (int j = 0; j < characteristics.size(); j++) {
if (characteristics.get(j).getUuid().toString().equals(UUID_write)) {
Log.e(TAG, "写入数据的特性UUID为" + characteristics.get(j).getUuid().toString());
writeBluetoothGattCharacteristic = characteristics.get(j);
} else if (characteristics.get(j).getUuid().toString().contains(UUID_read_conn)) {
Log.e(TAG, "读取数据的特性UUID为" + characteristics.get(j).getUuid().toString());
readBluetoothGattCharacteristic = characteristics.get(j);
}
}
}
}
}
}
主要是这一行:
gatt.requestMtu(512);
在发现服务的时候设置这个值,就会走后面的回调。
@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
super.onMtuChanged(gatt, mtu, status);
if (BluetoothGatt.GATT_SUCCESS == status) {
Log.e(TAG, "onMtuChanged success MTU = " + mtu);
setBleNotification();
} else {
Log.e(TAG, "onMtuChanged fail " + mtu);
}
}
成功之后设置设备主动通知时的回调
/**
* 设置监听通知
*/
public void setBleNotification() {
if (readBluetoothGattCharacteristic != null) {
BluetoothGattDescriptor descriptor = readBluetoothGattCharacteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.readCharacteristic(readBluetoothGattCharacteristic);
if (gatt.writeDescriptor(descriptor)) {
// 蓝牙设备在数据改变时,通知App,App在收到数据后回调onCharacteristicChanged方法
gatt.setCharacteristicNotification(readBluetoothGattCharacteristic, true);
}
}
}
这样当设备端数据改变时就会回调以下方法。
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
}
完成以上操作就达到了每次发送数据时突破20个包的限制(并且可以接收到设备端主动发送的通知)
2.手机端分包发送数据给设备端。
int size = 168;
byte[] bytes = s.getBytes();
byte[] value = {0x4a, 0x58, 0x57, 0x40, 0x41, (byte) (bytes.length & 0xff)};
byte[] concat = concat(value, bytes);
List<byte[]> wifiInfos = new ArrayList<>();
if (concat.length > size) {
for (int i = 0; i < concat.length; i += size) {
if (i + size < concat.length) {
byte[] infoData = new byte[size];
System.arraycopy(concat, i, infoData, 0, infoData.length);
wifiInfos.add(infoData);
} else {
byte[] infoData = new byte[concat.length - i];
System.arraycopy(concat, i, infoData, 0, infoData.length);
wifiInfos.add(infoData);
}
}
} else {
wifiInfos.add(concat);
}
for (int i = 0; i < wifiInfos.size(); i++) {
byte[] concat1 = wifiInfos.get(i);
integrationData(concat1);
BluetoothHelper.getInstance(context).writeData(concat1, UUID_write);
try {
Thread.sleep(8);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
这样就完成了每次发送168个字节数据给设备端的操作