• android5.0(Lollipop) BLE Central牛刀小试


    转载请表明作者:http://blog.csdn.net/lansefeiyang08/article/details/46482073

    昨天写了android L BLE Peripheral的简单使用,今天讲一下BLE Central的更新。

    搞过android4.4的人肯定对BluetoothAdapter的startLeScan函数不会陌生,但是在android L已经弃用此接口,但是为了兼容以前的版本,这个接口还是可以使用的。但是谷歌已经单独拿出来android.bluetooth.le类來处理BLE的操作,所以我建议还是用最新的接口开发。如果想要兼容L之前的版本,可以用 android.os.Build.VERSION.SDK_INT或者 android.os.Build.VERSION.RELEA加一个版本判断就可以。下面就來正式认识一下BLE Scanner的更新。

    在android L Central一共添加了6个scan的相关类(4个advertise相关类),这6个类把scan相关部分分得很细。按照上一篇Peripheral的思路,我们还是按照启动scan流程來学习这个类。

    1、关于判断是否支持蓝牙、支持BLE的代码我就不写了,下面我只贴一下支持BLE centrial的代码:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();  

    这句代码和Peripheral的getBluetoothLeAdvertiser基本类似,一般手机支持BLE都会支持Central,除非是本身就只是外设设备。这个不难,我就不浪费时间了。

    2、这里就直接进入scan动作了,新的接口把scan分为了两类,一种为:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. /** 
    2.  * Start Bluetooth LE scan with default parameters and no filters. The scan results will be 
    3.  * delivered through {@code callback}. 
    4.  * <p> 
    5.  * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. 
    6.  * 
    7.  * @param callback Callback used to deliver scan results. 
    8.  * @throws IllegalArgumentException If {@code callback} is null. 
    9.  */  
    10. public void startScan(final ScanCallback callback) {  
    11.     if (callback == null) {  
    12.         throw new IllegalArgumentException("callback is null");  
    13.     }  
    14.     startScan(null, new ScanSettings.Builder().build(), callback);  
    15. }  

    从函数你肯定就懂,这个是直接搜索全部周围peripheral设备,当然这里你要填写callback,具体的我下面会讲。

    第二种为:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. /** 
    2.  * Start Bluetooth LE scan. The scan results will be delivered through {@code callback}. 
    3.  * <p> 
    4.  * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. 
    5.  * 
    6.  * @param filters {@link ScanFilter}s for finding exact BLE devices. 
    7.  * @param settings Settings for the scan. 
    8.  * @param callback Callback used to deliver scan results. 
    9.  * @throws IllegalArgumentException If {@code settings} or {@code callback} is null. 
    10.  */  
    11. public void startScan(List<ScanFilter> filters, ScanSettings settings,  
    12.         final ScanCallback callback) {  
    13.     startScan(filters, settings, callback, null);  
    14. }  

    这一种明显属于定制化的函数了,因为他需要我们输入过滤条件。这里的ScanFilter和ScanSettings又是两个scan类,当然这两个类的目的主要是为了有些人想单独为某个产品开发应用,把过滤条件加上,比如DeviceName或者某个Service UUID等等,就可以搜索出只针对特定Peripheral特性的设备。

    拿着两个条件我们怎么用呢,我给大家写一点,大家可以参考我写的自己添加:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. // add a filter to only scan for advertisers with the given service UUID  
    2.         List<ScanFilter> bleScanFilters = new ArrayList<>();  
    3.         bleScanFilters.add(  
    4.                 new ScanFilter.Builder().setServiceUuid(SAMPLE_UUID).build()  
    5.         );  
    6.   
    7.         ScanSettings bleScanSettings = mBleScanSettingsBuilder.build();  
    8.   
    9.         Log.d(TAG, "Starting scanning with settings:" + bleScanSettings + " and filters:" + bleScanFilters);  
    10.   
    11.         // tell the BLE controller to initiate scan  
    12.         mBluetoothLeScanner.startScan(bleScanFilters, bleScanSettings, mBleScanCallback);  

    单独看这两个新的接口,可能有些人会迷惑,本来不久应该是这样吗?其实Andoid L之前,scan接口不是这样的,它只有一下两种

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. @Deprecated  
    2. public boolean startLeScan(LeScanCallback callback)   
    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. @Deprecated  
    2.     public boolean startLeScan(final UUID[] serviceUuids, final LeScanCallback callback)   

    你会发现,原来的scan只能通过service UUID去搜索,其他条件都不行,所以新版本的接口为我们定制应用提供了很大的便利。

    3、搜索完了,那就要拿到scan的callback了。在这里,我就拿第一种格式来讲。
    ScanCallBack有三个回调,当然callback也单独是一个类,这里我只讲讲对我们有用的 onScanResult(int callbackType, ScanResult result),为了大家理解,我直接给大家看看我搜索出来的结果:

    [plain] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. <span style="font-size:14px;">callbackType:1  
    2. ScanResult{mDevice=B4:52:7E:9A:41:A8,mScanRecord=ScanRecord [mAdvertiseFlags=6,mServiceUuids=[00001804-0000-1000-8000-00805f9b34fb,  
    3. 00001802-0000-1000-8000-00805f9b34fb,00001803-0000-1000-8000-00805f9b34fb,00000200-37cb-11e3-8682-0002a5d5c51b],  
    4. mManufacturerSpecificData={}, mServiceData={},mTxPowerLevel=0, mDeviceName=××××],mRssi=-43, mTimestampNanos=352640634804615}</span>  

    从这个结果可以看出来,现在scan返回的结果明显增加了,其实从结果大家应该也能理解,第二种设置过滤的话会有哪些参数可以让你去设置。

    你看到这些结果你肯定晕了,这要怎么拿出来,这就用到了Scan相关类的最后两个类ScanResult和ScanRecord。这两个类主要是用来解析你scan后数据的,我这里也贴一点代码,大家如果是需要其他结果,可以参考一下:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. BluetoothDevice device = result.getDevice();  
    2. Log.d(TAG, "Device name: " + device.getName());  
    3. Log.d(TAG, "Device address: " + device.getAddress());  
    4. Log.d(TAG, "Device service UUIDs: " + device.getUuids());  
    5.   
    6. ScanRecord record = result.getScanRecord();  
    7. Log.d(TAG, "Record advertise flags: 0x" + Integer.toHexString(record.getAdvertiseFlags()));  
    8. Log.d(TAG, "Record Tx power level: " + record.getTxPowerLevel());  
    9. Log.d(TAG, "Record device name: " + record.getDeviceName());  
    10. Log.d(TAG, "Record service UUIDs: " + record.getServiceUuids());  
    11. Log.d(TAG, "Record service data: " + record.getServiceData());  

    这里的result就是onScanResult(int callbackType, ScanResult result)的返回值。

    4、最后一步就是stop,这个大家应该很熟了,用一个postdelay如下:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. // post a future task to stop scanning after (default:25s)  
    2. mHandler.postDelayed(new Runnable() {  
    3.     @Override  
    4.     public void run() {  
    5.         stopScanning();  
    6.     }  
    7. }, DEFAULT_SCAN_PERIOD);  

    或者直接调用stop,这里的stopScanning实现如下:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. private void stopScanning() {  
    2.     if (mBluetoothLeScanner != null) {  
    3.         Log.d(TAG, "Stop scanning.");  
    4.         mBluetoothLeScanner.stopScan(mBleScanCallback);  
    5.     }  
    6. }  


    剩下的就是connectGatt了。这个和以前还是一样的,目前没有变化。

    ok,对于google新添加的android.bluetooth.le这个package算是解析完了,接下来几天就要看看android L系统里是怎么实现的了。

  • 相关阅读:
    如何使DIV居中
    #ifdef DEBUG的理解
    iOS程序启动画面的制作
    ios4支持高分辨率的一些总结(转)
    将旧的推送通知从通知中心移除掉的三种方法
    Mac锁屏设置快捷键
    湖北黑客因盗窃域名被刑事拘留 涉嫌诈骗犯罪
    php连接Access数据库错误及解决方法
    Cannot send session cache limiter – headers already sent
    php代码注意事项
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4848426.html
Copyright © 2020-2023  润新知