有兩種廣播包:
廣播數據包對每個外設都是強制性的,而響應數據包是可選的。每個廣播包的長度必須是31字節。如果小於31字節,其余部分用零填充,這部分數據無效。
壹個廣播數據包包含幾個廣播數據單元,也稱為AD結構。
廣播數據單元=長度值長度+廣告類型+廣告數據。
長度值Length僅占用壹個字節,位於廣播數據單元的第壹個字節。
這個概念有點抽象。讓我們看看下面的廣播消息:
?0x表示該字符串是十六進制字符串。兩個十六進制數字代表壹個字節。因為兩個字符組成的十六進制字符串最大值是FF,也就是255,而Java中byte type的取值範圍是-128到127,剛好可以表示壹個255的大小。所以兩個十六進制字符串代表壹個字節。
?繼續檢查消息內容,並開始讀取第壹個廣播數據單元。讀取第壹個字節:0x07,轉換成十進制,表示接下來的7個字節就是這個廣播數據單元的數據內容。數據內容超過這7個字節後,意味著壹個新的廣播數據單元。
?在第二個廣播數據單元中,第壹個字節的值為0x16,轉換成十進制時為22,表示接下來的22個字節為第二個廣播數據單元。
?在廣播數據單元的數據部分中,第壹個字節代表數據類型,它決定了數據部分代表什麽數據。(即,廣播數據單元的第二字節是AD類型)
廣告類型的類型如下:
?該位1~7分別代表發送廣播的藍牙芯片的物理連接狀態。當bit的值為1時,支持該功能。
示例:
簡述了藍牙廣播的數據格式,有助於後面廣播操作的理解。
讓我們看看廣告設置是如何定義的:
(1).通過advertise settings . builder # setadvertise mode()設置廣播模式。有三種模式:
(2)通過advertise settings . builder # setAdvertiseMode()設置廣播發射功率。* * *有四種電源模式:
(3)通過advertise settings . builder # settimeout()設置連續播放時間,單位為毫秒。最多180000毫秒。當值為0時,沒有時間限制,廣播會繼續,除非調用bluetooth leadvertiser # stop advertising()停止廣播。
(4)設置是否可以通過advertise settings . builder # Set connectable()連接廣播。
如前所述,外設必須廣播廣播包,掃描包可選。但是增加掃描包也意味著廣播更多的數據,也就是廣播62字節。
可以看出,無論是廣播包還是掃描包,廣播內容都是由AdvertiseData類封裝的。
(1),廣告數據。Builder # setincludeddevicename()方法,可以設置廣播包中是否包含藍牙的名稱。
(2),廣告數據。Builder # setincludedpowerlevel()方法,可以設置廣播包中是否包含藍牙的發射功率。
(3),廣告數據。builder # addServiceUUID(ParcelUUID)方法,可以在廣播包中設置特定的UUID。
(4),廣告數據。builder # addServiceData(ParcelUUID,byte[])方法,可以在廣播包中設置特定的UID及其數據。
(5),廣告數據。builder # addManufacturerData(int,byte[])方法,可以在廣播包中設置特定的廠商Id及其數據。
?從AdvertiseData的設定就可以看出來。構建器,如果外設需要在沒有連接的情況下廣播數據,其數據可以存儲在對應於UUID的數據中或制造商的數據中。但是因為廠商ID需要藍牙SIG來分配,所以廠商之間的數據壹般都是在廠商數據中設置的。
此外,您可以通過BluetoothAdapter#setName()設置廣播的名稱。
我們先來看壹個例子。我們設置廣告數據的每個廣播消息參數。構建器分別在廣播包和掃描包中,得到報文內容:
(1)和type = 0x001表示設備LE的物理連接。
(2) Type = 0x09表示設備的全名。
(3) Type = 0x03表示完整的16位UUID。其值為0xFFF7。
(4),Type = 0xFF表示制造商數據。前兩個字節表示供應商ID,即供應商ID為0x11。接下來是制造商數據,由用戶定義。
(5) Type = 0x16表示16位UUID的數據,所以前兩個字節是UUID,即UUID是0xF117,後面的數據是UUID,由用戶自定義。
最後,繼承AdvertiseCallback自定義廣播回調。
初始化上述對象後,您可以廣播:
?廣播主要是通過BluetoothLeAdvertiser # start advertising()的方法實現的,但在此之前,妳需要獲取bluetooth leadvertiser對象。
BluetoothLeAdvertiser對象在以下兩種情況下會得到Null:
所以在調用藍牙適配器# getBluetoothLeadVertiser()之前,需要調用判斷藍牙是否開啟。並判斷在BluetoothAdapter中獲取的BluetoothLeAdvertiser是否為空(部分華為手機測試過,如mbluetoothadapter。ismultipleadevertisementsupported()為false,但可以發送ble廣播)。
?與廣播配對意味著bluetoothleadvertiser。stopadvertising()停止廣播,可以通過傳入廣播開始時傳遞的廣播回調對象來關閉廣播:
?雖然外界通過廣播獲知其擁有這些服務,但手機本身並沒有初始化Gattd的服務。導致外部中心設備連接到手機後,無法找到相應的GATT服務並獲取相應的數據。
服務類型有兩個級別:
創建BluetoothGattService時,會傳入兩個參數:UUID和服務類型:
?我們都知道在Gatt中,下壹級服務是特性,它是最小的通信單元,通過讀寫特性進行通信。
?feature屬性指明了BluetoothGattCharacteristic有哪些功能,即可以在BluetoothGattCharacteristic上執行哪些操作。主要有三種:
權限屬性用於配置該特征值的功能。有兩種主要類型:
在特征下還有壹個描述符。初始化BluetoothGattDescriptor時,會傳入描述符UUID和權限屬性。
添加服務的特征和特征描述符:
?通過mBluetoothManager獲取Gatt服務器,用於添加Gatt服務。添加GATT服務後,當外部中央設備連接到手機時,將能夠獲得相應的Gatt服務,並獲得相應的數據。
?定義Gatt服務器回調。當中央設備連接到移動電話外圍設備時,特征值被修改,特征值被讀取,等等。,將獲得相應的回調。
最後,打開廣播後,連接nRF後看到的特征值信息如下圖所示:(增加了壹個只能用的特征值)
安卓藍牙BLE(1)-掃描
安卓藍牙BLE(2)-通信
安卓藍牙BLE(3)-廣播
安卓藍牙BLE(四)-實戰