изменение времени ожидания bluetooth низкой энергии gatt или промывки потока чтения для обнаружения события отключения быстрее

Я ищу способ Android для очистки характеристик, которые приложение получает от устройства Ble, или, по крайней мере, знаю из данных, что соединение было потеряно, как только оно на самом деле, за исключением примерно 15 секунд после его отключения. Если есть способ изменить время ожидания соединения gatt, это было бы значительно лучше.

чтобы повторить в другой форме, я хотел бы, чтобы решение (или ссылка, которая может объяснить) обнаружило отключение устройства BLE быстрее, чем независимо от значения тайм-аута в настоящее время, с помощью того, чтобы увидеть, является ли значение, которое я получаю, свежим, смывая характеристику или изменяя тайм-аут отключения на стороне gatt, поэтому я могу видеть в течение секунды его отключения, чтобы вызвать другой код.

5 ответов


другие ответы здесь может быть лучше, чем этот, но это было мое решение проблемы. Обязательно попробуйте Эмиль ответ перед использованием этого.

то, что я сделал, так как время было слишком медленным, чтобы ждать, было проверить rssi, так как он всегда меняется. Если есть период времени, скажем, 3 секунды, где значение остается неизменным, он отключается от устройства. Это идет вокруг 15-секундного тайм-аута и добавляет наш собственный тайм-аут.

Это быть тем, что нужно для проверки силы сигнала. Это было написано пару лет назад, поэтому некоторые вещи могут быть изменены.

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {

    @Override
    public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status){
            //check for signal strength changes. It will stay the same if we 
            //are getting no updates
            if(mLastRssi == rssi){ 
                disconnectCounter++;
                if(disconnectCounter> 140) {
                    //disconnect logic as if we are done with connection
                    //maybe start listening for device again to reconnect
                    disconnectCounter = 0;
                }
            }
            else{
                //we are connected. reset counter
                disconnectCounter = 0;
            }
            //store last value as global for comparison
            mLastRssi= rssi;
    }
}

где-то в цикле, называют

mBluetoothGatt.readRemoteRssi()

Не знаю, поможет ли это, но вы можете воспользоваться (если у вас есть) периодическими данными, которые передаются в ГАТТ. Поэтому, если, например, у вас есть измерение 1 секунды периодичности, вы можете сделать что-то вроде:

// runnable to detect the lack of activity:
private final Runnable watchDog = new Runnable() {
    @Override
    public void run() {
        measurement_timeout--;
        if(measurement_timeout==0) {
            Log.d("BLE_CONTROLLER", "PROBE WITH NO ACTIVITY");

        }
    }
};

// this should be in the reception of the periodic data:
measurement_timeout++;
mHandler.postDelayed(watchDog, 3000);

таким образом," measurement_timeout " будет работать как фактический тайм-аут, который при достижении 0 означает, что у вас нет данных, полученных в период 3000 МС. Обратите внимание, что вы должны иметь часы Время > 2*период данных.


единственный способ, которым мне удалось добиться быстрого отключения gatt, - это убедиться, что периферийное устройство отправляет инструкцию BLE disconnect, прежде чем оно отключит или разорвет соединение.

Как только android получает инструкцию отключения, ГАТТ немедленно убирает, а не занимает 15 секунд, чтобы понять, что периферийное устройство отсутствует.

казалось бы, что большинство периферийных устройств не беспокоят и просто исчезают.

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


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


в Android есть обратный вызов:

BluetoothGattCallback btleGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange( BluetoothGatt gatt,int status,int newState){ 
        if(newState == BluetoothProfile.STATE_DISCONNECTED){
            //your code here
        }
    }
}