天天看點

UNI-APP實作物聯網中BLE藍牙的資料互動UNI-APP的官網

前言:UNI-APP是一個使用 Vue.js 開發所有前端應用的架構,開發者編寫一套代碼,可釋出到iOS、Android、Web(響應式)、以及各種小程式(微信/支付寶/百度/頭條/飛書/QQ/快手/釘釘/淘寶)、快應用等多個平台。即使你不需要釋出到那麼多的平台,UNI-APP也是一個不錯的微信小程式的開發架構

UNI-APP的官網

了解藍牙API傳回的報錯

錯誤碼 錯誤資訊 說明
ok 正常
10000 not init 未初始化藍牙擴充卡
10001 not available 目前藍牙擴充卡不可用
10002 no device 沒有找到指定裝置
10003 connection fail 連接配接失敗
10004 no service 沒有找到指定服務
10005 no characteristic 沒有找到指定特征值
10006 no connection 目前連接配接已斷開
10007 property not support 目前特征值不支援此操作
10008 system error 其餘所有系統上報的異常
10009 system not support Android 系統特有,系統版本低于 4.3 不支援 BLE
10012 operate time out 連接配接逾時
10013 invalid_data 連接配接 deviceId 為空或者是格式不正确

初始化藍牙子產品

uni.openBluetoothAdapter(OBJECT)

  • 其他藍牙相關 API 必須在這個方法調用之後使用。否則 API 會傳回錯誤(errCode=10000)。
  • 在使用者藍牙開關未開啟或者手機不支援藍牙功能的情況下,調用這個方法會傳回錯誤(errCode=10001),表示手機藍牙功能不可用。
  • 初始化完成後,可通過

    uni.onBluetoothAdapterStateChange

    監聽手機藍牙狀态的改變,也可以調用藍牙子產品的所有API。

示例代碼

uni.openBluetoothAdapter({
	success: (res) => {
		if (res.errMsg == 'openBluetoothAdapter:ok') {}
	}
})
           

監聽藍牙狀态變化事件

uni.onBluetoothAdapterStateChange(CALLBACK)

CALLBACK 傳回參數

屬性 類型 說明
available boolean 藍牙擴充卡是否可用
discovering boolean 藍牙擴充卡是否處于搜尋狀态

示例代碼

uni.onBLEConnectionStateChange((res) => {
	if (res.connected == false) {
		this.cut = true
		uni.showModal({
			title: "藍牙連接配接斷開",
			content: "是否重新搜尋",
			success: (res) => {
				if (res.confirm) this.search()
			}
		})
	}
})
           

搜尋周圍的藍牙

uni.startBluetoothDevicesDiscovery(OBJECT)

  • App 端目前僅支援發現ble藍牙裝置
  • 開始搜尋附近的藍牙外圍裝置。此操作比較耗費系統資源,請在搜尋并連接配接到裝置後調用

    uni.stopBluetoothDevicesDiscovery

    方法停止搜尋。

OBJECT 參數說明

屬性 類型 預設值 必填 說明
services Array 要搜尋但藍牙裝置主 service 的 uuid 清單。某些藍牙裝置會廣播自己的主 service 的 uuid。如果設定此參數,則隻搜尋廣播包有對應 uuid 的主服務的藍牙裝置。建議主要通過該參數過濾掉周邊不需要處理的其他藍牙裝置。
allowDuplicatesKey boolean false 是否允許重複上報同一裝置。如果允許重複上報,則 uni.onBlueToothDeviceFound 方法會多次上報同一裝置,但是 RSSI 值會有不同。
interval number 上報裝置的間隔。0 表示找到新裝置立即上報,其他數值根據傳入的間隔上報。
success function 接口調用成功的回調函數
fail function 接口調用失敗的回調函數
complete function 接口調用結束的回調函數(調用成功、失敗都會執行)

示例代碼

uni.startBluetoothDevicesDiscovery({
	allowDuplicatesKey: true, //是否允許重複上報同一裝置
	interval: 0, //搜尋間隔
	success: (res2) => {
		if (res2.errMsg == 'startBluetoothDevicesDiscovery:ok') {
			this.monitor()
		}
	}
})
           

監聽尋找到新裝置的事件

uni.onBluetoothDeviceFound(CALLBACK)

CALLBACK 傳回參數

屬性 類型 說明
devices Array 新搜尋到的裝置清單

devices 的結構

屬性 類型 說明
name string 藍牙裝置名稱,某些裝置可能沒有
deviceId string 用于區分裝置的 id
RSSI number 目前藍牙裝置的信号強度
advertisData ArrayBuffer 目前藍牙裝置的廣播資料段中的 ManufacturerData 資料段
advertisServiceUUIDs Array 目前藍牙裝置的廣播資料段中的 ServiceUUIDs 資料段
localName string 目前藍牙裝置的廣播資料段中的 LocalName 資料段
serviceData Object 目前藍牙裝置的廣播資料段中的 ServiceData 資料段
  • 若在

    uni.onBluetoothDeviceFound

    回調了某個裝置,則此裝置會添加到

    uni.getBluetoothDevices

    (有興趣的話的查找一下)接口擷取到的數組中。

示例代碼

uni.onBluetoothDeviceFound((res) => {
	res.devices.forEach(result => {
		if ((result.name != '') && (result.localName != '')) {
			let idx = util.inArray(this.booth.list, 'deviceId', result.deviceId)
			if (idx === -1) {
				this.booth.list.push(result)
			} else {
				this.booth.list[idx] = result
			}
		}
	})
})
           

停止搜尋附近的藍牙外圍裝置

uni.stopBluetoothDevicesDiscovery(OBJECT)

  • 搜尋藍牙是很費資源的行為,若已經找到需要的藍牙裝置并不需要繼續搜尋時,建議調用該接口停止藍牙搜尋。

OBJECT 參數說明

屬性 類型 說明
success function 接口調用成功的回調函數
fail function 接口調用失敗的回調函數
complete function 接口調用結束的回調函數(調用成功、失敗都會執行)

示例代碼

stopSearch() {
	uni.stopBluetoothDevicesDiscovery()
}
           

連接配接低功耗藍牙裝置

uni.createBLEConnection(OBJECT)

  • 若APP在之前已有搜尋過某個藍牙裝置,并成功建立連接配接,可直接傳入之前搜尋擷取的 deviceId 直接嘗試連接配接該裝置,無需進行搜尋操作。
  • 藍牙連接配接随時可能斷開,建議監聽

    uni.onBLEConnectionStateChange

    回調事件,當藍牙裝置斷開時按需執行重連操作
  • 若對未連接配接的裝置或已斷開連接配接的裝置調用資料讀寫操作的接口,會傳回 10006 錯誤,建議進行重連操作。
  • 盡量成對的調用連接配接和斷開的接口,如果多次調用連接配接接口,有可能導緻系統持有同一裝置多個連接配接的執行個體,導緻調用斷開接口失效

OBJECT 參數說明

屬性 類型 必填 說明
deviceId string 用于區分裝置的 id
timeout number 逾時時間,機關ms,不填表示不會逾時
success function 接口調用成功的回調函數
fail function 接口調用失敗的回調函數
complete function 接口調用結束的回調函數(調用成功、失敗都會執行)

示例代碼

uni.createBLEConnection({
	deviceId: this.uuid.deviceId,
	success: (res) => {
		if (res.errMsg == 'createBLEConnection:ok') {
			setTimeout(() => {
				this.Service()
				this.BLEChange()
			}, 2000)
		}
	}
})
           

擷取藍牙裝置所有服務

uni.getBLEDeviceServices(OBJECT)

  • 這裡有一個坑,連接配接裝置成功後,不能立即調用

    uni.getBLEDeviceServices(OBJECT)

    ,否則擷取不到任何服務。解決方法:連接配接成功後,等個幾秒(看裝置的情況)在調用

    uni.getBLEDeviceServices(OBJECT)

OBJECT 參數說明

屬性 類型 必填 說明
deviceId string 藍牙裝置 id
success function 接口調用成功的回調函數
fail function 接口調用失敗的回調函數
complete function 接口調用結束的回調函數(調用成功、失敗都會執行)

success 傳回參數說明

屬性 類型 說明
services Array 裝置服務清單

res.services 的結構

屬性 類型 說明
uuid string 藍牙裝置服務的 uuid
isPrimary boolean 該服務是否為主服務

示例代碼

uni.getBLEDeviceServices({
	deviceId: this.uuid.deviceId,
	success: (res) => {
		if (res.services.length == 0) {
			util.showError("找不到服務")
		} else {
			let booth = true
			for (let i = 0; i < res.services.length; i++) {
				if (res.services[i].uuid == this.uuid.service) {
					booth = false
					this.Character()
					break;
				}
			}
			if (booth) util.showError("服務uuid錯誤")
		}
	}
})
           

擷取藍牙裝置某個服務中所有特征值

uni.getBLEDeviceCharacteristics(OBJECT)

OBJECT 參數說明

屬性 類型 必填 說明
deviceId string 藍牙裝置 id
serviceId string 藍牙服務 uuid,需要使用

getBLEDeviceServices

擷取
success function 接口調用成功的回調函數
fail function 接口調用失敗的回調函數
complete function 接口調用結束的回調函數(調用成功、失敗都會執行)

success 傳回參數說明

屬性 類型 說明
characteristics Array 裝置服務清單

res.characteristics 的結構

屬性 類型 說明
uuid string 藍牙裝置特征值的 uuid
properties Object 該特征值支援的操作類型

properties 的結構

屬性 類型 說明
uuid string 藍牙裝置特征值的 uuid
read boolean 該特征值是否支援 read 操作
write boolean 該特征值是否支援 write 操作
notify boolean 該特征值是否支援 notify操作
indicate boolean 該特征值是否支援 indicate操作
  • read:讀取操作
  • write:寫入操作

示例代碼

uni.getBLEDeviceServices({
					deviceId: this.uuid.deviceId,
					success: (res) => {
						if (res.services.length == 0) {
							util.showError("找不到服務")
						} else {
							let booth = true
							for (let i = 0; i < res.services.length; i++) {
								if (res.services[i].uuid == this.uuid.service) {
									booth = false
									this.Character()
									break;
								}
							}
							if (booth) util.showError("服務uuid錯誤")
						}
					}
				})
           

啟用低功耗藍牙裝置特征值變化時的 notify 功能

uni.notifyBLECharacteristicValueChange(OBJECT)

  • 必須裝置的特征值支援 notify 或者 indicate 才可以成功調用
  • 訂閱操作成功後需要裝置主動更新特征值的 value,才會觸發

    uni.onBLECharacteristicValueChange

    (後續監聽裝置的傳回消息)回調
  • 安卓平台上,在調用

    notifyBLECharacteristicValueChange

    成功後立即調用

    writeBLECharacteristicValue

    (向裝置發送資訊)接口,在部分機型上會發生 10008 系統錯誤
  • 連接配接藍牙裝置的過程到此結束

OBJECT 參數說明

屬性 類型 必填 說明
deviceId string 藍牙裝置 id
serviceId string 藍牙特征值對應服務的 uuid
characteristicId string 藍牙特征值的 uuid
state boolean 是否啟用 notify
success function 接口調用成功的回調函數
fail function 接口調用失敗的回調函數
complete function 接口調用結束的回調函數(調用成功、失敗都會執行)

示例代碼

uni.notifyBLECharacteristicValueChange({
					deviceId: this.uuid.deviceId,
					serviceId: this.uuid.service,
					characteristicId: this.uuid.character,
					state: true,
					success: (res) => {
						if (res.errMsg == 'notifyBLECharacteristicValueChange:ok') {
							uni.hideLoading();
							this.cut = false
							this.BLEValue()
						}
					}
				})
           

監聽低功耗藍牙裝置的特征值變化事件(擷取裝置發送的資訊)

uni.onBLECharacteristicValueChange(CALLBACK)

  • 監聽低功耗藍牙裝置的特征值變化事件。必須先啟用

    notifyBLECharacteristicValueChange

    接口才能接收到裝置推送的 notification。
  • 有些藍牙裝置發送的資訊是多段發送的,需要特殊處理

CALLBACK 傳回參數

屬性 類型 說明
deviceId string 藍牙裝置 id
serviceId string 藍牙特征值對應服務的 uuid
characteristicId string 藍牙特征值的 uuid
value ArrayBuffer 特征值最新的值
  • 接收裝置發送過來的資訊,需要對value字段進行處理才能擷取到資訊
  • 漢字的編碼格式也需要進行特殊處理

###示例代碼

uni.onBLECharacteristicValueChange((res) => {
					let caseoff = this.operation.Receive + util.ab2Str(res.value)
					let len = caseoff.length - 1
					let i = caseoff.charCodeAt(len)
					if (i < 127) {
						this.operation.Receive = ""
						caseoff = util.gbkStrToUtf16Str(caseoff)
						this.operation.receive += caseoff
					} else {
						if (caseoff.charCodeAt(len - 1) > 127) {
							this.operation.Receive = ""
							caseoff = util.gbkStrToUtf16Str(caseoff)
							this.operation.receive += caseoff
						} else {
							this.operation.Receive = caseoff
						}
					}
				})
           

向低功耗藍牙寫入資料

  • 必須裝置的特征值支援 write 才可以成功調用。
  • 并行調用多次會存在寫失敗的可能性。
  • APP不會對寫入資料包大小做限制,但系統與藍牙裝置會限制藍牙4.0單次傳輸的資料大小,超過最大位元組數後會發生寫入錯誤,建議每次寫入不超過20位元組。
  • 若單次寫入資料過長,iOS 上存在系統不會有任何回調的情況(包括錯誤回調)。
  • 安卓平台上,在調用

    notifyBLECharacteristicValueChange

    成功後立即調用

    writeBLECharacteristicValue

    接口,在部分機型上會發生 10008 系統錯誤
屬性 類型 必填 說明
deviceId string 藍牙裝置 id
serviceId string 藍牙特征值對應服務的 uuid
characteristicId string 藍牙特征值的 uuid
value ArrayBuffer 藍牙裝置特征值對應的二進制值
success function 接口調用成功的回調函數
fail function 接口調用失敗的回調函數
complete function 接口調用結束的回調函數(調用成功、失敗都會執行)

示例代碼

let j = 0;
				for (let i = 0; i < SendStr.length / 20; i++) {
					setTimeout(() => {
						let setData = SendStr.substring(j, j + 20)
						setData = new Uint8Array(util.stringToBytes(setData)).buffer
						j = j + 20
						uni.writeBLECharacteristicValue({
							deviceId: this.uuid.deviceId,
							serviceId: this.uuid.service,
							characteristicId: this.uuid.write,
							value: setData,
							fail: (err) => {
								util.showError("發生錯誤")
							}
						})
					}, i * 300)
				}