Home > Enterprise >  Devices with Android 12 keep bluetooth LE connection even when app is closed
Devices with Android 12 keep bluetooth LE connection even when app is closed

Time:07-26

I'm experiencing an issue, where I can connect to bluetooth device once, but after I disconnect, I no longer see that device when scanning for bluetooth devices. If I completely close the app, device is still undiscoverable, but if I turn off the phone, device becomes discoverable again.

I also noticed that this issue is happending on pixel, huawei and xiomi devices, but seems to work on samsung running android 12.

My assumption is, that there's some strange functionality in android 12 that somehow keeps connection alive separately from the app. In my app I call this code to disconnect:

gatt.close()

Are there any other ways I could make sure device is completely disconnected?

CodePudding user response:

Calling gatt.close only is not enough. In order to disconnect properly from the gatt server; you need to call BlueotoothGatt.disconnect first, then in onConnectionStateChange callback you must call the BluetoothGatt.close.

Some where in your activity

// Somewhere in your activity where you want to disconnect
// might be adequate in onPause callback
if(bleAdapter != null && bleAdapter.isConnected) {
    bleAdapter.disconnect(); // In bleAdapter you're supposed to hold a reference to the gatt object.
}

In your BLE adapter implementation

private void disconnect() {;
    if (bluetooth_adapter == null || bluetooth_gatt == null) {
        Log.d("disconnect: bluetooth_adapter|bluetooth_gatt null");
        return;
    }
    if (bluetooth_gatt != null) {
        bluetooth_gatt.disconnect();
    }
}

// And finally in your BluetoothGattCallback.onConnectionStateChange implementation you call the close method on your BluetoothGatt object reference
private final BluetoothGattCallback gatt_callback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        Log.d(TAG, "onConnectionStateChange: status="   status);
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            Log.d(TAG, "onConnectionStateChange: CONNECTED");
            connected = true;
        }
        else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            Log.d(TAG, "onConnectionStateChange: DISCONNECTED");
            connected = false;
            if (bluetooth_gatt != null) {
                Log.d(TAG,"Closing and destroying BluetoothGatt object");
                bluetooth_gatt.close();
                bluetooth_gatt = null;
            }
        }
    }

    // Other callbacks
};

CodePudding user response:

  1. Make sure you call close() on the correct BluetoothGatt object. You haven't posted the full code so it's impossible to say if this is done correctly.

  2. When you "completely close the app", make sure you "force quit" the app rather than just closing all activities, since closing all activities might still leave the app process running. When an app process quits for any reason, the Bluetooth stack will automatically close the process's BluetoothGatt objects that haven't been closed.

  3. Any app can have a BluetoothGatt object that references a connection. All these references must be disconnected or closed in order for the disconnect attempt to take place. BLE debug apps might hold connections active, so make sure to close all such apps.

  4. If the device still doesn't disconnect after following the above, try to inspect hci snoop log or logcat for clues.

  • Related