20、基於藍芽BLE的廣播包高頻快速搜尋
前言:
之前介紹過很多藍芽beacon、搜尋、連線、通訊的文章。不過最近我發現:之前寫的藍芽廣播包搜尋的工程,搜尋頻率太慢,而且不能一直保持搜尋狀態。因此,這裡探討下高頻藍芽廣播包掃描 —— 藍芽BLE掃描。
注:本文將從對比之前慢的和現在快的兩個工程進行展開
1、初始化-onCreate
新的:
// Get the local Bluetooth adapter // Initializes Bluetooth adapter. final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = bluetoothManager.getAdapter(); // Ensures Bluetooth is available on the device and it is enabled. If not, // displays a dialog requesting user permission to enable Bluetooth. if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); }
老的:
// Register for broadcasts when a device is discovered IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); this.registerReceiver(mReceiver, filter); // Register for broadcasts when discovery has finished filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); this.registerReceiver(mReceiver, filter); // Get the local Bluetooth adapter mBtAdapter = BluetoothAdapter.getDefaultAdapter();
可見:老的是通過註冊廣播過濾條件BluetoothDevice.ACTION_FOUND
和BluetoothAdapter.ACTION_DISCOVERY_FINISHED
,來實現監聽藍芽裝置掃描的發現和停止掃描事件。而mReceiver則是回撥函式,接下來會介紹;新的暫時看不出啥頭緒,僅僅獲得bluetoothManager
和mBluetoothAdapter
,接下來會用到。
2、開始掃描-doDiscovery
新的:
// Start device discover with the BluetoothAdapter private void doDiscovery() { // If we're already discovering, stop it if (mBluetoothAdapter.isDiscovering()) { mBluetoothAdapter.stopLeScan(mLeScanCallback); } // Request discover from BluetoothAdapter //use filter not work!!!!!!!!!! //UUID[] uuid_arrays = new UUID[1]; //uuid_arrays[0] = ParcelUuid.fromString(UUID_SERVICE).getUuid(); //mBluetoothAdapter.startLeScan(uuid_arrays,mLeScanCallback); //Log.d("RSSI",uuid_arrays[0].toString() + "" + UUID.randomUUID().toString()); mBluetoothAdapter.startLeScan(mLeScanCallback); }
老的:
// Start device discover with the BluetoothAdapter private void doDiscovery() { // If we're already discovering, stop it if (mBtAdapter.isDiscovering()) { mBtAdapter.cancelDiscovery(); } // Request discover from BluetoothAdapter mBtAdapter.startDiscovery(); }
可見:區別在於一個是BLE操作、一個是普通藍芽操作。
3、監聽
新的:
// Device scan callback. private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { runOnUiThread(new Runnable() { @Override public void run() { if(device_filter(device)){ //mDevicesNameVector.add(device.getName()); //mDevicesAddrVector.add(device.getAddress()); //mRSSIVector.add((short)rssi); Log.d("RSSI",device.getAddress() + " " + device.getName() + " " + String.valueOf(rssi)); ... } } }); } };
老的:
// The BroadcastReceiver that listens for discovered devices and // changes the title when discovery is finished //【查詢藍芽裝置】 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.d("onReceive","OK"); String action = intent.getAction(); // When discovery finds a device if (BluetoothDevice.ACTION_FOUND.equals(action)) { // Get the BluetoothDevice object from the Intent BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); mDevicesNameVector.add(device.getName()); mDevicesAddrVector.add(device.getAddress()); short rssi = intent.getExtras().getShort(BluetoothDevice.EXTRA_RSSI); mRSSIVector.add(rssi); Log.d("RSSI",device.getName()+""+String.valueOf(rssi)); // When discovery is finished, change the Activity title } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { setProgressBarIndeterminateVisibility(false); if (mDevicesNameVector.size() != 0) { Message msg = new Message();//訊息 Bundle bundle = new Bundle(); bundle.clear();Log.d("onReceive","1"); msg.what = 0x01;//訊息類別 bundle.putShort("msg",(short) 0);Log.d("onReceive","2"); msg.setData(bundle);Log.d("onReceive","3"); myHandler.sendMessage(msg);Log.d("onReceive","4"); } } } };
可見:新的相對比較簡單、可以持續不斷的掃描獲取(同一個裝置會被不斷的掃描到);老的則分為兩步:第一步是每次掃描到一次新裝置都會有一個FOUND事件、最後停止掃描了還有個FINISH事件,這裡我在FINISH事件結束時發出一個msg來通知進行其他操作。
4、許可權檔案配置
新的:
<uses-permission a:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission a:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission a:name="android.permission.BLUETOOTH"/> <uses-permission a:name="android.permission.BLUETOOTH_ADMIN"/> <uses-feature a:name="android.hardware.bluetooth_le" a:required="true"/>
老的:
<uses-permission a:name="android.permission.BLUETOOTH" /> <uses-permission a:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission a:name="android.permission.ACCESS_COARSE_LOCATION" />
可見:相差不大,新的比老的多了bluetooth_le說明。
5、最後說明
當你嘗試使用BLE SCAN之後,你會感覺有一種飛一般的感覺,幾乎同一個裝置每一秒都會被掃描到多次。拿這些高頻掃描的大量資料,就可以做類似beacon、距離估算、定位等小應用了!效果會比老的scan方法要好很多~
LINKS
ofollow,noindex" target="_blank">[1]. 本專案GITHUB連結地址
[2]. 在Linux下搭建安卓APP的開發燒寫環境(makefile版)—— 在Linux上用命令列+VIM開發安卓APP
[3]. android developer TextView
[6]. android developer Formatter
[7]. android developer Matcher
[8]. android developer Pattern
[9]. 等寬字型-Android 設定字型的三種方法(TypeFace)
[10]. Android 設定TextView滑動滾動條和滑動效果@beautifulzzzz 智慧硬體、物聯網,熱愛技術,關注產品 部落格:http://blog.beautifulzzzz.com 園友交流群:414948975