Android BLE 连接成功后有一些延迟
Android BLE taking some delay after successful connection
我正在开发 Android 连接到 BLE 设备并在那里进行一些处理的应用程序。
我总共有 5 个步骤:
扫描并连接后Gatt()
在onConnectionStateChange()中,
requestMtu()
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
switch (newState) {
case BluetoothProfile.STATE_CONNECTED:
gatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH);
Log.e("Connect", (System.currentTimeMillis() - startTime) + " ms");
deviceConnected = true;
gatt.requestMtu(185);
break;
在onMtuChanged()中,
discoverServices()
@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
super.onMtuChanged(gatt, mtu, status);
Log.e("Mtu Change", (System.currentTimeMillis() - startTime) + " ms");
if (status == BluetoothGatt.GATT_SUCCESS) {
gatt.discoverServices();
}
}
在 onServicesDiscovered() 中,
writeDescriptor()
@Override
public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
gatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_BALANCED);
Log.e("Service Discover", (System.currentTimeMillis() - startTime) + " ms");
try {
BluetoothGattService service = gatt.getService(UUID.fromString("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"));
BluetoothGattCharacteristic notifyChar = gatt.getService(UUID.fromString("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"));
if (notifyChar != null) {
gatt.setCharacteristicNotification(notifyChar, true);
BluetoothGattDescriptor descriptor = notifyChar.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
descriptor.setValue(new byte[]{0x01, 0x00});
gatt.writeDescriptor(descriptor);
gatt.readCharacteristic(notifyChar);
}
} catch (Exception e) {
showToast("Service Disc. EXCEPTION");
e.printStackTrace();
}
}
在onDescriptorWrite()中,
writeCharacteristic()
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
Log.e("Descriptor Write", (System.currentTimeMillis() - startTime) + " ms");
if (status == 0) {
BluetoothGattCharacteristic characteristic = gatt.getService(UUID.fromString("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"));
characteristic.setValue(myVal);
gatt.writeCharacteristic(characteristic);
Log.e(TAG, "TagID Sent");
}
}
在onCharacteristicWrite()中,
嘟嘟一声,
@Override
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
final int status) {
Log.e("Characteristic Write", (System.currentTimeMillis() - startTime) + " ms");
if(status == 0){
beep();
}
}
我记下了每一步所花费的时间,下面是读数(5 次的平均值),
- 连接成功(即 onConnectionStateChange()):500 到 525 毫秒
- MtuChange(即 onMtuChanged()):1400 到 1450 毫秒
- 服务发现(即 onServicesDiscovered()):10 到 25 毫秒
- 描述符写入(即 onDescriptorWrite()):10 到 25 毫秒
- 特征写入(即 onCharacteristicWrite):10 到 25 毫秒
所以,一开始我觉得设置mtu size太花时间了,然后我去掉了step 2 - requestMtu()) 直接调用了discoverService()方法,没想到服务发现(step 3))花了1400左右毫秒时间。
我又做了一个实验,再次调用步骤2)中的requestMtu方法,现在第二次调用只用了10到25毫秒。
终于明白了,连接成功后的任何第一步都需要更长的时间。
我不知道原因,你能帮我理解一下吗,另外,我想减少这个时间,让整个过程更快。
有可能吗?
提前致谢。
真正需要时间的是服务发现,它总是在设备连接时完成(即使您不调用 discoverServices)。任何命令都会延迟到完成为止。为了加快速度,您应该尝试缩小外围设备的 GATT 数据库。您也可以尝试在连接后直接从外设发送 MTU 请求,以减少服务发现使用的数据包。
顺便说一句,您不能在发送写描述符请求后立即读取特征。您总是需要等待 GATT 操作完成,然后才能发送新操作。
我正在开发 Android 连接到 BLE 设备并在那里进行一些处理的应用程序。
我总共有 5 个步骤:
扫描并连接后Gatt()
在onConnectionStateChange()中,
requestMtu()
@Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { switch (newState) { case BluetoothProfile.STATE_CONNECTED: gatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH); Log.e("Connect", (System.currentTimeMillis() - startTime) + " ms"); deviceConnected = true; gatt.requestMtu(185); break;
在onMtuChanged()中,
discoverServices()
@Override public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) { super.onMtuChanged(gatt, mtu, status); Log.e("Mtu Change", (System.currentTimeMillis() - startTime) + " ms"); if (status == BluetoothGatt.GATT_SUCCESS) { gatt.discoverServices(); } }
在 onServicesDiscovered() 中,
writeDescriptor()
@Override public void onServicesDiscovered(final BluetoothGatt gatt, int status) { gatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_BALANCED); Log.e("Service Discover", (System.currentTimeMillis() - startTime) + " ms"); try { BluetoothGattService service = gatt.getService(UUID.fromString("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")); BluetoothGattCharacteristic notifyChar = gatt.getService(UUID.fromString("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")); if (notifyChar != null) { gatt.setCharacteristicNotification(notifyChar, true); BluetoothGattDescriptor descriptor = notifyChar.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")); descriptor.setValue(new byte[]{0x01, 0x00}); gatt.writeDescriptor(descriptor); gatt.readCharacteristic(notifyChar); } } catch (Exception e) { showToast("Service Disc. EXCEPTION"); e.printStackTrace(); } }
在onDescriptorWrite()中,
writeCharacteristic()
@Override public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { Log.e("Descriptor Write", (System.currentTimeMillis() - startTime) + " ms"); if (status == 0) { BluetoothGattCharacteristic characteristic = gatt.getService(UUID.fromString("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")); characteristic.setValue(myVal); gatt.writeCharacteristic(characteristic); Log.e(TAG, "TagID Sent"); } }
在onCharacteristicWrite()中,
嘟嘟一声,
@Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, final int status) { Log.e("Characteristic Write", (System.currentTimeMillis() - startTime) + " ms"); if(status == 0){ beep(); } }
我记下了每一步所花费的时间,下面是读数(5 次的平均值),
- 连接成功(即 onConnectionStateChange()):500 到 525 毫秒
- MtuChange(即 onMtuChanged()):1400 到 1450 毫秒
- 服务发现(即 onServicesDiscovered()):10 到 25 毫秒
- 描述符写入(即 onDescriptorWrite()):10 到 25 毫秒
- 特征写入(即 onCharacteristicWrite):10 到 25 毫秒
所以,一开始我觉得设置mtu size太花时间了,然后我去掉了step 2 - requestMtu()) 直接调用了discoverService()方法,没想到服务发现(step 3))花了1400左右毫秒时间。
我又做了一个实验,再次调用步骤2)中的requestMtu方法,现在第二次调用只用了10到25毫秒。
终于明白了,连接成功后的任何第一步都需要更长的时间。
我不知道原因,你能帮我理解一下吗,另外,我想减少这个时间,让整个过程更快。
有可能吗?
提前致谢。
真正需要时间的是服务发现,它总是在设备连接时完成(即使您不调用 discoverServices)。任何命令都会延迟到完成为止。为了加快速度,您应该尝试缩小外围设备的 GATT 数据库。您也可以尝试在连接后直接从外设发送 MTU 请求,以减少服务发现使用的数据包。
顺便说一句,您不能在发送写描述符请求后立即读取特征。您总是需要等待 GATT 操作完成,然后才能发送新操作。