當前位置:編程學習大全網 - 源碼破解 - android藍牙BLE(三) —— 廣播

android藍牙BLE(三) —— 廣播

? 在藍牙開發中,有些情況是不需要連接的,只要外設廣播自己的數據即可,例如蘋果的 ibeacon 。自 Android 5.0 更新藍牙API後,手機可以作為外設廣播數據。

廣播包有兩種:

其中 廣播包是每個外設都必須廣播的,而響應包是可選的 。每個廣播包的長度必須是 31個字節 ,如果不到 31個字節 ,則剩下的全用 0 填充 補全,這部分的數據是無效的

廣播包中包含若幹個廣播數據單元,廣播數據單元也稱為 AD Structure 。

廣播數據單元 = 長度值Length + AD type + AD Data。

長度值 Length 只占 壹個字節 ,並且位於廣播數據單元的 第壹個字節

概念的東西有些抽象,先看看下面的廣播報文:

? 0x代表這串字符串是十六進制的字符串。 兩位十六進制數代表壹個字節 。因為兩個字符組成的十六進制字符串最大為 FF ,即255,而Java中byte類型的取值範圍是-128到127,剛好可以表示壹個255的大小。所以兩個十六進制的字符串表示壹個字節。

? 繼續查看報文內容,開始讀取第壹個廣播數據單元。讀取 第壹個 字節: 0x07 ,轉換為十進制就是7,即表示後面的7個字節是這個廣播數據單元的數據內容。超過這7個字節的數據內容後,表示是壹個新的廣播數據單元。

? 而第二個廣播數據單元,第壹個字節的值是 0x16 ,轉換為十進制就是22,表示後面22個字節為第二個廣播數據單元。

? 在廣播數據單元的 數據部分 中, 第壹個字節 代表 數據類型 (AD type),決定數據部分表示的是什麽數據。(即廣播數據單元第二個字節為AD type)

AD Type 的類型如下:

? 這bit 1~7分別代表著發送該廣播的藍牙芯片的物理連接狀態。當bit的值為1時,表示支持該功能。

例:

藍牙廣播的數據格式大致講了壹下,有助於下面的廣播操作的理解。

先看看廣播設置( AdvertiseSettings )如何定義:

(1)、通過 AdvertiseSettings.Builder#setAdvertiseMode() 設置廣播模式。其中有3種模式:

(2)、通過 AdvertiseSettings.Builder#setAdvertiseMode() 設置廣播發射功率。***有4種功率模式:

(3)、通過 AdvertiseSettings.Builder#setTimeout() 設置持續廣播的時間,單位為毫秒。最多180000毫秒。當值為0則無時間限制,持續廣播,除非調用 BluetoothLeAdvertiser#stopAdvertising() 停止廣播。

(4)、通過 AdvertiseSettings.Builder#setConnectable() 設置該廣播是否可以連接的。

之前說過,外設必須廣播廣播包,掃描包是可選。但添加掃描包也意味著廣播更多得數據,即可廣播62個字節。

可見無論是廣播包還是掃描包,其廣播的內容都是用 AdvertiseData 類封裝的。

(1)、 AdvertiseData.Builder#setIncludeDeviceName() 方法,可以設置廣播包中是否包含藍牙的名稱。

(2)、 AdvertiseData.Builder#setIncludeTxPowerLevel() 方法,可以設置廣播包中是否包含藍牙的發射功率。

(3)、 AdvertiseData.Builder#addService UUID (Parcel UUID ) 方法,可以設置特定的 UUID 在廣播包中。

(4)、 AdvertiseData.Builder#addServiceData(Parcel UUID ,byte[]) 方法,可以設置特定的 UUID 和其數據在廣播包中。

(5)、 AdvertiseData.Builder#addManufacturerData(int,byte[]) 方法,可以設置特定廠商Id和其數據在廣播包中。

? 從 AdvertiseData.Builder 的設置中可以看出,如果壹個外設需要在不連接的情況下對外廣播數據,其數據可以存儲在 UUID 對應的數據中,也可以存儲在廠商數據中。但由於廠商ID是需要由Bluetooth SIG進行分配的,廠商間壹般都將數據設置在廠商數據。

另外可以通過 BluetoothAdapter#setName() 設置廣播的名稱

先看壹個例子,我們分別在 廣播包 掃描包 中設置 AdvertiseData.Builder 的 每壹種廣播報文參數 ,得到壹下報文內容:

(1)、Type = 0x01 表示設備LE物理連接。

(2)、Type = 0x09 表示設備的全名

(3)、Type = 0x03 表示完整的16bit UUID 。其值為0xFFF7。

(4)、Type = 0xFF 表示廠商數據。前兩個字節表示廠商ID,即廠商ID為0x11。後面的為廠商數據,具體由用戶自行定義。

(5)、Type = 0x16 表示16 bit UUID 的數據,所以前兩個字節為 UUID ,即 UUID 為0xF117,後續為 UUID 對應的數據,具體由用戶自行定義。

最後繼承 AdvertiseCallback 自定義廣播回調。

初始化完畢上面的對象後,就可以進行廣播:

? 廣播主要是通過 BluetoothLeAdvertiser#startAdvertising() 方法實現,但在之前需要先獲取 BluetoothLeAdvertiser 對象。

BluetoothLeAdvertiser 對象存在兩個情況獲取為Null:

所以在調用 BluetoothAdapter#getBluetoothLeAdvertiser() 前,需要先調用判斷藍牙已開啟,並判斷在 BluetoothAdapter 中獲取的 BluetoothLeAdvertiser 是否為空(測試過某些華為手機 mBluetoothAdapter.isMultipleAdvertisementSupported() 為 false , 但是能發送ble廣播)。

? 與廣播成對出現就是 BluetoothLeAdvertiser.stopAdvertising() 停止廣播了,傳入開啟廣播時傳遞的廣播回調對象,即可關閉廣播:

? 雖然通過廣播告知外邊自身擁有這些Service,但手機自身並沒有初始化Gattd的Service。導致外部的中心設備連接手機後,並不能找到對應的 GATT Service 和 獲取對應的數據。

Service類型有兩個級別:

創建 BluetoothGattService 時,傳入兩個參數: UUID 和Service類型:

? 我們都知道Gatt中, Service 的下壹級是 Characteristic , Characteristic 是最小的通信單元,通過對 Characteristic 進行讀寫操作來進行通信。

? 特征屬性表示該 BluetoothGattCharacteristic 擁有什麽功能,即能對 BluetoothGattCharacteristic 進行什麽操作。其中主要有3種:

權限屬性用於配置該特征值所具有的功能。主要兩種:

Characteristic 下還有 Descriptor ,初始化 BluetoothGattDescriptor 時傳入: Descriptor UUID 和 權限屬性

為 Service 添加 Characteristic ,為 Characteristic 添加 Descriptor :

? 通過藍牙管理器 mBluetoothManager 獲取 Gatt Server ,用來添加 Gatt Service 。添加完 Gatt Service 後,外部中心設備連接手機時,將能獲取到對應的 GATT Service 和 獲取對應的數據

? 定義 Gatt Server 回調。當中心設備連接該手機外設、修改特征值、讀取特征值等情況時,會得到相應情況的回調。

最後開啟廣播後,用nRF連接後看到的特征值信息如下圖所示:(加多了壹個只能都的特征值)

android藍牙BLE(壹) —— 掃描

android藍牙BLE(二) —— 通信

android藍牙BLE(三) —— 廣播

android藍牙BLE(四) —— 實戰

  • 上一篇:復雜的校車怎麽畫圖片大全
  • 下一篇:高冷禁欲系男生網名
  • copyright 2024編程學習大全網