設備短版:減少BLE startScan檢測到的是Android 5.0棒棒糖
在我的Android 5.0棒棒糖測試中,我已經注意到android.bluetooth.le.BluetoothLeScanner
檢測BLE裝置的頻率低於Android 4.4的奇巧。這是爲什麼,還有其他選擇嗎?
龍版本:
我開發一個Android應用程序,專爲Nexus 7平板電腦,側重於檢測藍牙低功耗(BLE)設備。該應用主要關注信標的RSSI值,以確定它們與平板電腦的距離。這意味着我不需要連接到BLE設備,因爲RSSI值在檢測到設備時傳遞給掃描回調。
在Android 4.4 KitKat中,當我呼叫BluetoothAdapter.startLeScan(LeScanCallback)
時,對於每個檢測到的BLE設備,我的回調只被調用一次。 (我見過some discussions聲稱這種行爲可能會因設備而異)但是,我對不斷變化的RSSI值感興趣,所以目前推薦的方法是連續進行startLeScan和stopLeScan,並設置間隔(本例中爲250ms):
public class TheOldWay {
private static final int SCAN_INTERVAL_MS = 250;
private Handler scanHandler = new Handler();
private boolean isScanning = false;
public void beginScanning() {
scanHandler.post(scanRunnable);
}
private Runnable scanRunnable = new Runnable() {
@Override
public void run() {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (isScanning) {
adapter.stopLeScan(leScanCallback);
} else if (!adapter.startLeScan(leScanCallback)) {
// an error occurred during startLeScan
}
isScanning = !isScanning;
scanHandler.postDelayed(this, SCAN_INTERVAL_MS);
}
};
private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
// use the RSSI value
}
};
}
從本質上講,這給了我所需的結果,但是這個過程非常耗費資源,最終導致藍牙適配器無響應。
由於這些原因,我將Nexus 7升級到Android 5.0 Lollipop,查看我的BLE問題是否會得到解決。在棒棒糖BluetoothAdapter.startLeScan(LeScanCallback)已被棄用,並替換爲a new API,允許更多的控制掃描過程。從我第一次測試,這似乎startScan不會連續調用我的回調(在我的Nexus 7)當RSSI值的變化,所以我還是需要使用startScan/stopScan實現:
@TargetApi(21)
public class TheNewWay {
private static final int SCAN_INTERVAL_MS = 250;
private Handler scanHandler = new Handler();
private List<ScanFilter> scanFilters = new ArrayList<ScanFilter>();
private ScanSettings scanSettings;
private boolean isScanning = false;
public void beginScanning() {
ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder();
scanSettingsBuilder.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);
scanSettings = scanSettingsBuilder.build();
scanHandler.post(scanRunnable);
}
private Runnable scanRunnable = new Runnable() {
@Override
public void run() {
BluetoothLeScanner scanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();
if (isScanning) {
scanner.stopScan(scanCallback);
} else {
scanner.startScan(scanFilters, scanSettings, scanCallback);
}
isScanning = !isScanning;
scanHandler.postDelayed(this, SCAN_INTERVAL_MS);
}
};
private ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
int rssi = result.getRssi();
// do something with RSSI value
}
@Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
// a scan error occurred
}
};
}
正如你所看到的,我已經使用ScanSettings類配置掃描儀,它允許您設置scanMode
。我使用ScanSettings.SCAN_MODE_LOW_LATENCY
,其中包含以下文檔:「使用最高佔空比掃描。建議僅在應用程序在前臺運行時使用此模式。」聽起來和我想要的完全一樣,但不幸的是,我只能每隔15-30秒檢測一次信標,在這個掃描間隔裏,KitKat版本每隔1到2秒就會顯示一次相同的信標。
你有什麼想法可能是這種差異的原因?我錯過了什麼,也許一些新的設置?有沒有其他的方法來做到這一點?
非常感謝!
阿貝爾
PS:我想包括更多的鏈接,我已經使用的資源,但我沒有代表點呢。
在棒棒糖中「當RSSI值改變時,startScan不會連續調用我的回調(在我的Nexus 7上)」。但它是否至少每隔一段時間再打一次或只打一次?對不起,我沒有測試Nexus 7。在我的Nexus 5中,SCAN_MODE_LOW_POWER每秒都會調用它。 – sorianiv 2014-11-26 15:33:36
@abelcookingfox我幾乎得到了和你一樣不好的結果,我使用的是一加一,CM ROM 5.0.2,有時候掃描時間超過30秒,但有時候它就像死了一樣。你現在有什麼解決方案嗎? – Shawn 2015-02-07 12:57:57
我重新測試,我的One plus手機只掃描2次,那麼回調將永遠不會被解僱。 – Shawn 2015-02-07 13:25:14