搞了一段時間的藍(lán)牙摘悴,現(xiàn)在閑了下來,總結(jié)一下具體的流程舰绘。沉淀一下
接下來的流程中會涉及到一下幾個類,現(xiàn)在提前說明一下作用
BluetoothManager 藍(lán)牙管理類葱椭,用于獲取藍(lán)牙適配器捂寿,藍(lán)牙連接狀態(tài)
BluetoothAdapter 掃描,獲取藍(lán)牙設(shè)備的類
BluetoothGatt 管理遠(yuǎn)程藍(lán)牙設(shè)備內(nèi)部的service孵运,特征值
BluetoothDevice 藍(lán)牙設(shè)備的封裝類秦陋,用于獲取address,連接等作用
BluetoothAdapter.LeScanCallback 掃描設(shè)備的回調(diào)
BluetoothGattCallback 回調(diào)治笨,藍(lán)牙設(shè)備各種數(shù)據(jù)和狀態(tài)回調(diào)
BluetoothGattService 跑在遠(yuǎn)程藍(lán)牙設(shè)備中的服務(wù)
BluetoothGattCharacteristic 特征值 用于標(biāo)識可讀驳概,赤嚼,可寫,可發(fā)通知等屬性
BluetoothGattDescriptor 藍(lán)牙協(xié)議中的Descriptor
-
:獲取設(shè)備顺又,更卒,
-
獲取BluetoothAdapter
- 兩種方式:BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
- BluetoothAdapter.getDefaultAdapter();
使用BluetoothAdapter掃描設(shè)備,這里需要傳入LeScanCallback 用于接收掃描到的設(shè)備
public boolean startLeScan(LeScanCallback callback) { return startLeScan(null, callback); }
- 在LeScanCallback中可以獲取到設(shè)備 BluetoothDevice 這個類封裝了關(guān)于遠(yuǎn)程藍(lán)牙設(shè)備的信息稚照,有mac地址蹂空,設(shè)備名字,設(shè)備別名等信息果录,最重要的適用于手機(jī)和藍(lán)牙設(shè)備建立連接
-
-
連接設(shè)備
-
在這個方法中需要最重要的是傳入BluetoothGattCallback上枕,這個回調(diào)用于接受藍(lán)牙設(shè)備的連接狀態(tài)和數(shù)據(jù),連接成功后會返回一個BluetoothGatt 獲取service Characteristic Descriptor
public BluetoothGatt connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback) { return (connectGatt(context, autoConnect,callback, TRANSPORT_AUTO)); }
做完以上的步驟后連接藍(lán)牙已經(jīng)完成了弱恒,剩下的是監(jiān)聽和讀寫數(shù)據(jù)了
-
監(jiān)聽數(shù)據(jù) 上面提到BluetoothGattCallback 這個回調(diào)辨萍,用于接受藍(lán)牙設(shè)備的連接狀態(tài)和數(shù)據(jù),挑幾個比較常用的方法來說一下
public abstract class BluetoothGattCallback {
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
//連接狀態(tài)改變返弹,系統(tǒng)會調(diào)用這個方法分瘦,基本套路是這樣子的,
調(diào)用mBluetoothGatt.discoverServices()
這個方法后就會回調(diào)onServicesDiscovered琉苇,如果不調(diào)用的話你就會痛苦的思考為什么
下面這個回調(diào)不走嘲玫。
if (newState == BluetoothProfile.STATE_CONNECTED) {
mBluetoothGatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
}
}
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
//用于發(fā)現(xiàn)service并扇,BluetoothGattCharacteristic 去团,BluetoothGattDescriptor 這三個對象是監(jiān)聽數(shù)據(jù)的關(guān)鍵,決定你能不能讀寫數(shù)據(jù)和接收通知
1.獲取硬件商提供好的服務(wù)
BluetoothGattService RxService = mBluetoothGatt.getService(RX_SERVICE_UUID);
2.在服務(wù)中獲取特征值:
BluetoothGattCharacteristic TxChar = RxService.getCharacteristic(TX_CHAR_UUID);
3.在特征值中獲取描述
BluetoothGattDescriptor descriptor = TxChar.getDescriptor(CCCD);
上面的三個對象的獲取都是靠UUID來的穷蛹,藍(lán)牙協(xié)議已經(jīng)定義好一些UUID土陪,
硬件廠商也會根據(jù)需要定義自己的UUID。
UUID相當(dāng)于一個標(biāo)示符肴熏,用于獲取對象的數(shù)據(jù)或者對象鬼雀,可以自行百度一下UUID
} else {
}
}
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
int status) {
//當(dāng)遠(yuǎn)程藍(lán)牙設(shè)備通過特征值來發(fā)送數(shù)據(jù)給手機(jī)的時候會回調(diào),這里就是真正獲取數(shù)據(jù)的地方之一蛙吏,需要注意的源哩,
characteristic傳遞的是二進(jìn)制數(shù)據(jù),需要進(jìn)行轉(zhuǎn)換的鸦做。還有個很坑的地方励烦,這里我覺得并非運(yùn)行在主線程的,大家可以驗證一下
}
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
// 寫數(shù)據(jù)的回調(diào)
}
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
//當(dāng)遠(yuǎn)程藍(lán)牙設(shè)備通過特征值來發(fā)送數(shù)據(jù)給手機(jī)的時候會回調(diào)泼诱,這里就是真正獲取數(shù)據(jù)的地方之一坛掠,
}
- 總結(jié):因為目前公司的手環(huán)只用到了讀取數(shù)據(jù)的部分,寫數(shù)據(jù)部分還沒用到。等用到了再補(bǔ)一下屉栓,而且目前也是淺顯用了一下藍(lán)牙舷蒲,希望接下來有更多的機(jī)會可以用到藍(lán)牙,增加經(jīng)驗友多。