14

我有一个在 Android 4.3 和 4.4 上运行良好的应用程序。该应用程序将与自定义蓝牙设备连接并通信。
在我将 Nexus 5 刷到 Lollipop 后,我突然无法连接到设备。连接结果始终为 133。这是日志:

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

我的代码:

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

有人对此有任何想法吗?

4

4 回答 4

19

所以我发现问题出在 Lollipop 中的 Transport 选择上。
正如你在这里看到的变化

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

函数正在调用

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

传输设置为 TRANSPORT_AUTO。
就我而言,因为我将始终使用 TRANSPORT_LE(值为 2)
,所以我尝试从我的代码中调用第二种方法并将传输设置为 TRANSPORT_LE。由于未知原因,我不能直接调用它,所以我使用反射来调用它。到目前为止,这对我来说很好。

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

如果你们中的任何人对我的回答有任何疑问,请随时在评论中提问。
谢谢你。

于 2015-03-17T06:28:48.993 回答
4

对于有同样问题的Xamarin用户,这里有一个稍微不同的解决方案。我在使用 Xamarin 跨平台 SDK 的 Nexus 7 Android 6 上遇到了同样的问题。使用 TRANSPORT_LE 解决了这个问题。与其使用反射通过其签名获取方法(不起作用),不如使用反射遍历所有方法,直到找到匹配的名称。请参见下面的代码:

BluetoothDevice bd = (BluetoothDevice)device.NativeDevice;
Java.Lang.Reflect.Method[] methods = bd.Class.GetDeclaredMethods();

foreach (Java.Lang.Reflect.Method possibleConnectGattMethod in methods) 
{
// Find matching method name connectGatt and then invoke it with     TRANSPORT_LE
}
于 2016-03-02T06:26:44.383 回答
0

我不认为自己使用反射调用 connectGatt 方法是明智的。由于私有功能可以随时随着更新而更改,因此您的应用程序会出现错误。

无论如何,如果在外围广告数据包中设置了适当的标志,TRANSPORT_AUTO 应该尝试以所需的方式连接到外围设备。如果您的外围设备不支持 TRANSPORT_BREDR 模式,那么您应该在广告数据中设置一个标准标志“BrEdrNotSupported”,让中央知道它。

于 2015-04-02T23:34:31.657 回答
0

您使用的是哪种 BLE IC?如果是 CC254x,则可能与外围设备的软件堆栈问题有关:

https://e2e.ti.com/support/wireless_connectivity/f/538/t/401240

于 2015-04-09T02:25:14.303 回答