Search code examples
androidbluetoothandroid-5.0-lollipopgatt

Android - Could not connect to bluetooth device on Lollipop


I have an application that working well on Android 4.3 and 4.4. The application will connect and communicate with a custom bluetooth device.
After I flashed my Nexus 5 to Lollipop suddenly the I can't connect to the device at all. The connection result always 133. This is the log :

D/BluetoothGatt﹕ connect() - device: 00:07:80:04:1A:5A, auto: true
D/BluetoothGatt﹕ registerApp()
D/BluetoothGatt﹕ registerApp() - UUID=xxxxxx-xxxx-xxxxx-xxxx-xxxxxxxx
D/BluetoothGatt﹕ onClientRegistered() - status=0 clientIf=6
D/BluetoothGatt﹕ onClientConnectionState() - status=133 clientIf=6 device=00:07:80:04:1A:5A

My code :

public boolean connect(final String address) {
        if (mBluetoothAdapter == null || address == null) {
            return false;
        }
        Handler handler = new Handler(Looper.getMainLooper());
        // Previously connected device.  Try to reconnect.
        if (mBluetoothDeviceAddress != null
                && address.equals(mBluetoothDeviceAddress)
                && mBluetoothGatt != null) {

            handler.post(new Runnable() {
                @Override
                public void run() {
                    if (mBluetoothGatt.connect()) {
                        mConnectionState = STATE_CONNECTING;
                    }
                }
            });
            if (mConnectionState == STATE_CONNECTING) {
                return true;
            } else {
                return false;
            }
        }

        final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
        if (device == null) {
            return false;
        }

        handler.post(new Runnable() {
            @Override
            public void run() {
                mBluetoothGatt = device.connectGatt(BluetoothConnectService.this, true, mGattCallback);
            }
        });
        mBluetoothDeviceAddress = address;
        mConnectionState = STATE_CONNECTING;
        return true;
    }

Anybody have any idea about this?


Solution

  • So I figured out that the problem is the Transport choice in Lollipop.
    As you can see in here the change in the

    BluetoothDevice.connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback)

    function is calling

    BluetoothDevice.connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback, int transport)

    with transport set to TRANSPORT_AUTO.
    In my case because I will always use TRANSPORT_LE (The value is 2)
    I tried to call the second method from my code and set the transport to TRANSPORT_LE. For unknown reason I can't call it directly so I'm using reflection to call it. Until now this works fine for me.

                if(TTTUtilities.isLollipopOrAbove()) {
                    // Little hack with reflect to use the connect gatt with defined transport in Lollipop
                    Method connectGattMethod = null;
    
                    try {
                        connectGattMethod = device.getClass().getMethod("connectGatt", Context.class, boolean.class, BluetoothGattCallback.class, int.class);
                    } catch (NoSuchMethodException e) {
                        e.printStackTrace();
                    }
    
                    try {
                        mBluetoothGatt = (BluetoothGatt) connectGattMethod.invoke(device, BluetoothConnectService.this, false, mGattCallback, TRANSPORT_LE);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                } else  {
                    mBluetoothGatt = device.connectGatt(BluetoothConnectService.this, true, mGattCallback);
                }
    

    If any of you have question about my answer feel free to ask in the comment.
    Thank you.