0

I noticed that the method onConnectionStateChange() is not invariably invoked (or just not invoked on time) when a peripheral is non-manually disconnected like for example when the peripheral is powered off. Is there a way to get the connection state of a connected BLE peripheral manually versus just waiting for the onConnectionStateChange() to fire? I tried using BluetoothManager#getConnectionState but this method seems to be accessing the connection state updated by whatever thread is calling onConnectionStateChange(), and does not actually ask the device if it's connected. In other words, BluetoothManager#getConnectionState just returns false if onConnectionStateChange() hasn't been called yet.

Here is my isConnected method

public boolean isConnected(){

    // If the device has never connected, it's gatt service is null.
    if(mGatt != null){

        BluetoothManager btm =
                (BluetoothManager)
                        MainActivity.mMainActivity.getSystemService(Context.BLUETOOTH_SERVICE);

        int state = btm.getConnectionState(mGatt.getDevice(), BluetoothProfile.GATT);

        return state == 2;
    }

    // The gat service is null, the device is not connected, return false.
    return false;
}
the_prole
  • 8,275
  • 16
  • 78
  • 163

1 Answers1

2

onConnectionStateChange is being called as soon as the Bluetooth controller reports to the host Bluetooth stack that the link has been terminated. If you suddenly power off the peripheral without gracefully disconnecting, the connection will remain until the supervision timeout triggers. The default value of that was just changed from 20 seconds to 5 seconds in the latest Android versions because people have complained it was too long. The default on iOS is 0.72 seconds. On Android you can manually lower it by doing a connection parameter update request from the peripheral.

Emil
  • 16,784
  • 2
  • 41
  • 52
  • Thanks, could you provide an example of the connection parameter update? Not sure what you mean by it. – the_prole Jun 26 '17 at 05:05
  • That must be done from the peripheral side since Android unfortunately does not provide such an api. See https://www.google.se/search?q=connection+parameter+update+request. – Emil Jun 26 '17 at 07:46
  • Why is the connection supervision timeout parameter set by the peripheral if the peripheral is off? Shouldn't the master device be responsible for asking the peripheral if it's disconnected? Or does the peripheral send the parameter to the master? – the_prole Jun 26 '17 at 16:18
  • Well you must send the request from the peripheral before it disconnects. After that, the new parameters are applied. – Emil Jun 26 '17 at 18:11
  • Sorry, I think I misunderstood you. The master is connected to the peripheral. The peripheral can for example be a beacon, and the master could be a phone running a host Android application. Is the supervision time-out parameter programmed into the beacon or into the phone? – the_prole Jun 26 '17 at 19:23
  • It's initially set by the master. It may then be changed by any side later on (except that Android has no public API to do that). – Emil Jun 26 '17 at 21:12