前言
目前公司Vue H5项目,用webview打包成APP,现产品提出这样打包出来的app运行较慢,需要用uniapp方式(即使用HBuilder编辑器来打包H5)来打包,那需要的基座就不是安卓的基座而是uniapp的基座,而H5项目实现手机扫描功能就需要调用uniapp的基座的方法。
需求&流程说明
Vue2 开发的移动端项目(H5项目及ipad端项目),需要连接蓝牙设备打印
需求说明:
1、点击打印按钮时,先判断当前设备是否已连接过蓝牙(即是否存在蓝牙设备ID)
a、若已连接过:直接调用打印配置(即:type:bluetoothPrint)
b、若未连接过:
1、先获取当前设备的所有蓝牙list(即:type:getBluetoothList)
2、选中设备后调用蓝牙连接(即:type:connBluetooth)
3、连接成功后存储已连接的设备ID(即选中的设备)
具体步骤
一、Uniapp Webview 源码
<template> <view> <web-view :src="src" @message="showMessage"></web-view> </view></template><script>export default { data() { return { src: 'http://******/', // H5项目地址 qrCodeWv: null, devices: [], currDev: null, connId: '', } }, onReady() { // #ifdef APP-PLUS let currentWebview = this.$scope.$getAppWebview() setTimeout(() => { this.wv = currentWebview.children()[0] this.qrCodeWv = currentWebview.children()[0] this.wv.setStyle({ scalable: true }) }, 1000) // #endif }, methods: { showMessage(event) { if (event.detail.data && event.detail.data.length > 0) { let dataInfo = event.detail.data[0] console.log(dataInfo) let type = dataInfo.type if (type === 'getBluetoothList') { this.getBluetoothList() } if (type === 'connBluetooth') { console.log(dataInfo.params) let args = dataInfo.params; let deviceId = args.deviceId; let device = this.devices.find((item) => { return item.deviceId == deviceId; }) console.log(device) this.connBluetooth(device) } if (type === 'bluetoothPrint') { let args = dataInfo.params; let deviceId = args.deviceId; let command = args.command; let device = this.devices.find((item) => { return item.deviceId == deviceId; }) //当设备没有连接时需要重新连接设备 if (this.connId == '') { this.initBluetoothList(); this.connBluetooth(device); } let serviceId = this.currDev.services[0].serviceId; let characteristicId = this.currDev.services[0].characteristicId; this.senBlData(deviceId, serviceId, characteristicId, command); } } }, // 获取蓝牙设备list getBluetoothList() { this.initBluetoothList(); const data = JSON.stringify(this.devices) console.log('获取蓝牙设备list', data) this.qrCodeWv.evalJS(`appBluetoothListResult('${data}')`) }, initBluetoothList() { this.searchBle(); setTimeout(() => { this.stopFindBule(); }, 10000) }, // 查找蓝牙设备 searchBle() { var self = this console.log("initBule") uni.openBluetoothAdapter({ success(res) { console.log("打开 蓝牙模块") console.log(res) self.onDevice() uni.getBluetoothAdapterState({ success: function (res) { console.log(res) if (res.available) { if (res.discovering) { self.stopFindBule() } //搜索蓝牙 //开始搜寻附近的蓝牙外围设备 console.log("开始搜寻附近的蓝牙外围设备") uni.startBluetoothDevicesDiscovery({ success(res) { console.log(res) } }) } else { console.log('本机蓝牙不可用') } }, }) } }) }, onDevice() { console.log("监听寻找到新设备的事件---------------") var self = this //监听寻找到新设备的事件 uni.onBluetoothDeviceFound(function (devices) { //获取在蓝牙模块生效期间所有已发现的蓝牙设备 console.log('--------------new-----------------------' + JSON.stringify(devices)) var re = JSON.parse(JSON.stringify(devices)) let name = re.devices[0].name if (name != "未知设备" && name.length != 0) { console.log(name.length) let deviceId = re.devices[0].deviceId //信号过滤。大于50 //如果已经存在也不用加入 if (re.devices[0].RSSI > self.filterRSSI) { if (!self.devices.some(v => v.deviceId == deviceId)) { self.devices.push({ name: name, deviceId: deviceId, services: [] }) } } } }) }, stopFindBule() { console.log("停止搜寻附近的蓝牙外围设备---------------") uni.stopBluetoothDevicesDiscovery({ success(res) { console.log(res) } }) }, // 连接蓝牙 connBluetooth(device) { this.onConn(device); }, // 连接蓝牙 onConn(item) { var self = this console.log(`连接蓝牙---------------${item.deviceId}`) let deviceId = item.deviceId uni.createBLEConnection({ deviceId: deviceId, complete(res) { let result = false; if (res.errMsg == "createBLEConnection:ok") { plus.nativeUI.toast(`设备:${item.name} 已连接`, { verticalAlign: 'center' }) self.connId = deviceId; self.currDev = item, setTimeout(function () { self.getBLEServices(deviceId) }, 2000) result = true; } else { plus.nativeUI.toast(`设备: ${item.name} 连接失败。请重试!`, { verticalAlign: 'center', }) //切换异常时释放掉链接 if (self.connId != '') { uni.closeBLEConnection({ deviceId: self.connId, success(res) { console.log(res) } }) } } //连接成功 关闭搜索 self.stopFindBule() //发生是否成功结果 var data = {}; data.result = result; var data1 = JSON.stringify(data) self.wv.evalJS(`appConnBluetoothResult('${data1}')`) }, }) }, getBLEServices(_deviceId) { var self = this; let deviceId = _deviceId console.log("获取蓝牙设备所有服务(service)。---------------") uni.getBLEDeviceServices({ // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 deviceId: deviceId, complete(res) { console.log(res) let serviceId = "" for (var s = 0; s < res.services.length; s++) { console.log(res.services[s].uuid) let serviceId = res.services[s].uuid uni.getBLEDeviceCharacteristics({ // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 deviceId: deviceId, // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取 serviceId: serviceId, success(res) { var re = JSON.parse(JSON.stringify(res)) console.log(`deviceId =[${deviceId}] serviceId = [${serviceId}]`) for (var c = 0; c < re.characteristics.length; c++) { if (re.characteristics[c].properties.write == true) { let uuid = re.characteristics[c].uuid console.log(`deviceId =[${deviceId}] serviceId = [${serviceId}] characteristics=[${uuid}]`) for (var index in self.devices) { if (self.devices[index].deviceId == deviceId) { self.devices[index].services.push({ serviceId: serviceId, characteristicId: uuid }) break } } console.log(JSON.stringify(self.devices)) } } } }) } }, fail(res) { console.log(res) }, }) }, senBlData(deviceId, serviceId, characteristicId, uint8Array) { var uint8Buf = Array.from(uint8Array); function split_array(datas, size) { var result = {}; var j = 0 if (datas.length < size) { size = datas.length } for (var i = 0; i < datas.length; i += size) { result[j] = datas.slice(i, i + size) j++ } //result[j] = datas console.log(result) return result } var sendloop = split_array(uint8Buf, 20); // console.log(sendloop.length) function realWriteData(sendloop, i) { var data = sendloop[i] if (typeof (data) == "undefined") { return } //console.log("第【" + i + "】次写数据"+data) var buffer = new ArrayBuffer(data.length) var dataView = new DataView(buffer) for (var j = 0; j < data.length; j++) { dataView.setUint8(j, data[j]); } uni.writeBLECharacteristicValue({ deviceId, serviceId, characteristicId, value: buffer, success(res) { console.log('发送成功', i) setTimeout(() => { realWriteData(sendloop, i + 1); }, 100) }, fail(e) { console.log('发送数据失败') console.log(e) } }) } var i = 0; realWriteData(sendloop, i); }, }}</script>
二、H5 Vue项目引入js
1、在public新建js文件夹uni.webview.1.5.4.js文件,其源码地址
https://gitee.com/dcloud/uni-app/raw/dev/dist/uni.webview.1.5.4.js
2、index.html 引入 public/js 下文件
<script src="<%= BASE_URL %>js/uni.webview.1.5.4.js"></script>
3、main.js 定义回调方法和对象
// 蓝牙设备列表window.appBluetoothListResult = function (val) { window.appBluetoothListResultString = val window.dispatchEvent(new CustomEvent('bluetoothListResult'))}// 蓝牙连接成功或失败window.appConnBluetoothResult = function (val) { window.appConnBluetoothResultString = val window.dispatchEvent(new CustomEvent('connBluetoothResult'))}
4、Vue扫码页面代码
1、在mixins文件夹下新建bluetoothMixins.js:代码如下
export default { data() { return { bluetoothShow: false, // 蓝牙设备弹窗 deviceId: '', // 蓝牙设备ID listArr: [] // 获取所有蓝牙设备 } }, created() { window.addEventListener('bluetoothListResult', this.handleBluetoothList, false) window.addEventListener('connBluetoothResult', this.handleConnBluetoothResult, false) }, beforeDestroy() { window.removeEventListener('bluetoothListResult', this.handleBluetoothList) window.removeEventListener('connBluetoothResult', this.handleConnBluetoothResult) }, methods: { handleConnBluetoothResult() { const result = window.appConnBluetoothResultString console.log('返回蓝牙是否连接成功', result) if (JSON.parse(result).result) { console.log('连接成功') const deviceId = localStorage.getItem('bluetoothDeviceId') localStorage.setItem('bluetoothDeviceId', deviceId || this.deviceId) // alert(`${this.deviceId}---设置值选中的值`) // alert(`${deviceId}---设置值缓存的值`) this.bluetoothShow = false } }, handleBluetoothList() { const result = window.appBluetoothListResultString console.log('返回蓝牙list', result) if (result) { this.bluetoothShow = true this.listArr = JSON.parse(result) } }, // 选中设备 selectBluetooth(item) { console.log('选中设备', item) this.deviceId = item.deviceId uni.postMessage({ data: { action: 'connBluetooth', params: { deviceId: this.deviceId } } }) } }}
2、实际Vue页面:如下
import BluetoothMixins from '@/mixins/bluetoothMixins'export default { mixins: [BluetoothMixins], methods: { // 点击打印按钮 async print(deliveryNo) { console.log('配送单deliveryNo----', deliveryNo) // 获取蓝牙打印参数 const res = await this.$api.getDeliveryPrintParam({ deliveryNo }) if (res.success) { // 判断之前是否有连接过蓝牙 const deviceId = localStorage.getItem('bluetoothDeviceId') // alert(`${deviceId}---配送单缓存值`) if (deviceId) { // 连接过直接打印 uni.postMessage({ data: { action: 'bluetoothPrint', params: { deviceId, command: JSON.parse(res.data) } } }) } else { // 没有连接过,先去获取蓝牙设备数据(list) uni.postMessage({ data: { action: 'getBluetoothList' } }) } } } } }
相关文章
基于ElementUi再次封装基础组件文档
基于ant-design-vue再次封装基础组件文档
vue3+ts基于Element-plus再次封装基础组件文档