標籤:android l android l ble android5.0 ble central android5.0 ble
轉載請表明http://blog.csdn.net/lansefeiyang08/article/details/46482073
昨天寫了android L BLE Peripheral的簡單使用,今天講一下BLE Central的更新。
搞過android4.4的人肯定對BluetoothAdapter的startLeScan函數不會陌生,但是在android L已經棄用此介面,但是為了相容以前的版本,這個介面還是可以使用的。但是Google已經單獨拿出來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的代碼:
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
這句代碼和Peripheral的getBluetoothLeAdvertiser基本類似,一般手機支援BLE都會支援Central,除非是本身就只是外設裝置。這個不難,我就不浪費時間了。
2、這裡就直接進入scan動作了,新的介面把scan分為了兩類,一種為:
/** * Start Bluetooth LE scan with default parameters and no filters. The scan results will be * delivered through {@code callback}. * <p> * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. * * @param callback Callback used to deliver scan results. * @throws IllegalArgumentException If {@code callback} is null. */ public void startScan(final ScanCallback callback) { if (callback == null) { throw new IllegalArgumentException("callback is null"); } startScan(null, new ScanSettings.Builder().build(), callback); }從函數你肯定就懂,這個是直接搜尋全部周圍peripheral裝置,當然這裡你要填寫callback,具體的我下面會講。
第二種為:
/** * Start Bluetooth LE scan. The scan results will be delivered through {@code callback}. * <p> * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. * * @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. */ public void startScan(List<ScanFilter> filters, ScanSettings settings, final ScanCallback callback) { startScan(filters, settings, callback, null); }這一種明顯屬於定製化的函數了,因為他需要我們輸入過濾條件。這裡的ScanFilter和ScanSettings又是兩個scan類,當然這兩個類的目的主要是為了有些人想單獨為某個產品開發應用,把過濾條件加上,比如DeviceName或者某個Service UUID等等,就可以搜尋出只針對特定Peripheral特性的裝置。
拿著兩個條件我們怎麼用呢,我給大家寫一點,大家可以參考我寫的自己添加:
// add a filter to only scan for advertisers with the given service UUID List<ScanFilter> bleScanFilters = new ArrayList<>(); bleScanFilters.add( new ScanFilter.Builder().setServiceUuid(SAMPLE_UUID).build() ); ScanSettings bleScanSettings = mBleScanSettingsBuilder.build(); Log.d(TAG, "Starting scanning with settings:" + bleScanSettings + " and filters:" + bleScanFilters); // tell the BLE controller to initiate scan mBluetoothLeScanner.startScan(bleScanFilters, bleScanSettings, mBleScanCallback);
單獨看這兩個新的介面,可能有些人會迷惑,本來不久應該是這樣嗎?其實Andoid L之前,scan介面不是這樣的,它只有一下兩種
@Deprecated public boolean startLeScan(LeScanCallback callback)
@Deprecated public boolean startLeScan(final UUID[] serviceUuids, final LeScanCallback callback)
你會發現,原來的scan只能通過service UUID去搜尋,其他條件都不行,所以新版本的介面為我們定製應用提供了很大的便利。
3、搜尋完了,那就要拿到scan的callback了。在這裡,我就拿第一種格式來講。
ScanCallBack有三個回調,當然callback也單獨是一個類,這裡我只講講對我們有用的 onScanResult(int callbackType, ScanResult result),為了大家理解,我直接給大家看看我搜尋出來的結果:
<span style="font-size:14px;">callbackType:1ScanResult{mDevice=B4:52:7E:9A:41:A8,mScanRecord=ScanRecord [mAdvertiseFlags=6,mServiceUuids=[00001804-0000-1000-8000-00805f9b34fb,00001802-0000-1000-8000-00805f9b34fb,00001803-0000-1000-8000-00805f9b34fb,00000200-37cb-11e3-8682-0002a5d5c51b],mManufacturerSpecificData={}, mServiceData={},mTxPowerLevel=0, mDeviceName=××××],mRssi=-43, mTimestampNanos=352640634804615}</span>從這個結果可以看出來,現在scan返回的結果明顯增加了,其實從結果大家應該也能理解,第二種設定過濾的話會有哪些參數可以讓你去設定。
你看到這些結果你肯定暈了,這要怎麼拿出來,這就用到了Scan相關類的最後兩個類ScanResult和ScanRecord。這兩個類主要是用來解析你scan後資料的,我這裡也貼一點代碼,大家如果是需要其他結果,可以參考一下:
BluetoothDevice device = result.getDevice(); Log.d(TAG, "Device name: " + device.getName()); Log.d(TAG, "Device address: " + device.getAddress()); Log.d(TAG, "Device service UUIDs: " + device.getUuids()); ScanRecord record = result.getScanRecord(); Log.d(TAG, "Record advertise flags: 0x" + Integer.toHexString(record.getAdvertiseFlags())); Log.d(TAG, "Record Tx power level: " + record.getTxPowerLevel()); Log.d(TAG, "Record device name: " + record.getDeviceName()); Log.d(TAG, "Record service UUIDs: " + record.getServiceUuids()); Log.d(TAG, "Record service data: " + record.getServiceData());
這裡的result就是onScanResult(int callbackType, ScanResult result)的返回值。
4、最後一步就是stop,這個大家應該很熟了,用一個postdelay如下:
// post a future task to stop scanning after (default:25s) mHandler.postDelayed(new Runnable() { @Override public void run() { stopScanning(); } }, DEFAULT_SCAN_PERIOD);或者直接調用stop,這裡的stopScanning實現如下:
private void stopScanning() { if (mBluetoothLeScanner != null) { Log.d(TAG, "Stop scanning."); mBluetoothLeScanner.stopScan(mBleScanCallback); } }
剩下的就是connectGatt了。這個和以前還是一樣的,目前沒有變化。
ok,對於google新添加的android.bluetooth.le這個package算是解析完了,接下來幾天就要看看android L系統裡是怎麼實現的了。
android L BLE Central(Scanner)牛刀小試