【问题标题】:Android BLE reconnection very slowAndroid BLE重连很慢
【发布时间】:2015-11-20 20:48:00
【问题描述】:

背景:

我有一个具有两种模式的 BLE 外设:“应用程序”和“引导加载程序”。在这两种模式下,设备都使用相同的 MAC 地址进行通告。

要从一种模式切换到另一种模式,BLE 外围设备必须自行重启。这样做时,它必须断开任何活动的 BLE 连接。

BLE 外设仅在 Bootloader 模式下停留约 5 秒。如果没有人在该窗口内连接到它,它会切换到应用程序模式。

问题:

Android 需要很长时间才能重新连接到 BLE 设备,以至于我错过了 5 秒的窗口。原始代码有几层,一直到 BluetoothGATT 和 BluetoothAdapter 层,但调用顺序归结为:

BluetoothGattCharacteristic c = mCharacteristics.get(POWER_STATE_UUID);
c.setValue(SHUTDOWN_VALUE);
mBluetoothGatt.writeCharacteristic(c);
// Signalled by BluetoothGattCallback.onCharacteristicWrite
bleWriteCondition.await();

mBluetoothGatt.disconnect();
// Wait for the underlying layer to confirm we're disconnected
while( mConnectionState != BluetoothProfile.STATE_DISCONNECTED ) {
    // Signalled by BluetoothGattCallback.onConnectionStateChange
    bleStateCondition.await(); 
}
mBluetoothGatt.connect();
while (mConnectionState != BluetoothProfile.STATE_CONNECTED) {
    // Signalled by BluetoothGattCallback.onConnectionStateChange
    bleStateCondition.await();
    if (bleStateCondition.stat != 0) {
        break;
    }
}

我是不是完全走错了路?我尝试在 BluetoothGatt 实例上调用 close(),然后使用 BluetoothDevice.connectGatt 生成一个新实例,但我得到了同样的极其缓慢的行为。

我正在三星 Galaxy S4 上进行测试,API 级别 21。

【问题讨论】:

  • 设备多久做一次广告?
  • 在引导加载程序模式下,每 100 毫秒一次。在应用程序模式下,每秒一次。
  • 这个问题你解决了吗?我看到在失去与 ble 设备的连接后,即使您手动调用 disconnect()、close()、connect(),也需要 20 秒才能重新连接到同一个外围设备,无论使用直接还是后台
  • 我管理了一个适用于某些 Android 版本的解决方法。我在外围设备的重启命令中安装了延迟,以便 Android 设备可以启动断开连接。所以外围设备接收到重启命令,但直到Android端关闭连接才真正重启。然后,Android 可以重新连接到外围设备。显然,这仅在您可以访问外围设备的固件时才有效,但我希望它会有所帮助。
  • @James 谢谢,这是一种有趣的方式。我在外围设备重新启动之前添加了 0.5 秒的延迟,现在外围设备实际上有时间在重新启动电源之前正确断开连接。在某些较低层,断开例程必须包括通知链路的另一端,因为现在 Android 设备会立即断开连接并能够快速重新连接。谢谢

标签: android bluetooth-lowenergy android-bluetooth


【解决方案1】:

这里的问题是 gatt connect 调用发出一个后台连接请求。此调用可能需要很长时间才能建立连接。两种连接请求的描述在这里:Direct vs Background connections

获得连接的绝对最快方法是进行扫描,并在找到您的设备后向其发出直接连接请求。由于扫描刚刚找到它,您知道它就在那里,连接将很快完成。这比您的示例代码更复杂,但考虑到您的小窗口,这将是最有效的。扫描是查找设备的最激进方式。但是,如果您已经拥有设备对象,则可以在设备上调用直接连接请求。

使用如下代码发出扫描:

scanner = bluetoothAdapter.getBluetoothLeScanner();
settings = new ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .build();
filters = new ArrayList<ScanFilter>();
ScanFilter uuidFilter = new ScanFilter.Builder()
            .setServiceUuid(YOUR_SERVICE_UUID).build();
filters.add(uuidFilter);
scanner.startScan(filters, settings, myScanCallback);

找到您的设备后(使用扫描回调),通过此方法调用发出直接连接请求:

myGatt = myDevice.connectGatt(this, false, myGattCallback);

关键部分是false的参数。如果没有找到设备,连接请求将在 30s 左右超时。

【讨论】:

  • 您是否使用任何 BLE 设备测试了这段代码?目前,我在从 Android 5 连接时遇到连接问题
  • 这是从部署在现场的应用程序中获取的代码。这个问题和答案是特定于获得连接所花费的时间,它不是连接到比上述复杂得多的 BLE 设备的完整解决方案。
猜你喜欢
  • 2014-04-08
  • 1970-01-01
  • 2015-09-06
  • 2012-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 1970-01-01
相关资源
最近更新 更多