【问题标题】:How to make Android connect after the Bluetooth Adapter has been disabled & reenabled?禁用并重新启用蓝牙适配器后如何使 Android 连接?
【发布时间】:2018-08-30 09:31:42
【问题描述】:

我编写了一个连接到 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 的所有异常行为并将其收集到数据库中。如果您有兴趣做出贡献,请随时通过 bt.error@millibit.dk 给我发邮件

【问题讨论】:

  • 我禁用 BT 几秒钟,然后再次启用它。然后我启动应用程序,该应用程序将自动连接到上次连接的同一地址。我已经从日志中确认了这一点: 11:23:19.191 D/GattConnection: mGatt.connect(DE:97:0D:7F:2E:32, foreground[fast]) success 11:23:49.193 D/GattConnection: onBluetoothDisconnect
  • 您的外围设备有公共蓝牙设备地址还是随机地址?另外,您的设备是否已绑定?但我真的不明白你的问题;蓝牙关闭当然不能连接?
  • 蓝牙未关闭。我已经更新了描述以更好地解释。地址是随机的,不会改变。 “随机”地址存储在设备的出厂设置中。此外,设备未绑定。我完全控制了该设备,并确认没有进行连接尝试。我还用 IToken 检查了这一点。问题是一样的。禁用蓝牙后,您将无法建立连接。
  • 是的,华为 P8 Lite 的 BLE 在很多方面都被破坏了。它通常只是随机失败。

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


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多