您的足迹:首页 > 蓝牙BLE >android BLE 扫描BLE设备 BluetoothLeScanner

android BLE 扫描BLE设备 BluetoothLeScanner

______________________________________________________________

Android BLE 框架发布,功能全面,简单易用:

https://github.com/a1anwang/okble

______________________________________________________________

可以先看一下另一篇文章 android BLE Peripheral 手机模拟设备发出BLE广播 BluetoothLeAdvertiser

熟悉一下BLE的广播数据


BluetoothLeScanner 是android5.0 新加入的

在5.0之前扫描BLE设备 使用的方法是 :

  bluetoothAdapter.startLeScan( leScanCallback); 
 //或者 
 // UUID[] serviceUuids = new UUID[] { UUID.fromString("0000ae8f-0000-1000-8000-00805f9b34fb") };
 // bluetoothAdapter.startLeScan(serviceUuids, leScanCallback); 
 private LeScanCallback leScanCallback=new LeScanCallback() { 
         @Override 
         public void onLeScan(BluetoothDevice bluetoothdeivce, int rssi, byte[] scandata) {
                //把byte数组转成16进制字符串,方便查看 
                Log.e("TAG","scandata:"+ Bytes2HexString(scandata) +" rssi:"+rssi);
         } 

 };

可以看到,这个扫描方法已经过时了,被划了线

新和扫描方法使用的是BluetoothLeScanner,封装成了一个新的类

那么用法也很简单:


       BluetoothLeScanner bluetoothLeScanner=bluetoothAdapter.getBluetoothLeScanner();
       bluetoothLeScanner.startScan(scanCallback);
       
       private ScanCallback scanCallback=new ScanCallback() {
		@Override
		public void onScanResult(int callbackType, ScanResult result) {
			byte[] scanData=result.getScanRecord().getBytes();
                       //把byte数组转成16进制字符串,方便查看			
                        Log.e("TAG","onScanResult :"+CYUtils.Bytes2HexString(scanData));
			Log.e("TAG","onScanResult :"+result.getScanRecord().toString());
		}
		@Override
		public void onBatchScanResults(List<ScanResult> results) {
			super.onBatchScanResults(results);
		}

		@Override
		public void onScanFailed(int errorCode) {
			super.onScanFailed(errorCode);
		}
	};
BluetoothLeScanner还有另一个扫描方法,这个方法就是多了一个扫描过滤 和 扫描设置参数:
       public void startScan(List<ScanFilter> filters, ScanSettings settings, final ScanCallback callback)

我们来看一下BluetoothLeScanner 源码:

          

发现,startScan(callback) 其实是调用第2个扫描方法,只是 过滤参数为空,设置参数也是默认的。


好,不管怎么样,我们先来看下使用 startScan(callback) 扫描结果是什么样子的, 我手上的设备依然是 使用 BluetoothLeAdvertiser把手机2模拟成BLE来测试的(建议可以先看下我另一篇文章的前半部分,了解一下BLE的广播android BLE Peripheral 手机模拟设备发出BLE广播 BluetoothLeAdvertiser

模拟的广播的数据依然是:

E/TAG: scandata:02011A05FFAC0134560000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
好,那我们开始扫描看一下log打印结果:


05-24 17:01:08.011 19454-19454/jiqi.scandemo E/TAG: onScanResult :02011A05FFAC0134560000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
05-24 17:01:08.011 19454-19454/jiqi.scandemo E/TAG: onScanResult :ScanRecord [mAdvertiseFlags=26, mServiceUuids=null, mManufacturerSpecificData={428=[52, 86]}, mServiceData={}, mTxPowerLevel=-2147483648, mDeviceName=null]
可以知道,使用BluetoothLeScanner想要扫描出BLE设备的原始数据,需要通过 result.getScanRecord().getBytes() 来获取 byte[]数组


下面打印的ScanRecord 可以看到 有很多数据:

mManufacturerSpecificData={428=[52, 86]}     这个是设备厂商数据,是AC013456这一段, 通过我另一片文章知道 AC01是倒过来的,其实真实数据是01AC 两个字节,代表厂商id, 16进制数字,那么 0x01AC = 428  16进制的01AC等于10进制的428, 所有通过 log打印出来我们看到的是428,因为android studio 控制台打印默认是10进制,所以我们看到的log是428.   后面的52,86一样的道理  0x34=52, 0x56=86. 

还有一些其他数据 如 mServiceUuids,mServerData等等

好了,这样我们就知道了,其实这个新的扫描方法和 旧的差别不大,区别就在于在扫描结果里把原始的 byte[]的广播数据给 解析了,然后封装返回给我们, 是不是google 怕新手解析起来无从下手?(手动滑稽)

接下来 使用一组android BLE Peripheral 手机模拟设备发出BLE广播 BluetoothLeAdvertiser文章里的 广播数据,再打印一下,对比查看就明白了:

使用的广播数据:

E/TAG: scandata:02011A05FFAC0134560303E1FF05168FAE641200000000000000000000000000000000000000000000000000000000000000000000000000000000000000
使用BluetoothLeScanner 扫描结果如下:


05-24 17:38:41.731 12596-12596/jiqi.scandemo E/TAG: onScanResult :02011A05FFAC0134560303E1FF05168FAE641200000000000000000000000000000000000000000000000000000000000000000000000000000000000000
05-24 17:38:41.731 12596-12596/jiqi.scandemo E/TAG: onScanResult :ScanRecord [mAdvertiseFlags=26, mServiceUuids=[0000ffe1-0000-1000-8000-00805f9b34fb], mManufacturerSpecificData={428=[52, 86]}, mServiceData={0000ae8f-0000-1000-8000-00805f9b34fb=[100, 18]}, mTxPowerLevel=-2147483648, mDeviceName=null]
mServiceUuids里面的 0000ffe1......  这个数据对应于byte[]数组里的 E1FF,mServerData里的 0000ae8f.....=[100,18] 对应于 byte[]数组里的8FAE ,6412


好了,关于扫描结果的解析到此, 下面介绍一下 startScan(List<ScanFilter> filters, ScanSettings settings, final ScanCallback callback) 里面的过滤参数和扫描设置参数

第一个 

  List<ScanFilter> filters 可以添加多个过滤条件,如下:


可以设置mac地址,还有设备名称,serveruuid,serverdata 等等,这个比 之前的老扫描 代码

BluetoothAdapter. startLeScan(final UUID[] serviceUuids, final LeScanCallback callback) 高级,老代码只能设置一个过滤serveruuid。

当然这都是小问题,老代码在扫描到设备结果里面我们也可以手动写代码来再次过滤。


下面看一下ScanSettings ,


setCallbackType 参数有如下几项:
ScanSettings.CALLBACK_TYPE_ALL_MATCHES,CALLBACK_TYPE_FIRST_MATCH,
CALLBACK_TYPE_MATCH_LOST


setMatchMode 参数有:
ScanSettings.MATCH_MODE_AGGRESSIVE,
MATCH_MODE_STICKY
setScanMode 参数有:
ScanSettings.SCAN_MODE_OPPORTUNISTIC //这是一个特殊的扫描模式(投机取巧的),就是说程序本身不会使用BLE扫描功能,而是借助其他的扫描结果,比如程序A用了这个模式,其实程序A没有使用到蓝牙功能, 但是程序B在扫描的话,程序B的扫描结果会共享给程序A

SCAN_MODE_LOW_POWER,SCAN_MODE_BALANCED,SCAN_MODE_LOW_LATENCY 
这三个参数会越来越耗电,但扫描结果会越来越快(扫描结果间隔越来越短)


本博客所有文章如无特别注明均为原创。作者:AlanWang复制或转载请以超链接形式注明转自 AlanWang的博客-专注android和蓝牙BLE技术分享
原文地址《android BLE 扫描BLE设备 BluetoothLeScanner

相关推荐

发表评论

路人甲 表情
看不清楚?点图切换 Ctrl+Enter快速提交

网友评论(0)