一、開發(fā)流程
-
流程圖:流程圖作者原文章

-
實(shí)現(xiàn)模塊順序
1.1初始化藍(lán)牙模塊(打開藍(lán)牙適配器)
初次加載,自動獲取獲取系統(tǒng)信息,檢查藍(lán)牙適配器是否可用
初始化藍(lán)牙,提示打開GPS和藍(lán)牙,開始自動搜索藍(lán)牙設(shè)備


1.2搜索周圍藍(lán)牙
開始搜索藍(lán)牙設(shè)備,定時1s獲取搜索到的設(shè)備
把搜索到的設(shè)備保存在一個數(shù)組內(nèi),渲染在頁面

1.3監(jiān)聽搜索設(shè)備
監(jiān)聽5s后停止搜索,并把新設(shè)備push到數(shù)組進(jìn)行渲染
顯示設(shè)備名稱和連接按鈕
1.4連接目標(biāo)設(shè)備
點(diǎn)擊連接按鈕創(chuàng)建連接,獲取設(shè)備信息
連接成功停止搜索,獲取已連接藍(lán)牙的服務(wù)

1.5獲取服務(wù)、特征值
連接成功獲取藍(lán)牙設(shè)備服務(wù)和特征值(是否能讀寫)

1.6開啟notify,監(jiān)聽特征值變化
開啟監(jiān)聽功能,發(fā)送指令后接收設(shè)備響應(yīng)的數(shù)據(jù)

1.7發(fā)送指令、讀寫數(shù)據(jù)
設(shè)備特征值中寫入數(shù)據(jù),必須設(shè)備的特征支持 write
ArrayBuffer轉(zhuǎn)16進(jìn)制字符串

1.8斷開連接
清空設(shè)備名、設(shè)備id,關(guān)閉藍(lán)牙模塊

二、實(shí)現(xiàn)模塊代碼
-
初始化藍(lán)牙模塊(打開藍(lán)牙適配器)
openBluetoothAdapter() {
let that = this;
uni.openBluetoothAdapter({ //初始化藍(lán)牙模塊
success(res) {
console.log(res, '初始化藍(lán)牙成功');
uni.onBluetoothAdapterStateChange((res) => { // 監(jiān)聽藍(lán)牙適配器狀態(tài)變化
if (!res.available) {
uni.showModal({
title: '溫馨提示',
content: '藍(lán)牙適配器不可用,請重新啟動',
showCancel: false
});
}
});
that.searchBlue(); //開始搜索
},
fail(res) {
console.log(res, '初始化藍(lán)牙失敗');
uni.showToast({
title: '請檢查手機(jī)藍(lán)牙是否打開',
icon: 'none'
});
}
});
},
-
開始搜索周圍藍(lán)牙
searchBlue() {
let that = this;
uni.startBluetoothDevicesDiscovery({
// services: [],
success: (res) => {
console.log(res, "開始搜索設(shè)備");
uni.showLoading({
title: '正在搜索設(shè)備'
});
that.getBluetoothDevices();
},
fail: (res) => {
console.log(res, '搜索失敗');
uni.showToast({
title: '搜索藍(lán)牙設(shè)備失敗!',
icon: 'none'
});
}
});
},
-
獲取搜索到的設(shè)備
getBluetoothDevices() {
let that = this;
setTimeout(() => {
uni.getBluetoothDevices({ // 獲取搜索到的設(shè)備
success: (res) => {
console.log(res, "搜索到的設(shè)備");
let devicesListArr = [];
if (res.devices.length > 0) {
uni.hideLoading(res.devices);
res.devices.forEach((device) => {
if (!device.name && !device.localName) {
return;
} else if (device.name.substring(0, 2) == 'AA') {
devicesListArr.push(device);
that.devicesList = devicesListArr;
that.isHideList = true;
that.watchBluetoothFound(); // 監(jiān)聽搜索到的新設(shè)備
} else {
return
}
});
} else {
uni.hideLoading();
uni.showModal({
title: '溫馨提示',
content: '無法搜索到藍(lán)牙設(shè)備,請重試',
showCancel: false
});
uni.closeBluetoothAdapter({ //關(guān)閉藍(lán)牙模塊
success: (res) => {
console.log(res, "關(guān)閉藍(lán)牙模塊");
}
});
}
}
});
}, 2000);
},
-
監(jiān)聽搜索設(shè)備
watchBluetoothFound() {
let that = this;
uni.onBluetoothDeviceFound(function(res) { // 監(jiān)聽搜索到的新設(shè)備
if (String(res.devices.name).substring(0, 2) == 'AA') {
devicesListArr.push(res.devices);
that.devicesList = devicesListArr;
console.log(res.devices, "監(jiān)聽新設(shè)備");
}
})
},
-
連接目標(biāo)設(shè)備
createBLEConnection(e) {
let that = this;
let deviceId = e.currentTarget.dataset.id;
let connectName = e.currentTarget.dataset.name;
console.log("正在連接" + connectName);
uni.showLoading({
title: '連接中...'
});
uni.createBLEConnection({
deviceId,
success: (res) => {
uni.hideLoading();
that.stopBluetoothDevicesDiscovery(); // 連接成功,停止搜索
console.log(res, "連接成功");
if (res.errCode == 0) {
that.deviceId = deviceId;
that.connectName = connectName;
that.isHideConnect = true;
that.getBLEDeviceServices(deviceId); // 獲取服務(wù)
} else if (res.errCode == 10012) {
uni.showToast({
title: '連接超時,請重試!'
});
}
},
fail(error) {
uni.hideLoading();
console.log(error, '連接失敗');
uni.showToast({
title: '連接失?。?
});
}
});
},
-
獲取設(shè)備所有服務(wù)
getBLEDeviceServices(deviceId) {
let that = this;
// let serviceId;
uni.getBLEDeviceServices({
deviceId,
success: (res) => {
console.log(res.services, "獲取設(shè)備服務(wù)");
for (let i = 0; i < res.services.length; i++) {
let isPrimary = res.services[i].isPrimary
let uuid = res.services[i].uuid.substring(4, 8) == 'FE60'
if (isPrimary && uuid) {
this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
return
}
}
}
});
},
-
獲取特征值
getBLEDeviceCharacteristics(deviceId, serviceId) {
let that = this;
uni.getBLEDeviceCharacteristics({
deviceId,
serviceId,
success: (res) => {
console.log(res.characteristics, '獲取特征值成功')
let characteristicId = res.characteristics[0].uuid;
let writeNews = {
deviceId,
serviceId,
characteristicId
};
that.writeNews = writeNews;
let notifyId = res.characteristics[1].uuid;
that.notifyBLECharacteristicValueChange(serviceId, notifyId);
},
fail(err) {
console.log(err, "獲取失敗");
}
});
},
-
啟用監(jiān)聽特征值變化
notifyBLECharacteristicValueChange(serviceId, characteristicId) {
let that = this;
uni.notifyBLECharacteristicValueChange({ // 啟用監(jiān)聽設(shè)備特征值變化
type: 'notification',
state: true, // 啟用 notify 功能
deviceId: that.writeNews.deviceId,
serviceId,
characteristicId,
success(res) {
console.log(res, '啟用監(jiān)聽成功');
that.onBLECharacteristicValueChange()
},
fail: (err) => {
console.log(err, "啟用監(jiān)聽失敗");
}
});
},
-
監(jiān)聽特征值變化
onBLECharacteristicValueChange() {
let that = this;
uni.onBLECharacteristicValueChange(res => {
console.log(res, '監(jiān)聽變化成功');
let resHex = that.ab2hex(res.value)
console.log('從機(jī)響應(yīng)的數(shù)據(jù):', resHex)
})
},
-
發(fā)送、讀取數(shù)據(jù)
writeBLECharacteristicValue(order) { // 向藍(lán)牙設(shè)備發(fā)送一個0x00的16進(jìn)制數(shù)據(jù)
let that = this;
let msg = order;
let buffer = new ArrayBuffer(msg.length / 2); // 定義 buffer 長度
let dataView = new DataView(buffer); // 從二進(jìn)制ArrayBuffer對象中讀寫多種數(shù)值類型
let ind = 0;
for (var i = 0, len = msg.length; i < len; i += 2) {
let code = parseInt(msg.substr(i, 2), 16)
dataView.setUint8(ind, code)
ind++
}
console.log('主機(jī)寫入的指令:', that.ab2hex(buffer));
uni.writeBLECharacteristicValue({
deviceId: that.writeNews.deviceId,
serviceId: that.writeNews.serviceId,
characteristicId: that.writeNews.characteristicId,
value: buffer,
writeType: 'writeNoResponse',
success: (res) => {
console.log(res, '寫入數(shù)據(jù)成功');
that.onBLECharacteristicValueChange()
},
fail: (err) => {
console.log(err);
}
})
},
-
斷開連接
closeBLEConnection() {
let that = this;
console.log(that);
uni.closeBLEConnection({
deviceId: this.deviceId,
success: () => {
uni.showToast({
title: '已斷開連接'
});
that.deviceId = '';
that.connectName = '';
that.isHideConnect = false;
}
});
that.closeBluetoothAdapter();
},
-
關(guān)閉藍(lán)牙模塊
closeBluetoothAdapter() {
let that = this;
uni.closeBluetoothAdapter({
success: (res) => {
console.log(res);
that.devicesList = [];
that.isHideList = false;
that.isHideConnect = false;
}
});
},
-
停止搜索設(shè)備
stopBluetoothDevicesDiscovery() {
uni.stopBluetoothDevicesDiscovery({
success(res) {
console.log(res);
}
});
},
-
ArrayBuffer轉(zhuǎn)16進(jìn)制字符串
ab2hex(buffer) {
var hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function(bit) {
return ('00' + bit.toString(16)).slice(-2);
});
return hexArr.join('');
},
三、遇到的問題以及解決
問題1:onBLECharacteristicValueChange監(jiān)聽不到響應(yīng)數(shù)據(jù)?
解決方法:
1、給onBLECharacteristicValueChange添加延時器;
2、給notifyBLECharacteristicValueChange添加type: 'notification';
3、給writeBLECharacteristicValue添加 writeType: 'writeNoResponse';
4、更換手機(jī)設(shè)備:Android、IOS設(shè)備;
5、查看特征值:read、notify、write、writeNoResponse;
6、分包發(fā)送:藍(lán)牙BLE最大支持20個字節(jié)發(fā)送,因此超過20個字節(jié)需要分包發(fā)送;文章來源:http://www.zghlxwxcb.cn/news/detail-482615.html
7、遵循硬件文檔:使用指定服務(wù),寫入、接收分別使用的特征值(成功解決);文章來源地址http://www.zghlxwxcb.cn/news/detail-482615.html
到了這里,關(guān)于微信小程序藍(lán)牙功能全套開發(fā)流程介紹的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!