1.前言
藍牙在我們生活中扮演者許多重要的角色,藍牙耳機套利、藍牙音箱推励、藍牙燈泡、藍牙智能硬件等等肉迫!可見验辞,藍牙無處不在,而且也是物聯(lián)網(wǎng)的基礎(chǔ)紐帶喊衫,它改變了我們的許多生活方式跌造,給我們帶來了許多益處。
前段時間我也簡單地使用了小程序的藍牙api操作族购,接下來我也要開始重新認識下Android藍牙開發(fā)壳贪,藍牙又分為經(jīng)典藍牙和BLE(低功耗藍牙)财著,這次我主要學(xué)習(xí)藍牙BLE,所以我第一時間找了谷歌給我們提供了官方源碼demo:
https://github.com/googlesamples/android-BluetoothLeGatt
2.權(quán)限
配置文件需要先聲明藍牙權(quán)限:
<!--藍牙必須的權(quán)限-->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
除了藍牙權(quán)限外撑碴,還有如下權(quán)限是聲明程序是否可用于支持BLE或者支持出BLE外的設(shè)備;如果required=true朝墩,則應(yīng)用只能在支持BLE的Android設(shè)備上安裝運行醉拓,不支持BLE的設(shè)備將finish。
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
此外還有一個很關(guān)鍵的問題收苏,不知道你們在開發(fā)中有沒有遇到過呢亿卤?官方demo沒有適配到這里。Android6.0以上的手機僅僅是添加如上藍牙權(quán)限是不行的鹿霸,這將會造成無法掃描到其他設(shè)備排吴,針對這問題,果斷查了資料懦鼠,需要添加位置權(quán)限钻哩;
<!--android6.0以上使用藍牙需要的權(quán)限,否則在Android6.0以上的手機掃描不到藍牙設(shè)備-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
在Android6.0以上 位置相關(guān)的權(quán)限屬于運行時權(quán)限肛冶,所以代碼同時也要請求一下 讓用戶確認街氢,這個就不多說了。
3.是否支持藍牙BLE
在前面的權(quán)限也說了如果required=true睦袖,則應(yīng)用只能在支持BLE的Android設(shè)備上安裝運行珊肃,不支持BLE的設(shè)備將finish;
如果想在java代碼上實現(xiàn)上面的邏輯也是可以的馅笙,官方demo如下:
/**使用此檢查確定設(shè)備是否支持BLE伦乔。 然后你可以有選擇地禁用與BLE相關(guān)的功能。*/
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
4.初始化藍牙適配器
初始化藍牙適配器董习。 對于API級別18及更高級別烈和,請通過BluetoothManager獲取對BluetoothAdapter的引用。最后這里記得要判空皿淋!
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
// Checks if Bluetooth is supported on the device.
if (mBluetoothAdapter == null) {
Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
finish();
return;
}
5.當前設(shè)備是否已開啟藍牙
要想操作藍牙斥杜,必須確保在設(shè)備上啟用藍牙。如果當前未啟用藍牙沥匈,因此我們可以觸發(fā)Intent調(diào)用系統(tǒng)顯示一個對話框蔗喂,要求用戶授予啟用藍牙的權(quán)限。
if (!mBluetoothAdapter.isEnabled()) {
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
6.初始化listview列表適配器
這里目的就是將掃描到的藍牙設(shè)備顯示到listview列表上高帖,然后用戶就可以點擊對應(yīng)的item缰儿,程序就可以進行下一步操作。這一步驟可根據(jù)需要定制散址。
7.掃描
官方demo的掃描方法如下乖阵,如果要掃描的話就要傳入true執(zhí)行scanLeDvice(true)方法宣赔,然后藍牙適配器就調(diào)用startLeScan()方法進行掃描,mLeScanCallback是掃描回調(diào)瞪浸,下面會說到儒将;執(zhí)行掃描的同時開啟了一個延時操作,時間到了就調(diào)用stopLeScan()方法停止掃描对蒲。
我覺得這里設(shè)置了一個延時停止掃描操作是非常友好的钩蚊,因為掃描非常耗資源。
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
invalidateOptionsMenu();
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
invalidateOptionsMenu();
}
接下來就看看掃描的Callback回調(diào)吧蹈矮,這個回調(diào)里面有個onLeScan方法砰逻,藍牙掃描成功后的結(jié)果會返回此方法中,然后就可以處理BluetoothDevice拿到設(shè)備信息 最后展示到前面初始化的listview列表中泛鸟,大概流程就是這樣蝠咆。
// 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() {
mLeDeviceListAdapter.addDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged();
}
});
}
};
接著再看看這個onLeScan方法中的值吧!
第一個參數(shù)device北滥,表示一個遠程藍牙設(shè)備刚操,里面有它獨有的藍牙地址Address和Name等,所以后續(xù)需要進行連接藍牙操作也需要用到這里獲取的藍牙Address再芋;
第二個參數(shù)rssi表示掃描到的設(shè)備信號強度赡茸,這里應(yīng)該可以用來判斷距離的遠近。
第三個參數(shù)scanRecord表示遠程設(shè)備提供的廣告記錄的內(nèi)容祝闻。
至此已經(jīng)完成初始化配置占卧、一些設(shè)備的判斷邏輯和掃描操作了,如果能成功地掃描到設(shè)備并展示到界面上的話联喘,下一步如果用戶點擊了列表华蜒,將進行藍牙連接和相關(guān)的讀寫操作!
所以下一篇文章不出意外的話豁遭,就是繼續(xù)學(xué)習(xí)Android藍牙的連接和讀寫操作叭喜。
Android 藍牙BLE開發(fā)從官方源碼demo開始(二)