如何在蓝牙适配器被禁用和重新启用后进行Android连接?

问题描述 投票:1回答:1

我写了一个连接到BLE设备的应用程序。该应用程序在大多数设备上运行正常但有些设备(最明显的是华为P8 Lite和Nexus 6P)在蓝牙适配器被禁用后拒绝连接。

这是测试序列:

  1. 确保应用程序未运行。
  2. 从顶部向下滑动,禁用BT几秒钟,然后重新启用蓝牙。
  3. 启动应用程序。该应用程序自动连接到首选项中存储的蓝牙地址。
  4. 等待连接。这是华为手机上没有任何变化的地方,但其他手机,如三星,就像一个魅力。
  5. 从另一部手机验证设备是否正在做广告,您可以连接到它。

这是我用来连接的代码:

private final Runnable mBeginConnectRunnable = new Runnable() {
    @Override
    public void run() {
        synchronized (GattConnection.this) {
            if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
                try {
                    mBluetoothAdapter.cancelDiscovery();
                    mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(mAddress);
                    mGatt = mBluetoothDevice.connectGatt(mContext, mBackgroundConnect, mGattCallback);
                    final boolean connectSuccess = mGatt.connect();
                    Log.d(TAG, String.format(Locale.ENGLISH, "mGatt.connect(%s, %s) %s",
                            mAddress,
                            mBackgroundConnect ? "background[slow]" : "foreground[fast]",
                            connectSuccess ? "success" : "failed"));
                    refreshDeviceCache(mGatt);

                } catch (Exception ex) {
                    Log.e(TAG, "Create connection failed: " + ex.getMessage());
                    setState(State.Closed);
                }
            } else {
                Log.d(TAG, "Can't create connection. Adapter is disabled");
                setState(State.Closed);
            }
        }
    }
};

所有调用都通过Handler发布到主线程。我可以看到它等待连接,在30秒后放弃我在对象上调用BluetoothGatt.close()并使其为空。这就像什么都没有。

过了一段时间,在当天晚些时候,它再次起作用。

非常感谢帮助:-)

更新2018年9月14日:经过Emil的精彩解释后,我更新了我们的应用程序,因此在Nexus上没有这个问题。我注意到华为P8 Lite继续在后台扫描,似乎没有什么办法可以阻止它。

为了演示这些问题,我制作了一个非常简单和干净的应用程序,它在手机上运用蓝牙LE功能并用它来演示这个问题,并且P8也被打破了。该应用程序可在此处获取:https://play.google.com/store/apps/details?id=eu.millibit.bluetootherror来源可在此处获取:https://bitbucket.org/millibit/eu.millibit.bluetootherror/src/master/

我希望我随着时间的推移可以扩展这个应用程序,使其成为Android的一个测试工具,记录Android的所有stange行为并将其收集在数据库中。如果您有兴趣贡献,请不要犹豫,给我发邮件[email protected]

android bluetooth bluetooth-lowenergy android-bluetooth android-ble
1个回答
3
投票

Android蓝牙堆栈的API存在设计缺陷。当您通过蓝牙设备地址连接到特定设备时,无法判断您是指公共地址还是随机地址。

如果您开始连接到autoConnect = false且未绑定且最近未在扫描中看到的设备,则会假定您的意思是公共地址。因此,如果您尝试连接到具有静态随机地址的设备,它将失败。

如果设备未绑定,请确保使用正确的地址类型连接,必须首先执行扫描,找到设备,然后开始连接尝试。

© www.soinside.com 2019 - 2024. All rights reserved.