文章來源地址http://www.zghlxwxcb.cn/news/detail-530450.html
import {
SERVICEID,
NOTIFYID,
WRITEID,
BLUETOOTH_MESSAGE,
OPERATE_PROCESS
} from "./config.js"
import {
openBluetoothAdapterFailCallback,
onBluetoothAdapterStateChangeCallback,
onBluetoothDeviceFoundCallback,
getBluetoothAdapterStateSuccessCallback,
getBluetoothAdapterStateFailCallback,
createBLEConnectioSuccessCallback,
createBLEConnectioFailCallback,
onBLEConnectionStateChangeCallback,
onBLECharacteristicValueChangeCallback,
initStoreState,
notifyBLECharacteristicValueChangeFailCallback
} from "./tool.js"
import {
hexStringToArrayBuffer,
sleep,
getBufferArrayBy20,
arrayBufferToHexString,
setCommunicationListUtil,
getNowTime,
getMac,
filterDevices,
filterDevicesByRe,
unique,
showModalByMethod
} from "./utils.js"
let util = require('@/static/utils/utils.js');
import vm from "@/main.js"
//正常藍(lán)牙流程開始
export let bluetoothStart = () => {
getBluetoothAdapterState();
}
export let onBluetoothAdapterStateChange = () => {
//如果藍(lán)牙打開-關(guān)閉-再打開-監(jiān)聽不到?
uni.onBluetoothAdapterStateChange(async (res) => {
bluetoothExecByAdapterStatus(res);
})
}
//根據(jù)藍(lán)牙適配器的狀態(tài)、是否正在搜索設(shè)備執(zhí)行不同的操作流程
export let bluetoothExecByAdapterStatus = (res) => {
console.log("藍(lán)牙適配器狀態(tài)", res);
if (!res.available) {
util.showModal("藍(lán)牙適配器不可用,請打開藍(lán)牙");
} else {
if (!res.discovering && !vm.isNormalDiscoveryStatus) { // 防止正常停止搜索的時候會觸發(fā)這個條件
//如果前面已經(jīng)搜索過藍(lán)牙,則不需要再次搜索
vm.$u.vuex("isImmediateWhitePackage", false); //防止打開手機藍(lán)牙后并連接成功后,直接讓藍(lán)牙發(fā)送指令
if (vm.isBluetoothDiscovery) {
getBluetoothDevices();
} else {
startAndStopbluetoothDevicesDiscovery();
}
}
}
}
//獲取在藍(lán)牙模塊生效期間所有已發(fā)現(xiàn)的藍(lán)牙設(shè)備。包括已經(jīng)和本機處于連接狀態(tài)的設(shè)備
export let getBluetoothDevices = () => {
uni.getBluetoothDevices({
success(res) {
let devices = res.devices;
let devicesList = filterDevices(res.devices, vm.currentBike);
if (devicesList.length > 0) {
vm.$u.vuex('bluetoothDevice', devicesList[0])
vm.$u.vuex('connectCount', 0)
createBLEConnection(devicesList[0])
} else {
startAndStopbluetoothDevicesDiscovery();
}
}
})
}
//打開藍(lán)牙設(shè)備并監(jiān)聽藍(lán)牙設(shè)備
export let openAndOnBluetoothAdapter = () => {
vm.$u.vuex("bluetoothContent", "正在初始化藍(lán)牙");
uni.openBluetoothAdapter({
success(res) {
console.log("打開藍(lán)牙適配器成功");
startAndStopbluetoothDevicesDiscovery();
},
fail(res) {
console.log("打開藍(lán)牙設(shè)備器失敗", res)
console.log(res.errMsg == "openBluetoothAdapter:fail already opened")
//藍(lán)牙適配器已經(jīng)打開
if (res.errMsg == "openBluetoothAdapter:fail already opened") {
startAndStopbluetoothDevicesDiscovery();
} else {
console.log("打開藍(lán)牙適配器失敗:", BLUETOOTH_MESSAGE[res.errCode]);
util.showModal("藍(lán)牙適配器不可用,請打開藍(lán)牙或微信APP開啟藍(lán)牙權(quán)限");
openBluetoothAdapterFailCallback();
}
},
complete() {
onBluetoothAdapterStateChange();
}
})
}
//開始和停止藍(lán)牙搜索
export let startAndStopbluetoothDevicesDiscovery = () => {
//1、關(guān)閉藍(lán)牙-殺掉進(jìn)程,開啟藍(lán)牙不會重新連接,沒有監(jiān)聽搜索到的設(shè)備
onBluetoothDeviceFound();
//2、接步驟1,再關(guān)閉,再開發(fā)藍(lán)牙,連接成功,但是不會觸發(fā)藍(lán)牙連接
onBLEConnectionStateChange();
vm.$u.vuex('bluetoothContent', '正在搜索藍(lán)牙設(shè)備');
vm.$u.vuex("isBluetoothDiscovery", true);
vm.$u.vuex("bluetoothDevice", {}); //清空
//如果60s都還未搜索到藍(lán)牙,提示未搜索到,提示藍(lán)牙不在可搜索范圍內(nèi),
let timer = setTimeout(() => {
clearTimeout(timer);
//沒有找到設(shè)備并且定時器還在
if (vm.validatenull(vm.bluetoothDevice)) {
util.showModal('藍(lán)牙不在可搜索范圍內(nèi)');
stopBluetoothDevicesDiscovery();
}
}, 10000);
vm.$u.vuex('blueToothSearchTimer', timer);
uni.startBluetoothDevicesDiscovery({
services: [], //添加了SERVICEID搜索不到藍(lán)牙
allowDuplicatesKey: true,
powerLevel: 'high',
success() {
console.log("開始藍(lán)牙搜索成功");
},
fail(res) {
console.log(res);
util.showModal('開始藍(lán)牙搜索失敗');
console.log("開始藍(lán)牙搜索失敗:", BLUETOOTH_MESSAGE[res.errCode]);
}
})
}
export let stopBluetoothDevicesDiscovery = () => {
uni.stopBluetoothDevicesDiscovery({
success() {
console.log("停止藍(lán)牙搜索成功");
},
fail(res) {
console.log("停止藍(lán)牙搜索失敗:", BLUETOOTH_MESSAGE[res.errCode]);
},
complete() {
vm.$u.vuex("isNormalDiscoveryStatus", true);
setTimeout(()=>{
vm.$u.vuex("isNormalDiscoveryStatus", false);
},1000)
}
})
}
//監(jiān)聽尋找到新設(shè)備的事件
export let onBluetoothDeviceFound = () => {
uni.onBluetoothDeviceFound((res) => {
//搜索到的藍(lán)牙設(shè)備并唯一
let devices = filterDevices(res.devices, vm.currentBike);
if (devices.length) {
console.log("搜索到的目標(biāo)設(shè)備", devices)
vm.$u.vuex('bluetoothDevice', devices[0])
clearTimeout(vm.blueToothSearchTimer);
vm.$u.vuex('connectCount', 0)
createBLEConnection(devices[0]);
stopBluetoothDevicesDiscovery();
}
})
}
export let getBluetoothAdapterState = () => {
uni.getBluetoothAdapterState({
success(res) {
bluetoothExecByAdapterStatus(res);
},
fail(res) {
console.log("獲取藍(lán)牙適配器狀態(tài)失敗:", BLUETOOTH_MESSAGE[res.errCode]);
openAndOnBluetoothAdapter();
util.showModal('藍(lán)牙適配器不可用,請打開藍(lán)牙');
}
})
}
//ios必須要執(zhí)行
let getBLEDeviceServices = (device) => {
uni.getBLEDeviceServices({
deviceId: device.deviceId,
success(res) {
console.log(`獲取${device.deviceId}服務(wù)成功`, res);
getBLEDeviceCharacteristics(device);
},
fail(res) {
console.log(`獲取${device.deviceId}服務(wù)失敗:`, BLUETOOTH_MESSAGE[res.errCode]);
getBLEDeviceCharacteristics(device);
}
})
}
export let createBLEConnection = (device) => {
console.log("正在連接藍(lán)牙")
vm.$u.vuex('bluetoothContent', '正在連接藍(lán)牙設(shè)備');
//如果當(dāng)前狀態(tài)沒有連接,只去連接藍(lán)牙
if (!vm.isConnected && !vm.validatenull(vm.bluetoothDevice)) {
uni.createBLEConnection({
deviceId: device.deviceId,
success(res) {
console.log(`與藍(lán)牙設(shè)備${device.name}創(chuàng)建連接成功`, res);
getBLEDeviceServices(device);
createBLEConnectioSuccessCallback();
},
fail(res) {
console.log(res)
if(res.errCode == 10001) return;//如果是藍(lán)牙設(shè)配器沒有打開,則直接退出連接
if (vm.connectCount < 4) {
createBLEConnection(device);
let connectCount = vm.connectCount;
let newConnectCount = connectCount + 1;
vm.$u.vuex('connectCount', newConnectCount);
} else {
util.showModal('藍(lán)牙連接失敗');
}
}
})
}
}
//ios必須要執(zhí)行
let getBLEDeviceCharacteristics = (device) => {
uni.getBLEDeviceCharacteristics({
deviceId: device.deviceId,
serviceId: SERVICEID,
success: function(res) {
console.log(`獲取${device.deviceId}特征值成功`, res);
notifyAndOnBLECharacteristicValueChange(device);
},
fail: function(res) {
console.log(`獲取${device.deviceId}特征值失敗`, res);
},
})
}
export let onBLEConnectionStateChange = () => {
uni.onBLEConnectionStateChange((res) => {
console.log("監(jiān)聽藍(lán)牙是否斷開", res);
if(vm.lastConnectionStatus == res.connected){
let bluetoothDisconnectedCount = vm.bluetoothDisconnectedCount;
let newBluetoothDisconnectedCount = bluetoothDisconnectedCount+1;
vm.$u.vuex("bluetoothDisconnectedCount",newBluetoothDisconnectedCount);
}else{
vm.$u.vuex("bluetoothDisconnectedCount",0);
}
vm.$u.vuex("isConnected", res.connected);
if (!res.connected && !vm.isNormalBluetoothDisconnect && vm.bluetoothDisconnectedCount < 2) { //當(dāng)前檢測到時異常斷開狀態(tài),則進(jìn)行重連操作,連接不上,還是會觸發(fā)這個監(jiān)聽
vm.$u.vuex('connectCount', 0);
createBLEConnection(vm.bluetoothDevice);
}
vm.$u.vuex("lastConnectionStatus", res.connected);
onBLEConnectionStateChangeCallback(res);
})
}
//開始并且監(jiān)聽特征值的變化
export let notifyAndOnBLECharacteristicValueChange = (device) => {
//防止沒有更換狀態(tài)
uni.notifyBLECharacteristicValueChange({
state: true,
deviceId: device.deviceId,
serviceId: SERVICEID,
characteristicId: NOTIFYID,
success(res) {
console.log("開啟notify通知模式成功", res);
uni.onBLECharacteristicValueChange((res) => {
console.log("監(jiān)聽特征值", res);
clearTimeout(vm.notifyTimerId);
//關(guān)閉藍(lán)牙連接
onBLECharacteristicValueChangeCallback(device, res);
})
},
fail(res) {
notifyBLECharacteristicValueChangeFailCallback(device, res);
console.log("開啟notify通知模式失敗:", BLUETOOTH_MESSAGE[res.errCode]);
}
})
}
let writeBLECharacteristicValue = (device, value) => {
console.log("寫入數(shù)據(jù)", arrayBufferToHexString(value));
uni.writeBLECharacteristicValue({
deviceId: device.deviceId,
serviceId: SERVICEID,
characteristicId: WRITEID,
value,
success(res) {
console.log("寫入數(shù)據(jù)成功", res);
//判斷是否是最后一包,如果是最后一包,則開啟通訊計時器
},
fail(res) {
console.log("寫入數(shù)據(jù)失敗", BLUETOOTH_MESSAGE[res.errCode]);
console.log("寫入數(shù)據(jù)失敗", res);
util.showModal("寫入數(shù)據(jù)失敗");
}
})
}
export let closeBLEConnection = (device, callback = () => {}) => {
vm.$u.vuex("isNormalBluetoothDisconnect", true);
uni.closeBLEConnection({
deviceId: device.deviceId,
success() {
console.log("關(guān)閉藍(lán)牙連接成功");
},
fail(res) {
console.log("關(guān)閉藍(lán)牙連接失敗", res);
console.log("關(guān)閉藍(lán)牙連接失敗", BLUETOOTH_MESSAGE[res.errCode]);
},
complete() {
setTimeout(() => {
vm.$u.vuex("isNormalBluetoothDisconnect", false);
}, 1000)
callback();
}
})
}
export let closeBluetoothAdapter = (callback) => {
return new Promise((resolve, reject) => {
uni.closeBluetoothAdapter({
success() {
console.log("關(guān)閉藍(lán)牙適配器成功");
},
fail(res) {
console.log("關(guān)閉藍(lán)牙適配器失?。?, BLUETOOTH_MESSAGE[res.errCode]);
},
complete() {
callback();
}
})
})
}
//不分包寫數(shù)據(jù)
export let writeDataToDevice = (device, data) => {
console.log("發(fā)送數(shù)據(jù)", data);
vm.$u.vuex("bluetoothContent", "正在發(fā)送指令");
let allBuffer = hexStringToArrayBuffer(data);
writeBLECharacteristicValue(device, allBuffer);
}
//分包寫數(shù)據(jù)
export let writeDataToDeviceBySubPackage = (data) => {
vm.$u.vuex("commandMessage", '');
vm.$u.vuex("bluetoothContent", `正在發(fā)送${vm.commandName}指令`);
let bufferArray = getBufferArrayBy20(data);
console.log('bufferArray.length', bufferArray.length);
for (let i = 0; i < bufferArray.length; i++) {
//sleep(1); //同步延遲1ms
writeBLECharacteristicValue(bufferArray[i], i == bufferArray.length - 1);
}
// let allBuffer = hexStringToArrayBuffer(data);
// writeBLECharacteristicValue(allBuffer);
}
export let getConnectedBluetoothDevices = (callback) => {
uni.getConnectedBluetoothDevices({
services: [SERVICEID],
success(res) {
console.log("獲取連接的藍(lán)牙設(shè)備成功", res);
callback(res.devices)
},
fail(res) {
console.log("獲取連接的藍(lán)牙設(shè)備失敗", res);
callback([]);
},
complete() {
}
})
}
文章來源:http://www.zghlxwxcb.cn/news/detail-530450.html
到了這里,關(guān)于微信小程序藍(lán)牙流程及代碼的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!