bluetoothbluetooth-lowenergynrf51

How to return BLE peripheral's connection status


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

Solution

  • 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.