一、Ble藍牙操作流程

二、權(quán)限聲明
1.在Android 6.0(targetSdkVersion小于23)之前在權(quán)限的獲取和操作只需在AndroidManifest文件中聲明這兩個權(quán)限就可以。

2.在Android 6.0(targetSdkVersion等于或大于23)之后,操作藍牙需要申請GPS定位權(quán)限,而且在權(quán)限的獲取和操作上有所改動,分為Normal Permissions和Dangerous Permission。凡是Dangerous Permission都需要動態(tài)獲取權(quán)限。

三、獲取藍牙權(quán)限
1.對于6.0以上系統(tǒng)需要判斷版本調(diào)用

2.系統(tǒng)會回調(diào)onRequestPermissionsResult的方法,返回請求權(quán)限的結(jié)果。
onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
四、搜索設備
1.BLE設備的搜索調(diào)用BluetoothAdapter的startLeScan方法,如下圖所示。


2.調(diào)用掃描方法之后,Android系統(tǒng)會通過LeScanCallback返回掃描的結(jié)果。在 onLeScan() 方法中盡量少做耗時的操作,可以把掃描到的設備,扔到另外一個線程中去處理。

3.搜索設備是耗電的,所以搜索設備需要有時間限制,在搜索到或者超過預定時間之后需要調(diào)用stopLeScan(LeSacnCallback callback)方法停止搜索。
五、連接設備
1.通過掃描獲取到的BluetoothDevice對象調(diào)用connectGatt方法進行連接設備,如果已知BlE設備mac,可以通過BluetoothAdapter的getRemoteDevice(String address)方法獲取BluetoothDevice。

2. 連接狀態(tài)是由mGattCallBack的回調(diào)方法onConnectionStateChange(BluetoothGatt gatt, int status, int newState)中返回的。?參數(shù)解析:
status:返回Gatt的狀態(tài)(BluetoothGatt.GATT_SUCCESS:成功)
newState:藍牙連接狀態(tài)(BluetoothProfile.STATE_CONNECTED 設備已連接, BluetoothProfile.STATE_ DISCONNECTED設備已斷開連接 )
3.藍牙只能同時連接一個外圍設備,如果同時發(fā)起多個連接,前面連接失敗會后面設備連接阻塞。如果需要連接多個設備,建議隊列形式連接,如果連接失敗,調(diào)用disconnect()方法釋放連接。
六、發(fā)現(xiàn)并獲取BluetoothGattService
當設備連接成功之后,調(diào)用BluetoothGatt的discoverServices()獲取service。執(zhí)行完成之后將會回調(diào)BluetoothGattCallback的方法onServicesDiscovered(BluetoothGatt gatt, int status)。

Android BLE藍牙通信是通過BluetoothGatt 中的service和Characteristic進行通信的。
通過對外設的連結(jié)獲取BluetoothGatt ,一個外設只能同時被一個中心設備連結(jié),連結(jié)之后外設的藍牙廣播就會中斷,其他中心設備將無法連結(jié)。
1.BluetoothGatt類包含多個service。
2.每個service中包含多個Characteristic。
3.一個Characteristic中包含一個value和多個Descriptor。
七、注冊Notification
當BLE設備主動發(fā)送數(shù)據(jù)的時候,需要注冊Notification來接收數(shù)據(jù),注冊Notification之后,設備發(fā)送數(shù)據(jù)會回調(diào)BluetoothGattCallback的onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)方法。如何注冊如下操作:

八、BLE寫操作
寫數(shù)據(jù)操作,需要調(diào)用BluetoothGatt的writeCharacteristic(BluetoothGattCharacteristic characteristic)的方法,需要寫的數(shù)據(jù)通過BluetoothGattCharacteristic的setValue(byte[] value)方法進行設置。

當對藍牙操作完成之后 要及時關(guān)閉連接。關(guān)閉藍牙連接調(diào)用 BluetoothGatt的disconnect()方法,調(diào)用BluetoothGatt的close()方法來釋放連接對象;
BluetoothGatt的操作,如writeCharacteristic、readCharacteristic、writeDescriptor、readDescriptor和readRemoteRssi()都是異步操作。如果同時執(zhí)行多個writeCharacteristic操作,在第一個操作沒有返回的情況下(回調(diào) onCharacteristicWrite()之后),以下的寫操作是無效的。
解決辦法推薦:將所有的寫或者讀操作寫到一個隊列里,封裝成一個同步的操作,在操作沒有返回之前,讓下一個操作等待。