禁用并重新启用蓝牙适配器后,如何使Android连接?

时间:2018-08-30 09:31:43

标签: android bluetooth bluetooth-lowenergy android-bluetooth android-ble

我编写了一个连接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);
            }
        }
    }
};

所有调用都通过处理程序发布到主线程。我可以看到它等待连接,在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的所有不良行为并将其收集到数据库中。如果您有兴趣捐款,请随时给我发邮件bt.error@millibit.dk

1 个答案:

答案 0 :(得分:3)

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

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

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