Android BLE с некоторой задержкой после успешного подключения

Я работаю над приложением для Android, которое подключается к устройству BLE и выполняет там некоторые процессы.

Всего у меня 5 шагов:

После сканирования и connectGatt()

В onConnectionStateChange(),

  1. запросMtu()

    @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. обнаружитьуслуги()

        @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. написатьдескриптор()

        @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. написатьХарактеристика()

        @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 занимает слишком много времени, затем я удалил шаг 2 — requestMtu()) и напрямую вызвал метод DiscoverService(), что удивительно, обнаружение службы (шаг 3)) заняло около 1400 мс.

Я провел еще один эксперимент, снова вызвал метод requestMtu на шаге 2), теперь второй вызов занял всего от 10 до 25 мс.

Наконец-то я понял, что любой первый шаг после успешного подключения занимает больше времени.

Я не знаю причину, не могли бы вы помочь мне понять, а также я хочу сократить это время, чтобы ускорить весь процесс.

Есть ли возможность сделать это?

Заранее спасибо.


person Spectra Testing    schedule 16.02.2019    source источник


Ответы (1)


Что на самом деле требует времени, так это обнаружение службы, которое всегда выполняется при подключении устройства (даже если вы не вызываете DiscoverServices). Любая команда откладывается до тех пор, пока она не будет завершена. Чтобы ускорить его, вы должны попытаться уменьшить базу данных GATT периферийного устройства. Вы также можете попробовать отправить запрос MTU с периферийного устройства сразу после подключения, чтобы обнаружение службы использовало меньше пакетов.

Кстати, вы не можете прочитать характеристику сразу после того, как отправили запрос на запись дескриптора. Вам всегда нужно дождаться завершения операции GATT, прежде чем вы сможете отправить новую.

person Emil    schedule 16.02.2019
comment
Спасибо за ваш ответ :) Не могли бы вы также сказать мне, как сжать gatt db? - person Spectra Testing; 16.02.2019
comment
Это просто попытка не иметь слишком много сервисов, характеристик и дескрипторов. - person Emil; 16.02.2019