1. 程式人生 > >Android經典藍芽和Ble藍芽的對比

Android經典藍芽和Ble藍芽的對比

Android中的藍芽開發

要說到藍芽,小夥伴們聽到的可能有藍芽1.0、藍芽2.0、藍芽3.0、藍芽4.0之類的以數字結尾的藍芽版本號,而實際上,在最新的標準中,已經不再使用數字版本號作為藍芽版本的區分了,取而代之的是經典藍芽與低功耗藍芽(BLE)這兩種區別。

這裡提到的低功耗藍芽也會有很多人會誤解為就是藍芽4.0,但是完整的藍芽4.0規範中實際上包括有經典藍芽和低功耗藍芽這兩個部分,小夥伴們看看如下這張分類表就能夠明白這其中的關係了。

Android中經典藍芽與低功耗藍芽的簡單對比分析

如表中所述,咱們現在的藍芽實際上分為了三類:單模、雙模和經典。那麼,最官方的藍芽版本稱呼就是,單模藍芽、雙模藍芽和經典藍芽。

在這其中,最前沿的當屬單模藍芽了,也就是低功耗藍芽。這個藍芽標準和經典藍芽區別極大,在最初甚至考慮過加入WIFI陣營,但是因為藍芽陣營這邊條件較為優厚(比如授權費用極低)才併入了藍芽標準。

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

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

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

  • 發現裝置->配對/繫結裝置->建立連線->資料通訊

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

1. 發現裝置

經典藍芽裝置發現其它經典藍芽裝置的方式是呼叫BluetoothAdapter的startDiscovery()方法,這個方法只能夠發現經典藍芽裝置。

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

不過,在Android系統藍芽搜尋介面,兩種藍芽裝置都是可以被發現的。只有當兩種藍芽裝置被某裝置(包括當前的裝置)配對/繫結後,才不會再被掃描到。

2. 配對/繫結

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

不管是經典藍芽還是低功耗藍芽,繫結方法都是通用的,可以呼叫相同的繫結方法。

3. 建立連線

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

——藍芽小知識——

在藍芽裝置中,存在著實體地址,我們也叫作藍芽的MAC地址,這個地址是唯一的,就像咱們網路上的IP地址。同時還存在著一個叫做UUID的東西,可以把它理解為是IP地址中的埠號。正如知道了IP地址和埠號,就知道了怎麼連結到目標網路伺服器位置,知道了藍芽裝置的MAC地址和UUID也就能夠確定到具體是哪一臺藍芽裝置了,這兩者合起來就是藍芽的唯一身份標識。

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

低功耗藍芽則用了一種看起來比較怪異的方式建立連線(JACK的機器人被這種建立連線的方式折騰了好久)。

——關於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從裝置廣播出來的資料。

4. 資料通訊

經典藍芽中,當建立連線後,就可以直接使用BluetoothSocket的getOutputStream()方法獲取輸出流寫入需要傳送的資料。讀取傳送回來的資料,則是呼叫BluetoothSocket的getInputStream()方法獲取輸入流讀取。這點和Java中的Socket通訊幾乎是一模一樣。

而在低功耗藍芽中,想要實現主裝置對從裝置的資料傳送,則需要直接讀取獲取到的從裝置的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通訊的時候再做解釋。

最後奉上Google的官方藍芽演示DEMO原始碼,來自Android官方網站,小夥伴們可以參考原始碼再看看JACK的機器人的說明對比,這樣相信會更加利於理解。

下載地址

百度網盤提取碼:1qyp

此原始碼壓縮包中包括三個工程,都需要使用Android Studio開啟進行編譯安裝,具體說明如下:

(1)BluetoothAdvertisements.zip是Android智慧裝置作為從裝置的DEMO,需要在Android 5.0以上真機執行。

(2)BluetoothLeGatt.zip是Android智慧裝置作為主裝置的DEMO,需要在Android 4.3以上真機執行。

(3)BluetoothChat.zip是一個藍芽聊天室,兩臺具備藍芽的Android智慧裝置即可安裝執行,可以實現經典藍芽通訊方式的資料傳送與顯示。