6

I am looking for an android way to flush the characteristics the app receives from a Ble device, or at least know from the data that the connection has been lost as soon as it actually is except around 15 seconds after it disconnected. If there is a way to change the gatt connection timeout, that would be significantly better.

To repeat in a different form, I would like a solution (or a link that can explain) to detect a disconnect of the BLE device faster than whatever the timeout value currently is, by a means of seeing if the value I am getting is fresh by flushing the characteristic, or changing the disconnect timeout on the gatt side, so I can see within a second of it disconnecting to trigger other code.

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
btelman96
  • 413
  • 4
  • 11

5 Answers5

2

Other answers in here may be better than this one, but this was my solution to the problem. Be sure to attempt Emil's answer before using this.

What I did since the time was too slow to wait for it was to check the rssi since it always is changing. If there is a period of time, lets say 3 seconds, where the value stays the same, it disconnects from the device. This goes around the 15 second timeout and adds our own timeout.

This would be what would be needed to check signal strength. This was written a couple of years ago, so some things may need to be changed.

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;
    }
}

Somewhere in a loop, call

mBluetoothGatt.readRemoteRssi()
btelman96
  • 413
  • 4
  • 11
0

Don't know if this would be of help, but you can take advantage (if you have it) of a periodic data that is transmitted in the gatt. So if for example you have a measurement of 1 second of periodicity you can do something like:

// 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);

So the "measurement_timeout" will work as an actual timeout that when it reaches the 0 means that you don't have data received in the period of 3000 ms. Notice that you must have a watch time > 2*data period.

0

The only way I have managed to achieve a fast gatt disconnect has been to ensure that the peripheral device sends a BLE disconnect instruction before it powers down or severs the connection.

Once android receives the disconnect instruction, the gatt tidies up immediately instead of taking 15 seconds to realise the peripheral is missing.

It would seem that most peripherals do not bother and just disappear.

Clearly this approach is only possible if you are able to modify the peripheral.

Mark Ch
  • 2,840
  • 1
  • 19
  • 31
0

The proper way is to use the Connection Parameter Update Request from the peripheral side to change the timeout to a lower value.

Emil
  • 16,784
  • 2
  • 41
  • 52
-1

There is a callback in Android :

BluetoothGattCallback btleGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange( BluetoothGatt gatt,int status,int newState){ 
        if(newState == BluetoothProfile.STATE_DISCONNECTED){
            //your code here
        }
    }
}
Fabian N.
  • 3,807
  • 2
  • 23
  • 46
Shubham
  • 2,627
  • 3
  • 20
  • 36
  • 2
    This is what I pretty much have in my code right now. I am using the sample bluetooth low energy code provided in the android sdk examples. It currently takes 20 seconds after disconnect for what you provided to be called last time I measured time. Since the signal strength almost never is the same value for 20 readings or so, I will try to see if that works. – btelman96 Feb 26 '15 at 19:57