Android 從開發角度來看經典藍牙和低功耗(BLE)藍牙的區別

1. 開發分類

直接看圖。
在這裏插入圖片描述
從圖中可以看到,對於數據量較大的傳輸,如音視頻等開發,需要使用經典藍牙模式。而對於現在興起的 AIOT 物聯網、智能家居等領域,則會選擇低功耗藍牙 BLE,因爲成本和功耗更低,並對實時性要求更高。

從現如今手機的實際體驗來看,手機上的藍牙應該是雙模藍牙,以小米手機爲例,它可以連接藍牙耳機進行聽音樂,也可以連接智能家居設備,控制家電。

所以,根據上圖劃分,按照應用劃分的話,基本可以確定哪類場景使用哪種開發方式。具體不再贅述。

2. 開發區別

如果直接想看代碼, 可以直接看這裏:

  1. Android 經典藍牙開發
  2. Android 低功耗藍牙開發

那麼,低功耗藍牙和經典藍牙的區別究竟在哪裏呢?

要是僅僅從兩者的通信方式上來說,可以說除了名字叫藍牙外,完全可以當做兩個東西。這也就爲很多搞過經典藍牙以爲就可以很輕鬆的接着搞低功耗藍牙的人埋下了一個大坑。

不過,兩者在總體上的流程卻也是相似的(好吧,無線通信貌似也都是這麼個流程),那就是:

發現設備->配對/綁定設備->建立連接->數據通信

經典藍牙和低功耗藍牙除了配對/綁定這個環節是一樣的之外,其它三個環節都是不同的。

2.1 發現設備

經典藍牙設備發現其它經典藍牙設備的方式是調用BluetoothAdapter的startDiscovery()方法,這個方法只能夠發現經典藍牙設備。

低功耗藍牙中則有一個主設備(Central)和從設備(Peripheral,也叫外圍設備)的概念。主設備作爲發現方,調用發現設備的方法,通過BluetoothAdapter的startLeScan()方法實現。從設備則作爲被發現方,發出廣播,以供發現。同樣,這個startLeScan()方法也僅能夠發現低功耗藍牙從設備。

不過,在Android系統藍牙搜索界面,兩種藍牙設備都是可以被發現的。只有當兩種藍牙設備被某設備(包括當前的設備)配對/綁定後,纔不會再被掃描到。

2.2 配對/綁定

有很多小夥伴都不太理解配對和綁定究竟有什麼區別,或者它們根本就是同一個東西。好吧,嚴格說配對和綁定是有區別的,也就是不是指的同一件事情。但是這兩者的區別比較模糊,也不好解釋。目前JACK的機器人的理解是,配對是建立兩者的對應關係,而綁定則把這層關係保存固定下來並進行了強化,暫時這麼理解着吧。

不管是經典藍牙還是低功耗藍牙,綁定方法都是通用的,可以調用相同的綁定方法。

2.3 建立連接

在建立連接的方式上,兩者就千差萬別了。

在藍牙設備中,存在着物理地址,我們也叫作藍牙的 MAC 地址,這個地址是唯一的,就像咱們網絡上的 IP地址。同時還存在着一個叫做 UUID 的東西,可以把它理解爲是 IP 地址中的端口號。正如知道了 IP 地址和端口號,就知道了怎麼鏈接到目標網絡服務器位置,知道了藍牙設備的 MAC 地址和 UUID 也就能夠確定到具體是哪一臺藍牙設備了,這兩者合起來就是藍牙的唯一身份標識。

2.3.1 經典藍牙的連接方式

經典藍牙建立連接的方式實際上就是 Socket 的連接的建立。
只不過這裏不是直接用 Socket,而是 BluetoothSocket。獲取 BluetoothSocket 的方式也很簡單,利用搜索找到的BluetoothDevice,調用其方法 createRfcommSocketToServiceRecord(UUID)。最後,使用獲取到的BluetoothDevice 調用其方法 connect() 就建立了經典藍牙設備之間的連接通道。

2.3.2 BLE 低功耗藍牙的連接方式

低功耗藍牙則用了一種看起來比較怪異的方式建立連接。我們先來看關於 BLE 的一些基本概念:

Generic Attribute Profile (GATT)
通過BLE連接,讀寫屬性類小數據的 Profile 通用規範。現在所有的 BLE 應用 Profile 都是基於 GATT 的。

Attribute Protocol (ATT)
GATT 是基於 ATT Protocol 的。ATT 針對 BLE 設備做了專門的優化,具體就是在傳輸過程中使用盡量少的數據。每個屬性都有一個唯一的 UUID,屬性將以 characteristics and services 的形式傳輸。

Characteristic
Characteristic 可以理解爲一個數據類型,它包括一個 value 和 0 至多個對次 value 的描述(Descriptor)。

Descriptor
對 Characteristic 的描述,例如範圍、計量單位等。

Service
Characteristic 的集合。例如一個 service 叫做 “Heart Rate Monitor”,它可能包含多個 Characteristics,其中可能包含一個叫做 “heart rate measurement" 的 Characteristic。

這裏舉個例子,例如現在需要使用一個智能手機作爲主設備去連接一個作爲從設備的智能手環,那麼,此時這個作爲主設備的智能手機連接過程中實際是一個客戶端(Client),而作爲從設備的智能手環在此過程中則是服務端(Server)。這裏的主設備和從設備,客戶端和服務端一定要區分清楚。

想要和一臺 BLE 從設備建立連接,一般是某個智能設備,例如智能手環、智能燈泡之類的。如果使用智能手機作爲測試平臺,其硬件條件是,藍牙得至少是低功耗藍牙版本,然後安卓系統的話,至少得是 Android 4.3以上系統才行,因爲 Google 在 Android 4.3 以上才做了BLE主設備的支持,如果想將智能手機作爲 BLE 從設備,則必須在 Android 5.0 以上才行。

具體建立 GATT 連接的順序則是,首先通過 BluetoothAdapter 的 getRemoteDevice(address) 方法獲取到相應 BLE 從設備的 BluetoothDevice,其中的 address 爲目標藍牙設備 MAC 地址。

然後通過此BluetoothDevice的connectGatt(this, false, mGattCallback)方法獲取設備連接。此時的連接,只能夠進行監聽,也就是獲取到當前 BLE 從設備廣播出來的數據。

2.4 數據通信

2.4.1 經典藍牙數據通信

經典藍牙中,當建立連接後,就可以直接使用 BluetoothSocket 的 getOutputStream() 方法獲取輸出流寫入需要發送的數據。讀取發送回來的數據,則是調用 BluetoothSocket 的 getInputStream() 方法獲取輸入流讀取。這點和 Java中 的 Socket 通信幾乎是一模一樣。

2.4.2 低功耗藍牙數據通信

而在低功耗藍牙中,想要實現主設備對從設備的數據發送,則需要直接讀取獲取到的從設備的Characteristic,而Characteristic 又是 Service 下面的一層,所以操作順序是:

  1. 通過 BLE 從設備相應的 Service_UUID 獲取對應的 BluetoothGattService,獲取方法是:使用BluetoothDevice 的 connectGatt(this, false, mGattCallback) 方法返回的 BluetoothGatt 對象,調用BluetoothGatt 的方法 getService(Service_UUID) 獲取相應的BluetoothGattService;

  2. 調用 BluetoothGattService 和對應的 Characteristic 的寫入 UUID 獲取相應的BluetoothGattCharacteristic,獲取方法是:調用 BluetoothGattService 的getCharacteristic(Characteristic_UUID) 方法獲得;

  3. 設置需要發送的命令值,調用 BluetoothGattCharacteristic 的方法 setValue(value) 進行設置,其中 value一般爲 byte[];

  4. 最後,使用 BluetoothGatt 的寫入方法 writeCharacteristic(TxChar) 完成命令發送。

可以看到,想要實現 BLE 的數據通信,步驟相當繁瑣,這裏只是做一個簡單的概念理解,如果想要獲取到BLE 從設備的返回值,還需要設置 Notification,然後調用 BluetoothGatt 的 readCharacteristic(characteristic) 方法進行數據的讀取,這裏不做詳細說明了,放在以後詳細開發 BLE 藍牙通信的時候再做解釋。

參考文章

  1. 經典藍牙與低功耗藍牙的區別
發佈了331 篇原創文章 · 獲贊 168 · 訪問量 95萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章