BluetoothDevice.ConnectGatt() with transport param

2019-01-20 00:17发布

问题:

I just started with Android and set up an API 21 project in Android Studio using Bluetooth LE.

Digging into BluetoothDevice shows me two signatures of ConnectGatt() method:

public BluetoothGatt connectGatt(Context context, boolean autoConnect,
                                 BluetoothGattCallback callback)

and

public BluetoothGatt connectGatt(Context context, boolean autoConnect,
                                 BluetoothGattCallback callback, int transport)

I'd like to use the second one but the build fails:

Error:(127, 26) error: method connectGatt in class BluetoothDevice cannot be applied to given types; required: Context,boolean,BluetoothGattCallback found: Context,boolean,BluetoothGattCallback,int reason: actual and formal argument lists differ in length

It seems the compiler settings don't match the source code in Android Studio.

How can I fix this?

回答1:

If you want to use hidden API's you can invoke the method you want to use. But you have to bear in mind that a hidden API can change at any point. You have to use it at your own risk.

Here is an example code how to use the hidden connectGatt() method.

        Method connectGattMethod;
        BluetoothGatt connectGatt;

        try {
            connectGattMethod = device.getClass().getMethod("connectGatt", Context.class, boolean.class, BluetoothGattCallback.class, int.class);
        } catch (NoSuchMethodException e) {
          //NoSuchMethod
        }

        try {
            connectGatt = (BluetoothGatt) connectGattMethod.invoke(device, this, false, mBluetoothGattCallback, 2); // (2 == LE, 1 == BR/EDR)
        } catch (IllegalAccessException e) {
            //IllegalAccessException
        } catch (IllegalArgumentException e) {
            //IllegalArgumentException
        } catch (InvocationTargetException e) {
            //InvocationTargetException
        }


回答2:

UPDATE!!! I may have found a way around this defect that is bothering us so much. Since android defaults to connecting on L2CAP Channel 5 with iOS refuses to do. This is due to a bit flag on iOS advertising packet indicating BR/EDR.

Reviewing the android code I found that connectGatt() function has a hidden int TRANSPORT variable that will allow you to use AUTO or specific LE or BR/EDR only.

For some reason, this is available in the BluetoothDevice.java file in android studio, but not listed in the android code reference. When you attempt to use this, it gives you an error. If someone can explain how we can fix the compiler on android studio to compile our code using the TRANSPORT_LE option instead of TANSPORT_AUTO which I assume is being used.

Ok this is back on, let's get to work!