問題:
1.小程序藍牙搜索能不能搜到手機設備
2.如何判斷藍牙是否打開
3.搜索指定設備
4.開發者工具和 Android 上獲取到的deviceId爲設備 MAC 地址,iOS 上則爲設備 uuid。所以deviceId不能硬編碼到代碼中,如何鏈接藍牙
5.serviceId如何去選擇
6.characteristic(特徵值)幹嗎的,怎麼用
7.開啓notify
8.如何寫入數據
--------------------- android
原文:https://blog.csdn.net/caohoucheng/article/details/81633822ios
問題:
最近作了一個涉及到藍牙模塊小程序,作一下總結,爲本身的成長作一份記錄,若是能幫到你們的話是再好不過的了;小程序
1.小程序藍牙搜索能不能搜到手機設備
2.如何判斷藍牙是否打開
3.搜索指定設備
4.開發者工具和 Android 上獲取到的deviceId爲設備 MAC 地址,iOS 上則爲設備 uuid。所以deviceId不能硬編碼到代碼中,
如何鏈接藍牙
5.設備服務全部 service(服務) 如何去選擇
6.設備characteristic(特徵值)幹嗎的,怎麼用
7.開啓notify
8.寫入數據app
1.小程序藍牙搜索能不能搜到手機設備
搜不到!!!
小程序藍牙只支持BLE低功耗藍牙
什麼是低功耗藍牙設備呢?百度一下,你就知道(^__^) 嘻嘻ide
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:關閉藍牙模塊,使其進入未初始化狀態。調用該方法將斷開全部已創建的連接並釋放系統資源;ui
3.搜索指定設備
wx.startBluetoothDevicesDiscovery(OBJECT)開始搜尋附近的藍牙外圍設備
wx.getBluetoothDevices(OBJECT)獲取在小程序藍牙模塊生效期間全部已發現的藍牙設備
wx.onBluetoothDeviceFound(CALLBACK) 監聽尋找到新設備的事件編碼
注意:搜索藍牙wx.startBluetoothDevicesDiscovery(OBJECT)操做比較耗費系統資源,在搜索並鏈接到設備後調用 wx.stopBluetoothDevicesDiscovery(OBJECT) 方法中止搜索。.net
//開始搜索藍牙
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 prototype
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.搜索到設備後記得釋放資源stopBluetoothDevicesDiscovery 4.不須要使用藍牙的時候必定要關閉藍牙.wx.openBluetoothAdapter(OBJECT)和wx.closeBluetoothAdapter(OBJECT)成對使用--------------------- 做者:Cc_JoJo 來源:CSDN 原文:https://blog.csdn.net/caohoucheng/article/details/81633822 版權聲明:本文爲博主原創文章,轉載請附上博文連接!