小程式藍芽親身總結
問題:
最近做了一個涉及到藍芽模組小程式,做一下總結,為自己的成長做一份記錄,如果能幫到大家的話是再好不過的了;
1.小程式藍芽搜尋能不能搜到手機裝置 2.如何判斷藍芽是否開啟 3.搜尋指定裝置 4.開發者工具和 Android 上獲取到的deviceId為裝置 MAC 地址,iOS 上則為裝置 uuid。因此deviceId不能硬編碼到程式碼中, 如何連線藍芽 5.裝置服務所有 service(服務) 如何去選擇 6.裝置characteristic(特徵值)幹嘛的,怎麼用 7.開啟notify 8.寫入資料
1.小程式藍芽搜尋能不能搜到手機裝置
搜不到!!! 小程式藍芽只支援BLE低功耗藍芽 什麼是低功耗藍芽裝置呢?百度一下,你就知道(^__^
2.如何判斷藍芽是否開啟
利用wx.openBluetoothAdapter(OBJECT)判斷藍芽是否可用 在使用者藍芽開關未開啟或者手機不支援藍芽功能的情況下,呼叫wx.openBluetoothAdapter會返回錯誤,表示手機藍芽功能不可用;
wx.openBluetoothAdapter({ success: function (res) { console.log(res) }, fail: function (res) { wx.showModal({ content: '請開啟手機藍芽後再試' }) } })
注意:建議wx.openBluetoothAdapter(OBJECT)和wx.closeBluetoothAdapter(OBJECT)成對使用 wx.closeBluetoothAdapter:關閉藍芽模組,使其進入未初始化狀態。呼叫該方法將斷開所有已建立的連結並釋放系統資源;
3.搜尋指定裝置
wx.startBluetoothDevicesDiscovery(OBJECT)開始搜尋附近的藍芽外圍裝置wx.getBluetoothDevices(OBJECT)獲取在小程式藍芽模組生效期間所有已發現的藍芽裝置wx.onBluetoothDeviceFound(CALLBACK) 監聽尋找到新裝置的事件
注意:搜尋藍芽wx.startBluetoothDevicesDiscovery(OBJECT)操作比較耗費系統資源,在搜尋並連線到裝置後呼叫 wx.stopBluetoothDevicesDiscovery(OBJECT) 方法停止搜尋。
//開始搜尋藍芽
wx.startBluetoothDevicesDiscovery({
success: function (res) {
console.log('search', res)
}
})
//發現裝置
wx.getBluetoothDevices({
success: function (res) {
console.log('發現裝置', res)
if (res.devices[0]) {
console.log(that.ab2hext(res.devices[0].advertisData))
}
//5s內未搜尋到裝置,關閉搜尋,關閉藍芽模組
setTimeout(function(){
if (!that.data.deviceId){
wx.hideLoading()
app.showToast('搜尋裝置超時','none');
//關閉搜尋
that.stopBluetoothDevicesDiscovery();
//關閉藍芽
that.closeBluetoothAdapter();
}
},5000)
}
})
//監聽發現裝置
wx.onBluetoothDeviceFound(function (devices) {
console.log('發現裝置:', devices.devices)
for (let i = 0; i < devices.devices.length; i++) {
//檢索指定裝置
if (devices.devices[i].name == '裝置name') {
that.setData({
deviceId: devices.devices[i].deviceId
})
//關閉搜尋
that.stopBluetoothDevicesDiscovery();
console.log('已找到指定裝置:', devices.devices[i].deviceId);
}
}
})
ab2hext: function(buffer) {
var hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function (bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('');
}
這段程式碼是通過裝置名name去匹配配對裝置,若5s內未搜到指定裝置則關閉搜尋,關閉藍芽模組; 裝置名是已發現的藍芽裝置device 物件中的name
4.開發者工具和 Android 上獲取到的deviceId為裝置 MAC 地址,iOS 上則為裝置 uuid。因此deviceId不能硬編碼到程式碼中,如何連線藍芽
搜尋我們可以拿到了裝置的deviceId,通過deviceId去連線藍芽Android 上獲取到的deviceId為裝置 MAC 地址,iOS 上獲取到的deviceId則為裝置 uuid,因此deviceId不能硬編碼到程式碼中 那麼可能就有機智的小夥伴說了,設定兩個變數,一個為裝置MAC,一個為裝置uuid 在連線裝置的之前判斷下機型,ios裝置deviceId取:裝置uuid,android裝置deviceId:MAC地址!!! 我原本也是這樣想的,因為我們做的這個小程式是掃碼連線指定裝置(就好像共享單車一樣),所以本來是想在二維碼中直接放入mac和uuid然後連線的時候去根據機型去取對應值 但是!!!但是!!!但是!!! 在實現過程中發現,ios不同手機搜尋到的裝置deviceId還是不同的. 所以還是乖乖通過裝置name(廣播名),去獲取deviceId去連線 只怪自己經驗不足,還總想走捷徑 正確的流程是 初始化藍芽wx.openBluetoothAdapter(OBJECT) ↓ 開始搜尋藍芽 wx.startBluetoothDevicesDiscovery(OBJECT) ↓ 所有已發現的藍芽裝置wx.getBluetoothDevices(OBJECT) ↓ 監聽尋找到新裝置的事件wx.onBluetoothDeviceFound(CALLBACK) ↓ 連線低功耗藍芽裝置wx.createBLEConnection(OBJECT) ↓ 獲取藍芽裝置所有 service(服務) wx.getBLEDeviceServices(OBJECT) ↓ 獲取藍芽裝置某個服務中的所有 characteristic(特徵值)wx.getBLEDeviceCharacteristics(OBJECT) ↓ 啟用低功耗藍芽裝置特徵值變化時的 notify 功能wx.notifyBLECharacteristicValueChange(OBJECT) ↓ 寫入wx.writeBLECharacteristicValue(OBJECT)
在搜尋到裝置後通過拿到的裝置的deviceId去連線裝置
wx.createBLEConnection({
deviceId: that.data.deviceId,//搜尋裝置獲得的藍芽裝置 id
success: function (res) {
console.log('連線藍芽:', res.errMsg);
},
fail: function (res) {
app.showToast('連線超時,請重試或更換車輛', 'none');
that.closeBluetoothAdapter();
}
})
5.serviceId如何去選擇
連線成功以後就可以去獲取裝置的服務列表,我這邊拿的是FEE7的服務ID
wx.getBLEDeviceServices({
deviceId: that.data.deviceId,//搜尋裝置獲得的藍芽裝置 id
success: function (res) {
let service_id = "";
for(let i = 0;i<res.services.length;i++){
if(services[i].uuid.toUpperCase().indexOf("FEE7") != -1){
service_id = services[i].uuid;
break;
}
}
console.log('fee7-service_id:', that.data.service_id);
},
fail(res){
console.log(res);
}
})
6.characteristic(特徵值)幹嘛的,怎麼用
服務特徵值是幹嘛的:每個服務都包含了一組特徵值用來描述服務的一些屬性,獲取是否可讀,是否可寫,是否可以開啟notify通知等,當你跟藍芽通訊時需要這些特徵值ID來傳遞資料。服務特徵值怎麼用:
//獲取特徵值
wx.getBLEDeviceCharacteristics({
deviceId: that.data.deviceId,//搜尋裝置獲得的藍芽裝置 id
serviceId: that.data.service_id,//服務ID
success: function (res) {
console.log('device特徵值:', res.characteristics)
for (let i = 0; i < res.characteristics.length; i++) {
let charc = res.characteristics[i];
if (charc.properties.indicate) {
that.setData({indicate_id: charc.uuid});
console.log('indicate_id:', that.data.indicate_id);
}
if (charc.properties.write) {
that.setData({write_id: charc.uuid});
console.log('寫write_id:', that.data.write_id);
}
if (charc.properties.read) {
that.setData({read_id: charc.uuid});
console.log('讀read_id:', that.data.read_id);
}
}
}
});
篩選出你所需要的服務特徵值 在得到對應特徵值後可以在執行相關操作時使用 例如: 開啟notify:必須裝置的特徵值支援notify或者indicate才可以成功呼叫 支不支援notify或者indicate就是我們上面篩選出來的對應值
if (charc.properties.indicate) {
that.setData({indicate_id: charc.uuid});
console.log('indicate_id:', that.data.indicate_id);
}
7.開啟notify
開啟notify後可以監聽低功耗藍芽裝置的特徵值變化。必須先啟用notify接口才能接收到裝置推送的notification
//開啟notify
wx.notifyBLECharacteristicValueChange({
state: true, // 啟用 notify 功能
deviceId: that.data.deviceId,//藍芽裝置id
serviceId: that.data.service_id,//服務id
characteristicId: that.data.indicate_id,//服務特徵值indicate
success: function (res) {
console.log('開啟notify', res.errMsg)
//監聽低功耗藍芽裝置的特徵值變化
wx.onBLECharacteristicValueChange(function (res) {
console.log('特徵值變化', that.arrayBufferToHexString(res.value));
})
//寫入資料
}
});
8.如何寫入資料
如何寫入資料呢,通過獲取到的write特徵值write_id注意:必須裝置的特徵值支援write才可以成功呼叫
let buffer = that.hexStringToArrayBuffer(ArrayBuffer);
//寫入資料
wx.writeBLECharacteristicValue({
deviceId: that.data.deviceId,//裝置deviceId
serviceId: that.data.service_id,//裝置service_id
characteristicId: that.data.write_id,//裝置write特徵值
value: buffer,//寫入資料
success: function (res) {
console.log('傳送資料:', res.errMsg)
}
});
hexStringToArrayBuffer:function (str) {
if(!str) {
return new ArrayBuffer(0);
}
var buffer = new ArrayBuffer(str.length);
let dataView = new DataView(buffer)
let ind = 0;
for (var i = 0, len = str.length; i < len; i += 2) {
let code = parseInt(str.substr(i, 2), 16)
dataView.setUint8(ind, code)
ind++
}
return buffer;
}
總結:有幾點特別需要注意,快拿出小本本1.IOS裡面藍芽狀態變化以後不能馬上開始搜尋,否則會搜尋不到裝置,必須要等待2秒以上2.開啟notify以後並不能馬上傳送訊息,藍芽裝置有個準備的過程,需要在setTimeout中延遲1秒以上才能傳送,否則會發送失敗
setTimeout(function () {
wx.writeBLECharacteristicValue({
deviceId: that.data.deviceId,
serviceId: that.data.service_id,
characteristicId: that.data.write_id,
value: buffer,
success: function (res) {
console.log('傳送資料:', res.errMsg)
}
});
}, 1100);
3.搜尋到裝置後記得釋放資源stopBluetoothDevicesDiscovery4.不需要使用藍芽的時候一定要關閉藍芽.wx.openBluetoothAdapter(OBJECT)和wx.closeBluetoothAdapter(OBJECT)成對使用