[安卓] 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_FOUNDBluetoothAdapter.ACTION_DISCOVERY_FINISHED,來實現監聽藍牙設備掃描的發現和停止掃描事件。而mReceiver則是回調函數,接下來會介紹;新的暫時看不出啥頭緒,僅僅獲得bluetoothManagermBluetoothAdapter,接下來會用到。


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方法要好很多~


[1]. 本項目GITHUB鏈接地址
[2]. 在Linux下搭建安卓APP的開發燒寫環境(makefile版)—— 在Linux上用命令行+VIM開發安卓APP
[3]. android developer TextView
[4]. android developer Vector
[5]. android developer String
[6]. android developer Formatter
[7]. android developer Matcher
[8]. android developer Pattern
[9]. 等寬字體-Android 設置字體的三種方法(TypeFace)
[10]. Android 設置TextView滑動滾動條和滑動效果


@beautifulzzzz
智能硬件、物聯網,熱愛技術,關注產品
博客:http://blog.beautifulzzzz.com
園友交流群:414948975


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM