初始化藍牙
使用藍牙之前,首先要先初始化藍牙(openBluetoothAdapter)
,之后才能調用藍牙的各種api。初始化狀態分為兩種:
初始化成功:這時可以去搜索藍牙設備(startBluetoothDevicesDiscovery)
。
初始化失敗:這個時候需要提示用戶打開藍牙,同時監聽藍牙的狀態(onBluetoothAdapterStateChange)
,當藍牙打開時,去搜索設備。
openBluetoothAdapter() {
const that = this
wx.openBluetoothAdapter({
success: (res) => {
console.log('openBluetoothAdapter success', res)
// 初始化成功,去搜索設備
this.startBluetoothDevicesDiscovery()
},
fail: (res) => {
if (res.errCode === 10001) {
// 藍牙未打開,監聽藍牙狀態
wx.onBluetoothAdapterStateChange(function (res) {
console.log('onBluetoothAdapterStateChange', res)
if (res.available) {
that.startBluetoothDevicesDiscovery()
}
})
}
}
})
}
搜索藍牙設備
開始搜索附近的藍牙設備(startBluetoothDevicesDiscovery)
,該操作比較耗費資源,建議在連接到藍牙設備后,手動停止搜索。
startBluetoothDevicesDiscovery() {
if (this._discoveryStarted) {
return
}
this._discoveryStarted = true
// 開始搜索藍牙設備,allowDuplicatesKey,會重復搜索同一設備
wx.startBluetoothDevicesDiscovery({
allowDuplicatesKey: true,
success: (res) => {
console.log('startBluetoothDevicesDiscovery success', res)
this.onBluetoothDeviceFound()
},
})
}
獲取藍牙設備
獲取藍牙設備有兩個api。
onBluetoothDeviceFound
:獲取新發現的設備,將startBluetoothDevicesDiscovery
中的allowDuplicatesKey
設置為true
時,該方法重復上報同一藍牙設備。getBluetoothDevices
:獲取已經發現的藍牙設備列表,該方法獲取的藍牙設備數量跟搜索時間有關系,一般在開始搜索藍牙設備后,延時一段時間在調用該方法。
onBluetoothDeviceFound() {
// 獲取新發現的藍牙設備
wx.onBluetoothDeviceFound((res) => {
res.devices.forEach(device => {
if (!device.name && !device.localName) {
return
}
const foundDevices = this.data.devices
const idx = inArray(foundDevices, 'deviceId', device.deviceId)
const data = {}
if (idx === -1) {
data[`devices[${foundDevices.length}]`] = device
} else {
data[`devices[${idx}]`] = device
}
this.setData(data)
})
})
}
連接藍牙設備
createBLEConnection
:連接藍牙設備,基本上到這,藍牙設備就連接上了。為了避免一個設備多個連接實例,一般和closeBLEConnection
成對調用。在連接成功后,一般需要調用stopBluetoothDevicesDiscovery
,停止藍牙的搜索。
createBLEConnection(e) {
const ds = e.currentTarget.dataset
const deviceId = ds.deviceId
const name = ds.name
// 開始連接藍牙設備
wx.createBLEConnection({
deviceId,
success: (res) => {
this.setData({
connected: true,
name,
deviceId,
})
this.getBLEDeviceServices(deviceId)
}
})
// 在連接藍牙設備后,停止搜索藍牙。
this.stopBluetoothDevicesDiscovery()
}
停止搜索藍牙設備
stopBluetoothDevicesDiscovery
: 在藍牙設備連接成功后,需要停止搜索藍牙設備。
stopBluetoothDevicesDiscovery() {
wx.stopBluetoothDevicesDiscovery()
}
監聽藍牙設備的連接狀態
onBLEConnectionStateChange
:監聽藍牙設備的連接狀態,包括藍牙設備的丟失,斷開,可以在該方法中進行處理這些連接后發生的異常情況。
wx.onBLEConnectionStateChange(function (res) {
// 該方法回調中可以用於處理連接意外斷開等異常情況
console.log(`device ${res.deviceId} state has changed, connected: ${res.connected}`)
})
獲取藍牙設備服務
在連接上藍牙設備后,我們想要的還是跟藍牙進行通信,或讀取藍牙設備的數據,或寫數據到藍牙設備。首先需要獲取藍牙設備的服務信息。
getBLEDeviceServices(deviceId) {
// 獲取藍牙設備的服務信息。
wx.getBLEDeviceServices({
deviceId,
success: (res) => {
for (let i = 0; i < res.services.length; i++) {
if (res.services[i].isPrimary) {
// 獲取藍牙設備的特征值
this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
return
}
}
}
})
}
獲取藍牙設備的特征值
getBLEDeviceCharacteristics
:根據藍牙的服務信息,獲取可以跟藍牙進行通信的特征值。一般使用notify或indicate為true、read或write為true
的特征值。
啟用藍牙設備的通知功能
notifyBLECharacteristicValueChange
: 啟用藍牙設備的通知功能,該方法需要藍牙設備的特征值 notify 或 indicate 為 true
。只有在在藍牙設備啟用該功能,才能監聽到藍牙設備的數據變化。
獲取藍牙設備的數據
onBLECharacteristicValueChange
:監聽藍牙設備的數據變化,當藍牙設備的數據變化時,可以獲取相應變化后的數據。需要在啟用藍牙設備的通知功能后才能使用。
寫數據到藍牙設備
writeBLECharacteristicValue
:寫數據到藍牙設備,需要特征值的write為true
。
// 獲取藍牙設備的特征值
getBLEDeviceCharacteristics(deviceId, serviceId) {
wx.getBLEDeviceCharacteristics({
deviceId,
serviceId,
success: (res) => {
console.log('getBLEDeviceCharacteristics success', res.characteristics)
for (let i = 0; i < res.characteristics.length; i++) {
let item = res.characteristics[i]
if (item.properties.read) {
// 讀取藍牙設備的數據
wx.readBLECharacteristicValue({
deviceId,
serviceId,
characteristicId: item.uuid,
})
}
if (item.properties.write) {
this.setData({
canWrite: true
})
this._deviceId = deviceId
this._serviceId = serviceId
this._characteristicId = item.uuid
// 寫數據到藍牙設備
this.writeBLECharacteristicValue()
}
if (item.properties.notify || item.properties.indicate) {
// 啟用藍牙設備的通知功能,之后才能監聽到藍牙數據的變化
wx.notifyBLECharacteristicValueChange({
deviceId,
serviceId,
characteristicId: item.uuid,
state: true,
})
}
}
},
fail(res) {
console.error('getBLEDeviceCharacteristics', res)
}
})
// 監聽藍牙設備的數據變化
wx.onBLECharacteristicValueChange((characteristic) => {
const idx = inArray(this.data.chs, 'uuid', characteristic.characteristicId)
const data = {}
if (idx === -1) {
data[`chs[${this.data.chs.length}]`] = {
uuid: characteristic.characteristicId,
value: ab2hex(characteristic.value)
}
} else {
data[`chs[${idx}]`] = {
uuid: characteristic.characteristicId,
value: ab2hex(characteristic.value)
}
}
this.setData(data)
})
}
// 寫數據到藍牙設備
writeBLECharacteristicValue() {
// 向藍牙設備發送一個0x00的16進制數據
let buffer = new ArrayBuffer(1)
let dataView = new DataView(buffer)
dataView.setUint8(0, Math.random() * 255 | 0)
wx.writeBLECharacteristicValue({
deviceId: this._deviceId,
serviceId: this._serviceId,
characteristicId: this._characteristicId,
value: buffer,
})
}
斷開藍牙設備的連接
closeBLEConnection
:斷開與藍牙設備的連接
closeBLEConnection() {
// 斷開藍牙設備的連接
wx.closeBLEConnection({
deviceId: this.data.deviceId
})
this.setData({
connected: false,
chs: [],
canWrite: false,
})
}
關閉藍牙模塊
closeBluetoothAdapter
: 當藍牙使用完成后,關閉藍牙模塊,釋放系統資源。
// 關閉藍牙模塊
wx.closeBluetoothAdapter({
success(res) {
console.log(res)
}
})