在寫《Android藍牙開發系列文章-藍牙音箱連接》時,計劃細化出兩篇文章,分別是:
關於藍牙設備類型分類的,這個已經完成了,閱讀請點擊《Android藍牙開發系列文章-藍牙設備類型知多少?》。
今天我們要完成的是另外一篇:如何掃描藍牙設備,怎麼快速的、準確的掃描設備。
你也許會問,什麼叫準確的掃描設備?難道我們在掃描的時候可以指定要掃描設備嗎?
答案是肯定的,讓我們慢慢講來~
目錄
1.姿勢一:掃描經典藍牙
在《Android藍牙開發系列文章-藍牙設備類型知多少?》中,我們沒有提“經典藍牙”和“低功耗藍牙”的事兒,這裏怎麼又冒出了這兩個概念?
其實,我們在上一節說的藍牙設備類型,是從功能角度出發進行定義的一種概念。就是說這個藍牙設備是個音箱,還是一個鼠標。
而今天說的這兩個類型是比較專業化的概念,一般人,我是不告訴他的,誰讓你關注了我呢,來,讓我告訴你。
經典藍牙設備:又稱爲傳統藍牙設備,英文爲Classic Bluetooth,主要用於傳輸數據量比較大的功能傳輸,例如,藍牙音箱。
低功耗藍牙設備:英文爲Bluetooth Low Energy,最大的特點是功耗的降低,主要用於實時性要求較高、但數據量不大的產品中,例如,藍牙燈、藍牙手環等等。
講完了這兩個概念,我們再來講兩個: 單模設備、雙模設備。
單模設備:是指進具有經典藍牙設備功能或者低功耗藍牙功能的設備。例如,僅僅具有心率測量功能的手環。
雙模設備:是指同時具有經典藍牙設備功能和低功耗藍牙功能的設備。例如,既具有心率測量功能,又具有通話功能的手環。再例如,我們現在智能電視的藍牙遙控器(語音功能使用的是經典藍牙,按鍵功能使用的是低功耗藍牙)。再例如,小米的小愛音箱,它就是典型的雙模設備,具有兩個mac地址。
在這裏要說一下,不是所有的雙模設備都是兩個mac地址,有的也僅是一個mac地址。我抽空會再寫一下藍牙mac 地址的分類(如果一直這樣細化下去,不知道我的藍牙專題是否要寫100+篇?),不知道你是否期待?
講完了概念,我們接着講“姿勢一”,如果你讀過我之前寫的藍牙音箱連接的文章,你應該知道了經典藍牙設備如何掃描了。
調用BluetoothAdapter::startDiscovery()接口,然後接受廣播,從廣播中解析出你想要的設備。這種方法掃描出的藍牙設備不僅僅是隻能掃描到經典藍牙,也會掃描到低功耗藍牙。如果你要掃描經典藍牙的話,只能忍受這一個弊端了,因爲沒有別的招了。
如想了解經典藍牙設備的掃描,請移步《Android藍牙開發系列文章-藍牙音箱連接》。我在這裏就不再講解一遍了。
2.姿勢二:用過時的接口掃描低功耗藍牙
下面開始講一下經典藍牙設備的掃描。
第一步,要先申請必要的權限,
<!--藍牙權限-->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<!--BLE掃描權限-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!--藍牙ble feature檢查,只有在由此feature的設備上才能安裝本應用-->
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
我在寫demo的過程中發現,靜態申請了BLE掃描的權限沒有生效,沒有掃描到任何設備,經過上網百度獲悉,從Android6.0開始需要動態申請位置權限,所以有了如下一段代碼:
private void requestPermission() {
//動態申請是否有必要看sdk版本哈
if (Build.VERSION.SDK_INT < 23){return;}
//判斷是否有權限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//請求權限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//請求權限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}
}
先獲取BluetoothAdapter對象,然後調用BluetoothAdapter::startLeScan(LeScanCallback callback)發起設備掃描。
掃碼到的設備都會在onLeScan()中拿到。
//藍牙編程千古不變:第一行代碼
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Log.d(TAG, "mBluetoothAdapter = " + mBluetoothAdapter);
//設備回調,掃描到的設備都在onLeScan()中拿到
private static LeScanCallback mLeScanCallback = new LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
if(device == null || device.getName() == null || device.getAddress() == null) {
return;
}
Log.d(TAG, "onLeScan(), device = " + device.getName() + "mac = " + device.getAddress() + "rssi = " + rssi);
for (int i = 0; i < scanRecord.length; i++) {
Log.d(TAG, "onLeScan(), device = " + device.getName() + "content = " + scanRecord[i]);
}
}
};
//調用BluetoothAdapter.startLeScan(LeScanCallback callback)發起設備掃描
private void startBleScan1() {
boolean ret = mBluetoothAdapter.startLeScan(mLeScanCallback);
Log.d(TAG, "startBtScan(),ret = " + ret);
}
運行一下我們的demo,看一下掃描結果,家裏的唯一一個低功耗設備,藍牙體脂秤,被掃描出來了。
03-16 21:07:32.130 9909-9909/com.atlas.devicefinder D/MainActivity: mBluetoothAdapter = android.bluetooth.BluetoothAdapter@ddeeda9
03-16 21:07:32.131 9909-9909/com.atlas.devicefinder D/MainActivity: mBluetoothLeScanner = android.bluetooth.le.BluetoothLeScanner@e0adf2e
03-16 21:07:34.947 9909-9909/com.atlas.devicefinder D/MainActivity: onClick,View = androidx.appcompat.widget.AppCompatButton{e036fde VFED..C.. ...P.... 0,0-426,144 #7f070042 app:id/bt_start_blescan1}
03-16 21:07:34.970 9909-9909/com.atlas.devicefinder D/MainActivity: startBtScan(),ret = true
03-16 21:07:40.498 9909-9909/com.atlas.devicefinder D/MainActivity: onLeScan(), device = 1LS_W_9mac = 08:7C:BE:48:65:ADrssi = -78
03-16 21:07:40.499 9909-9909/com.atlas.devicefinder D/MainActivity: onLeScan(), device = 1LS_W_9content = 10
03-16 21:07:40.501 9909-9909/com.atlas.devicefinder D/MainActivity: onLeScan(), device = 1LS_W_9content = 9
03-16 21:07:40.503 9909-9909/com.atlas.devicefinder D/MainActivity: onLeScan(), device = 1LS_W_9content = 49
03-16 21:07:40.505 9909-9909/com.atlas.devicefinder D/MainActivity: onLeScan(), device = 1LS_W_9content = 76
03-16 21:07:40.508 9909-9909/com.atlas.devicefinder D/MainActivity: onLeScan(), device = 1LS_W_9content = 83
03-16 21:07:40.509 9909-9909/com.atlas.devicefinder D/MainActivity: onLeScan(), device = 1LS_W_9content = 95
03-16 21:07:40.512 9909-9909/com.atlas.devicefinder D/MainActivity: onLeScan(), device = 1LS_W_9content = 87
03-16 21:07:40.513 9909-9909/com.atlas.devicefinder D/MainActivity: onLeScan(), device = 1LS_W_9content = 95
03-16 21:07:40.515 9909-9909/com.atlas.devicefinder D/MainActivity: onLeScan(), device = 1LS_W_9content = 57
03-16 21:07:40.517 9909-9909/com.atlas.devicefinder D/MainActivity: onLeScan(), device = 1LS_W_9content = 0
03-16 21:07:40.518 9909-9909/com.atlas.devicefinder D/MainActivity: onLeScan(), device = 1LS_W_9content = 0
03-16 21:07:40.519 9909-9909/com.atlas.devicefinder D/MainActivity: onLeScan(), device = 1LS_W_9content = 2
03-16 21:07:40.521 9909-9909/com.atlas.devicefinder D/MainActivity: onLeScan(), device = 1LS_W_9content = 1
03-16 21:07:40.524 9909-9909/com.atlas.devicefinder D/MainActivity: onLeScan(), device = 1LS_W_9content = 6
03-16 21:07:40.526 9909-9909/com.atlas.devicefinder D/MainActivity: onLeScan(), device = 1LS_W_9content = 5
因爲家裏只有一個低功耗藍牙設備,所以沒有掃描出來其他設備(這可不是因爲這個接口具有掃描指定設備的功能哈,因爲它並沒有,不然怎麼被廢棄了呢)。
3.姿勢三:用時髦的接口掃描低功耗藍牙
這裏將一個時髦的藍牙掃描接口,BluetoothLeScanner::startScan()。這個接口的定義如下所示,第一個參數就是對掃描到的設備的過濾條件,第二個參數表示的是對本次掃描的設置,第三個參數用於接收掃描結果(如果有過濾條件,則是經過濾後的設備)。
/**
* Start Bluetooth LE scan. The scan results will be delivered through {@code callback}.
* For unfiltered scans, scanning is stopped on screen off to save power. Scanning is
* resumed when screen is turned on again. To avoid this, do filetered scanning by
* using proper {@link ScanFilter}.
* <p>
* An app must hold
* {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
* {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
* in order to get results.
*
* @param filters {@link ScanFilter}s for finding exact BLE devices.
* @param settings Settings for the scan.
* @param callback Callback used to deliver scan results.
* @throws IllegalArgumentException If {@code settings} or {@code callback} is null.
*/
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public void startScan(List<ScanFilter> filters, ScanSettings settings,
final ScanCallback callback) {
startScan(filters, settings, null, callback, /*callbackIntent=*/ null, null);
}
我們先不設置過濾條件,看一下該方法如何使用:
先獲取BluetoothLeScanner對象,然後調用其startScan(ScanCallback callback)方法,看到沒,就只有一個回調參數。
//先獲取BluetoothLeScanner對象
private BluetoothLeScanner mBluetoothLeScanner = null;
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
private void startBleScan2() {
mBluetoothLeScanner.startScan(mScanCallback);
}
//回調接口
private static ScanCallback mScanCallback = new ScanCallback() {
//每掃描到一個BLE設備,就接收到一次回調
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
Log.d(TAG, "onScanResult, result = " + result);
}
//批量回調接口
@Override
public void onBatchScanResults(List<ScanResult> results) {
super.onBatchScanResults(results);
Log.d(TAG, "onBatchScanResults");
}
//掃描失敗的回調,可以根據失敗的原因執行不同策略,例如,重新掃描或者
//先停止當前掃描,再重新發起掃描
@Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
Log.d(TAG, "onScanFailed, errorCode = " + errorCode);
}
};
我們這樣搞,會得到一個什麼樣的掃描結果呢?可以看到除了我家的體脂秤,也掃描到了另外一個BLE設備(反正不是俺家的,不知道誰的)。我還特意把我家的藍牙音箱打開了,結果可想而知:掃不到~
03-15 20:41:37.946 10425-10425/com.atlas.devicefinder D/MainActivity: mBluetoothAdapter = android.bluetooth.BluetoothAdapter@bc4da35
03-15 20:41:37.947 10425-10425/com.atlas.devicefinder D/MainActivity: mBluetoothLeScanner = android.bluetooth.le.BluetoothLeScanner@74b3eca
03-15 20:41:41.476 10425-10425/com.atlas.devicefinder D/MainActivity: onClick,View = androidx.appcompat.widget.AppCompatButton{e98ee7a VFED..C.. ...P.... 0,288-426,432 #7f070043 app:id/bt_start_blescan2}
03-15 20:41:47.466 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5B:CE:4F:45:38:61, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, -47, -34, -112]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-97, mTimestampNanos=86214200338022}
03-15 20:41:52.332 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5B:CE:4F:45:38:61, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, -47, -34, -112]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-94, mTimestampNanos=86219088416145}
03-15 20:41:56.438 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5B:CE:4F:45:38:61, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, -47, -34, -112]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-94, mTimestampNanos=86223197857185}
03-15 20:41:58.892 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5B:CE:4F:45:38:61, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, -47, -34, -112]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-93, mTimestampNanos=86225651024476}
03-15 20:42:04.863 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5B:CE:4F:45:38:61, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, -47, -34, -112]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-95, mTimestampNanos=86231621502599}
03-15 20:42:05.935 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5B:CE:4F:45:38:61, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, -47, -34, -112]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-94, mTimestampNanos=86232694169265}
03-15 20:42:12.296 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=08:7C:BE:48:65:AD, mScanRecord=ScanRecord [mAdvertiseFlags=6, mServiceUuids=[0000fee7-0000-1000-8000-00805f9b34fb, 0000d618-0000-1000-8000-00805f9b34fb], mManufacturerSpecificData={0=[8, 124, -66, 72, 101, -83]}, mServiceData={}, mTxPowerLevel=-2147483648, mDeviceName=1LS_W_9����], mRssi=-71, mTimestampNanos=86239051067804}
03-15 20:42:12.436 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5B:CE:4F:45:38:61, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, -47, -34, -112]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-94, mTimestampNanos=86239196387388}
03-15 20:42:12.712 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5B:CE:4F:45:38:61, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, -47, -34, -112]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-98, mTimestampNanos=86239469748846}
03-15 20:42:17.346 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5B:CE:4F:45:38:61, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, -47, -34, -112]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-87, mTimestampNanos=86244101039261}
03-15 20:42:17.616 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5B:CE:4F:45:38:61, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, -47, -34, -112]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-87, mTimestampNanos=86244372349886}
03-15 20:42:22.388 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5A:C1:FA:54:54:0F, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, 17, 115, -33]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-42, mTimestampNanos=86249143803842}
03-15 20:42:22.657 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5A:C1:FA:54:54:0F, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, 17, 115, -33]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-42, mTimestampNanos=86249413593842}
03-15 20:42:27.374 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5A:C1:FA:54:54:0F, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, 17, 115, -33]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-50, mTimestampNanos=86254130413424}
03-15 20:42:27.421 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5B:CE:4F:45:38:61, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, -47, -34, -112]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-96, mTimestampNanos=86254178738632}
03-15 20:42:27.642 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5A:C1:FA:54:54:0F, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, 17, 115, -33]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-38, mTimestampNanos=86254399760298}
03-15 20:42:27.693 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5B:CE:4F:45:38:61, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, -47, -34, -112]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-96, mTimestampNanos=86254451050298}
03-15 20:42:32.251 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5A:C1:FA:54:54:0F, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, 17, 115, -33]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-39, mTimestampNanos=86259010351130}
03-15 20:42:32.309 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5B:CE:4F:45:38:61, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, -47, -34, -112]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-93, mTimestampNanos=86259068604255}
03-15 20:42:32.527 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5A:C1:FA:54:54:0F, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, 17, 115, -33]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-40, mTimestampNanos=86259282907588}
03-15 20:42:37.525 10425-10425/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=5A:C1:FA:54:54:0F, mScanRecord=ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={76=[16, 5, 81, 28, 17, 115, -33]}, mServiceData={}, mTxPowerLevel=12, mDeviceName=null], mRssi=-37, mTimestampNanos=86264281754670}
既然這種掃描方式可以對掃描和過濾進行設置,那我們來試一下子吧~
在這裏,我想僅僅掃描家裏的體脂秤,所以,調用了setDeviceAddress(string)方法,把體脂秤的mac地址傳遞進去。
其實,這個時候就OK了,因爲藍牙mac地址是設備的唯一標識嘛,這樣設備就一定會只掃描到我的目標設備了。
可是,我想把事情搞大一點,給過濾再加點限制,看是否還能掃描成功。
我又setServiceUuid()方法將體脂秤支持的service uuid傳遞進來。
//過濾條件
List<ScanFilter> bleScanFilters = new ArrayList<>();
ScanFilter filter = new ScanFilter.Builder().setDeviceAddress("08:7C:BE:48:65:AD").setServiceUuid(ParcelUuid.fromString("0000fee7-0000-1000-8000-00805f9b34fb")).build();
bleScanFilters.add(filter);
再來對掃描設置進行一些定製:
設置掃描模式爲低延遲模式,這種模式下可以更快的進行設備掃描,除此之外,還有均衡模式(SCAN_MODE_BALANCED)、低功耗模式(SCAN_MODE_LOW_POWER)。從字面意思,你應該也能猜出來,低延遲模式掃描設備最快,低功耗模式掃描設備最慢,均衡模式居中。
設置回調模式爲全匹配(CALLBACK_TYPE_ALL_MATCHES),就是說,如果我們設置了過濾條件,則只上報過濾條件都完全匹配的設備,如果沒有設置任何過濾條件,則上報掃描到的所有設備。
設置粘性匹配,就是在掃描到的設備滿足一定信號強度時,纔去跟過濾條件進行匹配,信號強度太弱,藍牙固件直接丟棄,也不會去做匹配操作。
最後,我們將兩個參數傳遞到startScan()方法中來。
//掃描設置
ScanSettings scanSetting = new ScanSettings.Builder().setScanMode(SCAN_MODE_LOW_LATENCY).setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES).setMatchMode(ScanSettings.MATCH_MODE_STICKY).build();
mBluetoothLeScanner.startScan(bleScanFilters, scanSetting, mScanCallback);
看一下此時的掃描結果,我們的目標設備是可以正常掃描到,並且上報設備的粒度明顯降低了。
03-15 21:12:14.335 16060-16060/com.atlas.devicefinder D/MainActivity: onClick,View = androidx.appcompat.widget.AppCompatButton{e98ee7a VFED..C.. ...P.... 0,288-426,432 #7f070043 app:id/bt_start_blescan2}
03-15 21:12:15.177 16060-16060/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=08:7C:BE:48:65:AD, mScanRecord=ScanRecord [mAdvertiseFlags=6, mServiceUuids=[0000fee7-0000-1000-8000-00805f9b34fb, 0000d618-0000-1000-8000-00805f9b34fb], mManufacturerSpecificData={0=[8, 124, -66, 72, 101, -83]}, mServiceData={}, mTxPowerLevel=-2147483648, mDeviceName=1LS_W_9����], mRssi=-77, mTimestampNanos=88041917514200}
03-15 21:12:19.962 16060-16060/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=08:7C:BE:48:65:AD, mScanRecord=ScanRecord [mAdvertiseFlags=6, mServiceUuids=[0000fee7-0000-1000-8000-00805f9b34fb, 0000d618-0000-1000-8000-00805f9b34fb], mManufacturerSpecificData={0=[8, 124, -66, 72, 101, -83]}, mServiceData={}, mTxPowerLevel=-2147483648, mDeviceName=1LS_W_9����], mRssi=-85, mTimestampNanos=88046719595240}
03-15 21:12:22.366 16060-16060/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=08:7C:BE:48:65:AD, mScanRecord=ScanRecord [mAdvertiseFlags=6, mServiceUuids=[0000fee7-0000-1000-8000-00805f9b34fb, 0000d618-0000-1000-8000-00805f9b34fb], mManufacturerSpecificData={0=[8, 124, -66, 72, 101, -83]}, mServiceData={}, mTxPowerLevel=-2147483648, mDeviceName=1LS_W_9����], mRssi=-70, mTimestampNanos=88049124682114}
03-15 21:12:24.775 16060-16060/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=08:7C:BE:48:65:AD, mScanRecord=ScanRecord [mAdvertiseFlags=6, mServiceUuids=[0000fee7-0000-1000-8000-00805f9b34fb, 0000d618-0000-1000-8000-00805f9b34fb], mManufacturerSpecificData={0=[8, 124, -66, 72, 101, -83]}, mServiceData={}, mTxPowerLevel=-2147483648, mDeviceName=1LS_W_9����], mRssi=-70, mTimestampNanos=88051533382946}
03-15 21:12:27.180 16060-16060/com.atlas.devicefinder D/MainActivity: onScanResult, result = ScanResult{mDevice=08:7C:BE:48:65:AD, mScanRecord=ScanRecord [mAdvertiseFlags=6, mServiceUuids=[0000fee7-0000-1000-8000-00805f9b34fb, 0000d618-0000-1000-8000-00805f9b34fb], mManufacturerSpecificData={0=[8, 124, -66, 72, 101, -83]}, mServiceData={}, mTxPowerLevel=-2147483648, mDeviceName=1LS_W_9����], mRssi=-70, mTimestampNanos=88053936127529}
4.總結
利用上面提到了方式3 來進行設備掃描有什麼好處呢?
在藍牙固件中即進行設備匹配,可以大大減少藍牙協議棧以及應用層的操作,降低內存佔用、CPU佔用。
可以根據需要進行掃描參數的設置,實現動態調整,進而實現快速掃描目標設備。
天不早了,該休息了~
本博客始終堅持理論與實踐相結合,想盡最大努力將知識點講解清楚,但不知道實際效果如何,
如果有任何建議,可以隨時跟我溝通,謝謝。
如果想持續關注本博客內容,請掃描關注個人微信公衆號,或者微信搜索:萬物互聯技術。