Android BLE重新连接非常慢

时间:2015-11-20 20:48:00

标签: android bluetooth-lowenergy android-bluetooth

背景

我有一个BLE外围设备有两种模式:"应用程序"和#34; Bootloader"。在这两种模式下,设备都使用相同的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。

1 个答案:

答案 0 :(得分: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的参数。如果找不到设备,连接请求将在30秒左右超时。