赞
踩
在写《Android蓝牙开发系列文章-蓝牙音箱连接》时,计划细化出两篇文章,分别是:
关于蓝牙设备类型分类的,这个已经完成了,阅读请点击《Android蓝牙开发系列文章-蓝牙设备类型知多少?》。
今天我们要完成的是另外一篇:如何扫描蓝牙设备,怎么快速的、准确的扫描设备。
你也许会问,什么叫准确的扫描设备?难道我们在扫描的时候可以指定要扫描设备吗?
答案是肯定的,让我们慢慢讲来~
目录
在《Android蓝牙开发系列文章-蓝牙设备类型知多少?》中,我们没有提“经典蓝牙”和“低功耗蓝牙”的事儿,这里怎么又冒出了这两个概念?
其实,我们在上一节说的蓝牙设备类型,是从功能角度出发进行定义的一种概念。就是说这个蓝牙设备是个音箱,还是一个鼠标。
而今天说的这两个类型是比较专业化的概念,一般人,我是不告诉他的,谁让你关注了我呢,来,让我告诉你。
经典蓝牙设备:又称为传统蓝牙设备,英文为Classic Bluetooth,主要用于传输数据量比较大的功能传输,例如,蓝牙音箱。
低功耗蓝牙设备:英文为Bluetooth Low Energy,最大的特点是功耗的降低,主要用于实时性要求较高、但数据量不大的产品中,例如,蓝牙灯、蓝牙手环等等。
讲完了这两个概念,我们再来讲两个: 单模设备、双模设备。
单模设备:是指进具有经典蓝牙设备功能或者低功耗蓝牙功能的设备。例如,仅仅具有心率测量功能的手环。
双模设备:是指同时具有经典蓝牙设备功能和低功耗蓝牙功能的设备。例如,既具有心率测量功能,又具有通话功能的手环。再例如,我们现在智能电视的蓝牙遥控器(语音功能使用的是经典蓝牙,按键功能使用的是低功耗蓝牙)。再例如,小米的小爱音箱,它就是典型的双模设备,具有两个mac地址。
在这里要说一下,不是所有的双模设备都是两个mac地址,有的也仅是一个mac地址。我抽空会再写一下蓝牙mac 地址的分类(如果一直这样细化下去,不知道我的蓝牙专题是否要写100+篇?),不知道你是否期待?
讲完了概念,我们接着讲“姿势一”,如果你读过我之前写的蓝牙音箱连接的文章,你应该知道了经典蓝牙设备如何扫描了。
调用BluetoothAdapter::startDiscovery()接口,然后接受广播,从广播中解析出你想要的设备。这种方法扫描出的蓝牙设备不仅仅是只能扫描到经典蓝牙,也会扫描到低功耗蓝牙。如果你要扫描经典蓝牙的话,只能忍受这一个弊端了,因为没有别的招了。
如想了解经典蓝牙设备的扫描,请移步《Android蓝牙开发系列文章-蓝牙音箱连接》。我在这里就不再讲解一遍了。
下面开始讲一下经典蓝牙设备的扫描。
第一步,要先申请必要的权限,
- <!--蓝牙权限-->
- <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
因为家里只有一个低功耗蓝牙设备,所以没有扫描出来其他设备(这可不是因为这个接口具有扫描指定设备的功能哈,因为它并没有,不然怎么被废弃了呢)。
这里将一个时髦的蓝牙扫描接口,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}
利用上面提到了方式3 来进行设备扫描有什么好处呢?
在蓝牙固件中即进行设备匹配,可以大大减少蓝牙协议栈以及应用层的操作,降低内存占用、CPU占用。
可以根据需要进行扫描参数的设置,实现动态调整,进而实现快速扫描目标设备。
天不早了,该休息了~
本博客始终坚持理论与实践相结合,想尽最大努力将知识点讲解清楚,但不知道实际效果如何,
如果有任何建议,可以随时跟我沟通,谢谢。
如果想持续关注本博客内容,请扫描关注个人微信公众号,或者微信搜索:万物互联技术。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。