本文章是參考官網,而後加入本身實踐中的理解完成!沒有看上一篇的讀者,能夠先閱讀一下前一篇,這是一個系列。
官網地址:https://developer.android.com/guide/topics/connectivity/bluetooth-le
java
Android 4.3 (API 18 )引入了低功耗藍牙,應用能夠查詢周圍設備、查詢設備的服務、傳輸信息。android
通用屬性配置文件(GATT Generic Attribute Profile)git
GATT 配置文件是一種傳輸數據規範,用於在 BLE 鏈路上發送和接受被稱爲屬性的短數據的通用規範。目前全部低功耗應用配置文件基本都是基於 GATTgithub
Bluetooth SIG (藍牙技術聯盟)服務器
是爲低功耗設備定義了許多配置文件。配置文件是設備在特定應用程序中的工做方式的規範。設備能夠實現多個配置文件。例如,設備能夠包含心率監測器和電池水平檢測器。併發
定義規範的框架
屬性協議(ATT Attribute Protocol)ide
GATT 是創建在屬性協議(ATT)之上的。也被稱爲 GATT/ATT 。ATT 通過優化,可在 BLE 設備上使用。爲此,它使用了儘量少的字節。每一個屬性由通用惟一標識符(UUID)來惟一標識。ATT 傳輸的屬性被格式化爲 特徵 和 服務優化
特徵ui
特徵包含單個值和描述特徵值的 0 ~ n 個描述符。特徵值能夠被稱爲類型。相似於類。(是在和 BLE 設備進行通訊的時候主要的操做內容)
描述符
是用來定義特徵值的已定義屬性。用來描述特徵值的。例如:描述符能夠指定人類可讀的描述,特徵值的可接受範圍或者特徵值特定的度量單位
服務
服務中包含一系列的特徵值。例如,咱們能夠使用名爲 「心率監測器」的服務,其中包括"心率測量"等特徵。能夠在 bluetooh.org 上找到基於 GATT 的現有配置文件的服務的列表。
Android 設備和 BLE 設備交互時應用的角色和職責
應用在使用藍牙設備的時候必需要聲明藍牙權限 BLUETOOTH
須要這個權限才能夠進行藍牙通訊,例如:請求鏈接、接受鏈接、和傳輸數據。
若是還須要發現或者操做藍牙設置,則須要聲明 BLUETOOTH_ADMIN
權限。使用這個權限的前提是要有 BLUETOOTH
權限。
若是要聲明咱們的應用僅適用於支持 BLE 的設備,須要清單文件中作以下聲明
<uses-feature android:name = "android.hardware.bluetooth_le" android:required = true />
若是咱們但願咱們的應用程序在不支持 BLE 的設備上也能夠運行的時候,只須要將 true 修改爲 false 就能夠了。
還能夠在代碼中做出判斷
if(!getPackageManager().hasSystemFeature(PackgeManger.FEATURE_BLUETOOTH_LE)){ // 不支持 BLE 設備 }
BLE 一般和位置有關係,所以還須要聲明位置權限 ACCESS_COARSE_LOCATION
或者 ACCESS_FINE_LOCATION
沒有這些權限掃描將不會返回任何結果。
得到 BluetoothAdapter
BluetoothAdapter 表明設備本身的藍牙適配器,整個系統只有一個藍牙適配器,咱們的應用程序能夠使用此對象與其交互。
這裏的獲取方法是經過 BluetoothManager 來獲取的
BluetoothManager bluetoothManger = getSystemSerive(Context.BULETOOTH_SERVIcE); BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
啓用藍牙設備
其實這些和普通藍牙的啓動都是同樣的。
isEnable()
查看當前是否啓用了藍牙
經過 BluetoothAdapter.ACTION_REQUEST_ENABLE 來啓動
查找 BLE 設備
這一點和發現普通的藍牙設備是不同的
// 經過 Adapter 的 startLeScan(callBack); 方法來開啓掃描 // 若是咱們有指定的藍牙設備能夠使用 sartLeScan(UUID[],BluetoothAdapter.LeScanCallBakc) 經過 UUID 來指定 BLe // 這個方法已通過時了,官方文檔最新支持的掃描藍牙的方法是經過一個專門的對象 BluetoothLeScanner 用來開啓掃描低功耗藍牙 BluetoothLeScanner scanner = bluetoothAdapter.getBluetoothLeScanner(); // 這個方法能夠有參數,用來過濾要掃描的低功耗藍牙的,具體的後面講 scanner.startScan();
只能單獨掃描普通藍牙設備或者 BLE 設備,沒有方法同時執行
與 BLE 設備通訊,第一步就是要鏈接到它,就是鏈接到該設備的 GATT 服務。使用方法 connectGatt()
有三個參數:Context 對象 autoConnect (表示是否在可用的時候本身鏈接到 BLE 設備) 還有一個回調,全部的交互都在這個回調裏面完成。
調用這個方法會返回一個 BluetoothGatt
對象,經過這個對象進行和 BLE 設備的交互。交互的結果會在回調方法中觸發。
public class BluetoothLeService extends Service{ private final static String TAG = BluetoothLeService.class.getSimpleName(); private BluetoothManger bluetoothManger; private BluetoothAdapter bluetoothAdapter; private String bluetoothDeviceAddress; private BluetoothGatt bluetoothGatt; private int connectionState = STATE_DISCONNECTED; private static final int STATE_DISCONNECTED = 0; private static final int STATE_CONNETING = 1; private static final int STATE_CONNECTED = 2; public final static String ACTION_GATT_CONNECTED = "com.example.bluetooth.le.ACTION_GATT_CONNECTED"; public final static String ACTION_GATT_DISCONNECTED = "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED"; public final static String ACTION_GATT_SERVICES_DISCOVERED = "com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED"; public final satic String ACTION_DATA_AVAILABLE = "com.example.bluetooth.le.ACTION_DATA_AVAILABLE"; public final static String EXTRA_DATA = "com.example.bluetooth.le.EXTRA_DATA"; public final static UUID UUID_HEART_RATE_MEASUREMENT = UUID.formString(SampleGattAttributes.HEART_RATE_MEASURMENT); private final BluetoothGattCallback gattCallback = new BluetoothGattCallback(){ // 你的中央設備鏈接上 ble 設備後,會回調這個這方法。 @Override public viod onConnectionStateChange(BluetoothGatt gatt,int status,int newState){ String intenAction; if(newState == BluetoothProfile.STATE_CONNECTED){ intentaction = ACTION_GATT_CONNECTED; connectionState = STATE_CONNECTED; broadcastUpdate(intentAction); // 鏈接上後,緊接着就是要尋找裏面 Service bluetoothGatt.discoverServices(); }else if(newState = BluetoothProfile.STATE_STATE_DISCONNECTED{ intentAction = ACTION_GATT_DISCONNECTED; connectionState = STATE_DISCONNECTED; broadcastUpdate(intentAction); } } @Override // service 發現後就會觸發這個方法,而後你就須要找到你和 ble 約定好的 service public void onServicesDiscovered(BluetoothGatt gatt,int status){ if(status == BluetoothGatt.GATT_SUCCESS){ broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); } } public void onCharacteristicREad(。。。){ } ....... } }
當觸發特定的回調的時候,會調用適當的 broadcastUpdate() 輔助方法並向其傳遞操做。具體的數據解析格式是根據配置文件規範執行的(是你和你的BLE 設備共同約定好的規範)
大致的過程當中:開啓鏈接,而後會觸發對應的鏈接回調,而後發現服務,觸發發現服務回調,獲取服務內部的特徵值,對其讀寫命令(和 BLE 共同約束的規範)。就是這麼一個過程,很簡單。
讀 BLE 屬性
一旦咱們的 Android 設備鏈接到了 GATT 服務器並發現了服務,咱們就能夠在支持的位置讀取或者寫入屬性了。
完成後要記得關閉設備 bluetoothGatt.close();
關於藍牙框架的一個庫:https://github.com/Alex-Jerry/Android-BLE