- wx.onBLECharacteristicValueChange偶现回调异常?
import modal from "@/utils/modal"; import { mapState } from "vuex"; import skeyTool from "@/utils/skeyTool"; import utils from "@/utils/utils"; export default { data() { return { connectTime: null, isIos: false, //ios特殊处理 isOpenBluebooth: false, isOpenSetting: false,//检测蓝牙未打开 跳转蓝牙设置页 userLocation: true,//判断Android机型下是否授权了地理位置 bleAdapterState: false,//蓝牙适配器状态 } }, mounted() { const systemInfo = wx.getSystemInfoSync(); if (/iPhone/.test(systemInfo.model)) { this.isIos = true; } //针对Android 部分机型需要地理位置授权 // wx.getSetting({ // success(res) { // if (!this.isIos && !res.authSetting['scope.userLocation']) { // wx.authorize({ // scope: 'scope.userLocation', // success(res) { // console.log('authorize', 'success'); // }, // fail() { // this.userLocation = false // console.log('authorize', 'fail'); // } // }) // } // } // }) }, methods: { //用户授权信息判断 getSetting() { let _that = this try { wx.getSetting({ withSubscriptions: true, success(res) { if (res.authSetting['scope.bluetooth']) { _that.initBlueTooth() } else { if (_that.$refs["setBlueRef"]) _that.$refs["setBlueRef"].hide(); modal.toast('您拒绝了蓝牙授权') _that.closeBlueTooth() } } }) } catch (error) { // console.log(error, 'getSetting'); throw error } }, // 打开手机蓝牙功能 setBlueTooth() { this.isOpenSetting = true //ios特殊处理 if (this.isIos) { try { wx.openAppAuthorizeSetting({ success: (res) => { this.isOpenBluebooth = true // console.log('您拒绝了蓝牙授权', res); if (this.$refs["setBlueRef"]) this.$refs["setBlueRef"].hide(); }, fail: (res) => { this.isOpenBluebooth = false }, }); } catch (error) { throw error } } else { //安卓手机打开蓝牙设置页面 try { wx.openSystemBluetoothSetting({ success: (data) => { this.isOpenBluebooth = true if (this.$refs["setBlueRef"]) this.$refs["setBlueRef"].hide(); }, fail: (err) => { this.isOpenBluebooth = false }, }); } catch (error) { throw error } } }, //---------------------step1------------------------ // 判断是否打开了蓝牙 async initBlueTooth() { let _that = this; await this.$refs["privacyModal"].show(); try { wx.openBluetoothAdapter({ mode: "central", success: function (res) { // 蓝牙已打开直接扫码 // 获取蓝牙适配器状态 _that.isOpenBluebooth = true _that.getBluetoothAdapter(); }, fail: function (res) { if (res.errCode == 10001) { uni.hideToast() if (_that.$refs["setBlueRef"]) return _that.$refs["setBlueRef"].show(); } _that.isOpenBluebooth = false _that.getSetting() }, }); } catch (error) { throw error } }, //-----------------------step1 end------------------- //------------------------step4------------------- //获取本机蓝牙适配器状态 //检测本机蓝牙是否可用 async getBluetoothAdapter() { let _that = this; try { //获取本机蓝牙适配器状态 wx.getBluetoothAdapterState({ success: function (res2) { // console.log('getBluetoothAdapterState', res2); //跳转到手机系统蓝牙设置页后回到此页面监听蓝牙是否打开 if (!res2.available && _that.isOpenSetting) { _that.isOpenSetting = false _that.bleAdapterState = false modal.toast('蓝牙未打开') return } if (res2.errMsg == "getBluetoothAdapterState:ok") { //搜寻附近的蓝牙设备 uni.showLoading({ title: "连接设备蓝牙中", mask: true, }); _that.startBluetoothDevices(); _that.isOpenSetting = false _that.bleAdapterState = true } }, fail: function (res2) { if (_that.isOpenSetting) uni.hideLoading(); }, }); } catch (error) { throw error // console.log(error, "getBluetoothAdapterState"); } }, //------------------------step4 end------------------- //------------------------- step5---------------------- //开始搜寻附近的蓝牙外围设备。 async startBluetoothDevices() { let _that = this; try { wx.startBluetoothDevicesDiscovery({ success: function (res) { if (res.errCode == 0) { // 监听寻找到新设备的事件 _that.onBluetoothDevice(); } console.log('startBluetoothDevicesDiscovery', res ); }, fail: function (res) { if (res.errCode < 0 && res.errMsg.includes('location')) { uni.hideToast() uni.hideLoading() modal.toast('请开启微信定位授权') return } console.log(res, 'startBluetoothDevicesDiscovery'); if (res.errCode > 1) modal.toast("连接失败"); // if (_that.connectTime) clearTimeout(_that.connectTime); // _that.connectTime = null; }, }); } catch (error) { // console.log(error, "startBluetoothDevicesDiscovery"); throw error } }, //------------------------- step5 end---------------- //----------------step6------------------- //监听寻找到新设备的事件 async onBluetoothDevice() { let _that = this; /** advertisData ArrayBuffer 当前蓝牙设备的广播数据段中的 ManufacturerData 数据段。 advertisServiceUUIDs Array.<string> 当前蓝牙设备的广播数据段中的 ServiceUUIDs 数据段 localName string 当前蓝牙设备的广播数据段中的 LocalName 数据段 serviceData Object 当前蓝牙设备的广播数据段中的 ServiceData 数据段 connectable boolean 当前蓝牙设备是否可连接( Android 8.0 以下不支持返回该值 ) */ try { wx.onBluetoothDeviceFound((res) => { res.devices.length && res.devices.forEach((device) => { //https://developers.weixin.qq.com/miniprogram/dev/api/device/bluetooth/wx.onBluetoothDeviceFound.html //这里要求柜机外围设备发送ManufacturerData 数据段 (advertisData ArrayBuffer数据类型) if (device.deviceId && device.advertisData && device.localName) { let deviceId = _that.hex2ab(device.advertisData); // 确保蓝牙设备中的advertisData字段有数据 if (deviceId) { //转换后多了一个P 字符? let new_sim = deviceId.substr( deviceId.length - 15, deviceId.length ); if (_that.sim == new_sim) { _that.deviceId = device.deviceId; //筛选完成,连接蓝牙 先连接蓝牙后停止搜寻附近的蓝牙设备 _that.stopBluetooth() setTimeout(() => { _that.createBLEConnectionFn(device.deviceId); }, 400) } } } }); }); } catch (error) { uni.hideLoading(); _that.stopBluetooth(); throw error } }, //------------------step6 end----------------------- //-----------------------step7----------------------- //连接蓝牙 async createBLEConnectionFn() { let _that = this; try { //连接蓝牙前先关闭已连接蓝牙 wx.createBLEConnection({ deviceId: _that.deviceId, success: function (res) { //获取连接设备的service服务 _that.getBLEDeviceServicesFn(_that.deviceId); uni.hideLoading(); uni.showToast({ title: "连接设备蓝牙成功", icon: "success", mask: true, }); _that.currentIndex = 1; _that.connectSuccess = true _that.connectFlag = true; //监听蓝牙关闭 wx.onBLEConnectionStateChange(function (res) { if (!res.connected) { uni.hideLoading() _that.connectFlag = false _that.isConnectIng = false _that.showLoading = false _that.connectSuccess = false // console.log('设备已断开蓝牙连接'); modal.toast("设备已断开蓝牙连接"); if (_that.$refs["paging"]) { _that.$refs["paging"].scrollToTop(); _that.$refs["paging"].complete(); } } }); }, fail: function (res) { console.log(res, 'createBLEConnection'); _that.stopBluetooth(); uni.hideLoading(); uni.showToast({ title: "连接蓝牙失败", icon: "error", mask: true, }); _that.connectSuccess = false if (_that.$refs["paging"]) { _that.$refs["paging"].scrollToTop(); _that.$refs["paging"].complete(); } }, }); } catch (error) { throw error } }, //----------------------step7 end-------------------------- //---------------------step8---------------------- //获取连接设备的service服务 async getBLEDeviceServicesFn(deviceId) { let _that = this; try { wx.getBLEDeviceServices({ deviceId: _that.deviceId, success: function (res) { for (let i = 0; i < res.services.length; i++) { if (res.services[i].isPrimary) { _that.serviceId = res.services[i].uuid; //获取连接设备的所有特征值 _that.getBLEDevice( deviceId, res.services[i].uuid ); } } }, fail: function (res) { // console.log("获取蓝牙失败", res); }, }); } catch (error) { throw error } }, //-----------------------step8 end---------------------- //-----------------------step 9--------------------- //获取连接设备的所有特征值 async getBLEDevice(deviceId, serviceId) { let _that = this; try { wx.getBLEDeviceCharacteristics({ deviceId: deviceId, serviceId: serviceId, success: function (res) { if (res.errCode == 0) { let characteristicId = res.characteristics; for (var i = 0; i < res.characteristics.length; i++) { if (res.characteristics[i].properties.write) { _that.characteristicId = characteristicId[i]["uuid"]; //确保设备能够写入数据 let str = "xx" + _that.sim + "ok"; _that.writeBLECharacteristic(str); //启用低功耗蓝牙设备特征值变化时的 notify 功能 setTimeout(() => { _that.notifyBLECharacteristic( deviceId, serviceId, characteristicId[i]["uuid"] ); }, 500); //设备详情 与终端确定 切换仅4G模式相当于清空WiFi配置 // 没有WiFi列表数据主动获取一次 if (_that.wifiList) { if (!_that.wifiList.length) _that.getWifiList() } // 设置详情页面通过蓝牙清空WiFi配置 if (_that.isClearWifiConf) { setTimeout(() => { _that.clearWrite() }, 500) } } } } else { // console.log("获取特征值失败"); // modal.toast("获取特征值失败"); } }, }); } catch (error) { throw error } }, //---------------------------step11------------------------ //启用低功耗蓝牙设备特征值变化时的 notify 功能 async notifyBLECharacteristic( deviceId, serviceId, characteristicId ) { let _that = this; try { wx.notifyBLECharacteristicValueChange({ deviceId: deviceId, serviceId: serviceId, characteristicId: characteristicId, state: true, success: function (res) { // console.log("启用低功耗蓝牙设备特征值变化时的 notify 功能", res); /*用来监听手机蓝牙设备的数据变化*/ _that.onBLECharacteristic(); _that.watchBleConnectionState() }, fail: function (res) { modal.toast('启用notify失败') }, }); } catch (error) { modal.toast('启用notify失败') // console.log(error, "notifyBLECharacteristicValueChange"); throw error } }, //--------------------------------ste11 end-------------------- //--------------------------------step12 ---------------------- onBLECharacteristic() { let _that = this; try { wx.onBLECharacteristicValueChange(function (res) { let flag = _that.hex2ab(res.value); //针对WiFi列表发送完成 console.log('通过hex2ab解析的数据', flag); console.log(res, res.value, 'onBLECharacteristic'); if (_that.sendIngWifi) { if (flag === "sendWifiListOK") { _that.connectFlag = true; uni.hideLoading() _that.stopSendWifi(); _that.sendIngWifi = false; _that.initWifiList(_that.wifiListStr); } else { let val = _that.str2abEmpty(res.value); _that.wifiListStr += val; console.log('通过str2abEmpty解析的数据', val,); } } //当前WiFi连接成功后会切换模式 if (flag == "WifiConnectOK") { _that.connectFlag = true; //控制设备连接WiFi成功 _that.isConnectIng = false } else if (flag == "WifiConnectFailed") { uni.showToast({ title: "WiFi连接失败", icon: "error", mask: true, }); _that.isConnectIng = false } }); } catch (error) { // console.log(error, 'onBLECharacteristic'); uni.hideLoading() modal.toast('监听notify失败') throw error } }, //--------------------------------step12end---------------------- // 获取要写入蓝牙设备的值 writeBLECharacteristic(val) { let _that = this; let buffer = _that.string2ArrayBuffer(val); try { wx.writeBLECharacteristicValue({ deviceId: _that.deviceId, serviceId: _that.serviceId, characteristicId: _that.characteristicId, value: buffer, // writeType: "write", success: function (res) { }, fail: function (err) { uni.hideLoading() if (_that.showLoading) _that.showLoading = false modal.toast("写入数据失败"); if (_that.$refs["paging"]) { _that.$refs["paging"].scrollToTop(); _that.$refs["paging"].complete(); } }, }); } catch (error) { uni.hideLoading() modal.toast("写入数据失败"); if (_that.showLoading) _that.showLoading = false; throw error } }, async stopBluetooth() { let _that = this try { wx.stopBluetoothDevicesDiscovery({ success: (result) => { if (_that.$refs["paging"]) { _that.$refs['paging'].scrollToTop() _that.$refs["paging"].complete() } }, fail: (error) => { console.log("停止搜寻附近的蓝牙外围设备失败", error); }, }); } catch (error) { // console.log('stopBluetooth', error); throw error } }, // 字符串转ArrayBuffer string2ArrayBuffer(str) { try { var bytes = new Array(); var len, c; len = str.length; for (var i = 0; i < len; i++) { c = str.charCodeAt(i); if (c >= 0x010000 && c <= 0x10ffff) { bytes.push(((c >> 18) & 0x07) | 0xf0); bytes.push(((c >> 12) & 0x3f) | 0x80); bytes.push(((c >> 6) & 0x3f) | 0x80); bytes.push((c & 0x3f) | 0x80); } else if (c >= 0x000800 && c <= 0x00ffff) { bytes.push(((c >> 12) & 0x0f) | 0xe0); bytes.push(((c >> 6) & 0x3f) | 0x80); bytes.push((c & 0x3f) | 0x80); } else if (c >= 0x000080 && c <= 0x0007ff) { bytes.push(((c >> 6) & 0x1f) | 0xc0); bytes.push((c & 0x3f) | 0x80); } else { bytes.push(c & 0xff); } } var array = new Int8Array(bytes.length); for (var i in bytes) { array[i] = bytes[i]; } return array.buffer; } catch (error) { uni.hideLoading() modal.toast('解析ArrayBuffer失败~') // console.log(error, 'string2ArrayBuffer'); throw error } }, //ArrayBuffer 转字符串 str2ab(arrayBuffer) { try { let unit8Arr = new Uint8Array(arrayBuffer); let encodedString = String.fromCharCode.apply(null, unit8Arr); let decodedString = decodeURIComponent(escape(encodedString)); //没有这一步中文会乱码 return decodedString; } catch (error) { //抛出异常不管了 // console.log(error, 'str2ab'); uni.hideLoading() modal.toast('解析数据失败~str2ab') return false; } }, hex2ab(str) { try { return String.fromCharCode.apply(null, new Uint8Array(str)); } catch (error) { uni.hideLoading() modal.toast('解析数据失败~hex2ab') // console.log(error, 'hex2ab'); throw error } }, //16进制ArrayBuffer 转字符串 不去掉 \n str2abEmpty(arrayBuffer) { try { let str = String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)); let ret = str.replace(/\n/g, "/n"); //将\n标记为/n return ret; } catch (error) { uni.hideLoading() modal.toast('解析数据失败~') throw error } }, // 16进制(byte格式)转字符串 hexToString(str) { try { let res = str.replace(/\\x/g, "%"); let result = decodeURIComponent(res, "utf-8"); return result; } catch (error) { uni.hideLoading() modal.toast('解析WiFi数据失败') setTimeout(() => { this.currentIndex = 0 }, 1000); this.$store.commit('submitErrorLog', { error_type: "handlerError", url: 'bluebooth.hexToString', param: { wifiListStr: this.wifiListStr }, timeout: '0', epukey: skeyTool.getSkey(), datetime: utils.formatTime(new Date()), err_code: '200' }) throw error } }, async closeBlueTooth() { try { if (this.connectFlag) { wx.closeBLEConnection({ deviceId: this.deviceId, success(res) { console.log('closeBLEConnection', res); }, fail(err) { console.log(err, 'closeBlueTooth', 'fail') }, }) } } catch (error) { throw error } }, watchBleConnectionState() { try { wx.onBLEConnectionStateChange((res) => { if (!res?.connected) { uni.hideLoading() modal.toast('设备已断开蓝牙连接') } }) } catch (error) { throw error } }, //清空倒计时、重置蓝牙功能相关数据配置 //关闭蓝牙相关操作 handlerCloese() { //关闭蓝牙模块。 wx.closeBluetoothAdapter({ success: (res) => { console.log('closeBluetoothAdapter', res); }, fail: (err) => { console.log('closeBluetoothAdapter', err); } }); // 移除搜索到新设备的事件的全部监听函数 uni.hideLoading(); uni.hideToast(); } }, beforeDestroy() { this.handlerCloese() }, //针对蓝牙打开手机自带蓝牙设置页面 返回到当前页面 特殊处理 onShow() { setTimeout(() => { if (this.isOpenSetting) this.getBluetoothAdapter() }, 500) }, computed: { ...mapState(["privacyFlag", 'needPrivacy']), }, }[图片] 安卓端、iOS端 多次写入数据wx.writeBLECharacteristicValue 偶现wx.onBLECharacteristicValueChange无回调 有时候收到第一条数据后后面无回调 有时候是接收到了硬件方发送的一半数据 硬件方始终是20字节 我这边也没有超过20字节 这里的wifiListStr我会在设备端发送给我sendWifiListOK之后重新解析一遍 当前这个代码是当做一个mixins使用的 frequency signal 是硬件发送的自定义数据(第一条数据),后面就没执行了也没报错 返回上个页面关闭了蓝牙适配器
09-05 - ucharts的tooltips功能失效 基础库有bug?
[图片] [图片]uchart的原生工具 版本v2.5.0-20230101 、v2.4.5-20221130 在基础库版本2.24.7上正常, 在3.3.4 、3.4.3 等多个版本基础库上不能显示
04-28 - 订单中心页在tabbar且是当做组件使用,改如何设置订单中心页path?
[图片]如图,用户登录后,获取用户权限相关数据,加载对应tabbar(每个tabbar当做组件使用的),所有tabbar都是在同一个路径下,订单组件是所有订单类型的入口(数据列表展示),通过点击不同类型的列表中的数据跳转到对应的详情页,这种情况怎么设置订单中心页path(现在没有版本迭代的需求,后台设置的是这个主页面的路径),不同类型订单,展示的结果不一样,有的是订单相关信息(下单时间,下单地点,订单号,订单金额,商品信息等),有的是订单状态、订单时间信息(没有订单金额等信息),后台设置的是当前页面的路径(切换tabbar路径保持不变),但是[图片]
2022-12-22