SMGhost
SMGhost

Reputation: 4037

Android BLE connecting directly via address fails

So I have this situation. If I scan for new LE devices and connect to any device found, I'm able to connect successfully, but If I store that device address in memory, turn off app and turn on again and then try to connect directly in my onConnectionStateChange I get newState as BluetoothProfile.STATE_DISCONNECTED most of the time, but not always.

This seems to happen on galaxy s7, but not on my other cheap tablet.

My connection logic looks like this:

    BluetoothDevice bluetoothDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(
            device.getAddress());
    Log.i(TAG, "Found device: " + bluetoothDevice.getAddress()
            + " (" + bluetoothDevice.getName() + ") Type: " + bluetoothDevice.getType());
    bluetoothGatt = bluetoothDevice.connectGatt(context, false, new BluetoothGattCallback() { <..> }, BluetoothDevice.TRANSPORT_LE);

My onConnectionStateChange method looks like this:

        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            Log.i(TAG, "New connection state: " + newState);
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                Log.i(TAG, "Connection successful");
                new Handler(Looper.getMainLooper()).postDelayed(
                        gatt::discoverServices, DELAY_BEFORE_DISCOVERING);

            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                if (status == CONNECTION_ERROR) { // Error 133
                    Log.i(TAG, "Connection error. Trying again.");
                    connect(device);
                } else {
                    bluetoothGatt.close();
                    Log.i(TAG, "Disconnected");
                }
            }
        }

Log looks like this:

2019-03-06 08:26:20.415 5905-5905/app I/LeBluetoothDevice: Write status: true 2019-03-06 08:26:20.417 5905-7919/app I/LeBluetoothDevice: Characteristic write status: 0 2019-03-06 08:26:21.069 5905-9996/app V/FA: Inactivity, disconnecting from the service 2019-03-06 08:26:26.151 5905-7919/app D/BluetoothGatt: onClientConnectionState() - status=8 clientIf=9 device=00:0D:19:00:88:D5 2019-03-06 08:26:26.153 5905-7919/app I/LeBluetoothDevice: New connection state: 0 2019-03-06 08:26:26.154 5905-7919/app D/BluetoothGatt: close() 2019-03-06 08:26:26.155 5905-7919/app D/BluetoothGatt: unregisterApp() - mClientIf=9 2019-03-06 08:26:26.163 5905-7919/app I/LeBluetoothDevice: Disconnected

Any suggestions on how to handle this would be appreciated

Upvotes: 0

Views: 278

Answers (2)

RBusarow
RBusarow

Reputation: 754

You can (and should) also make use of your BluetoothGattCallback here. Discovering services triggers BluetoothGattCallback.onServicesDiscovered(). You should make use of that callback in your scheduling.

I've found that it's best to implement a retry loop with a delay. That way, when the connection does fully initialize immediately you get a better experience. Try immediately, and if the callback hasn't fired within 2-300ms, try again, then again, etc. until you feel you've tried long enough.

Upvotes: 1

SMGhost
SMGhost

Reputation: 4037

Ok, so my issue was with DELAY_BEFORE_DISCOVERING which was ~600 ms. It appears samsung galaxy s7 needs at least 1500ms here. With it I was able to connect every time I tried.

Upvotes: 0

Related Questions