天天看點

android ble藍牙不穩定,Android BLE重新連接配接非常慢

背景:

我有一個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.

解決方法:

這裡的問題是gatt connect調用發出背景連接配接請求.此調用可能需要相當長的時間才能生成連接配接.這兩種連接配接請求的描述如下:Direct vs Background connections

獲得連接配接的絕對最快方式是進行掃描,并在找到裝置時向其發出直接連接配接請求.當掃描剛剛找到它時,您知道它就在那裡,連接配接将很快完成.這比您的示例代碼更複雜,但是在您的小視窗的情況下最有效.掃描是查找裝置最積極的方式.但是,如果您已有裝置對象,則隻需在裝置上調用直接連接配接請求即可.

掃描是使用以下代碼發出的:

scanner = bluetoothAdapter.getBluetoothLeScanner();

settings = new ScanSettings.Builder()

.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)

.build();

filters = new ArrayList();

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秒左右逾時.

标簽:android,bluetooth-lowenergy,android-bluetooth

來源: https://codeday.me/bug/20190706/1397909.html