Android BLE 连接成功后有一些延迟

Android BLE taking some delay after successful connection

我正在开发 Android 连接到 BLE 设备并在那里进行一些处理的应用程序。

我总共有 5 个步骤:

扫描并连接后Gatt()

在onConnectionStateChange()中,

  1. 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()中,

  1. 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() 中,

  1. 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()中,

  1. 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()中,

  1. 嘟嘟一声,

        @Override
    public void onCharacteristicWrite(BluetoothGatt gatt,
                                      BluetoothGattCharacteristic characteristic,
                                      final int status) {
        Log.e("Characteristic Write", (System.currentTimeMillis() - startTime) + " ms");
        if(status == 0){
            beep();
        }
    }
    

我记下了每一步所花费的时间,下面是读数(5 次的平均值),

  1. 连接成功(即 onConnectionStateChange()):500 到 525 毫秒
  2. MtuChange(即 onMtuChanged()):1400 到 1450 毫秒
  3. 服务发现(即 onServicesDiscovered()):10 到 25 毫秒
  4. 描述符写入(即 onDescriptorWrite()):10 到 25 毫秒
  5. 特征写入(即 onCharacteristicWrite):10 到 25 毫秒

所以,一开始我觉得设置mtu size太花时间了,然后我去掉了step 2 - requestMtu()) 直接调用了discoverService()方法,没想到服务发现(step 3))花了1400左右毫秒时间。

我又做了一个实验,再次调用步骤2)中的requestMtu方法,现在第二次调用只用了10到25毫秒。

终于明白了,连接成功后的任何第一步都需要更长的时间。

我不知道原因,你能帮我理解一下吗,另外,我想减少这个时间,让整个过程更快。

有可能吗?

提前致谢。

真正需要时间的是服务发现,它总是在设备连接时完成(即使您不调用 discoverServices)。任何命令都会延迟到完成为止。为了加快速度,您应该尝试缩小外围设备的 GATT 数据库。您也可以尝试在连接后直接从外设发送 MTU 请求,以减少服务发现使用的数据包。

顺便说一句,您不能在发送写描述符请求后立即读取特征。您总是需要等待 GATT 操作完成,然后才能发送新操作。