Vue H5项目,怎么引入uni.webview sdk,调用uni postMessage实现手机蓝牙连接打印功能(uniapp)

前言

目前公司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再次封装基础组件文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/236251.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Appium 自动化测试从入门到精通,零基础也能听懂

1.Appium介绍 1&#xff0c;appium是开源的移动端自动化测试框架&#xff1b; 2&#xff0c;appium可以测试原生的、混合的、以及移动端的web项目&#xff1b; 3&#xff0c;appium可以测试ios&#xff0c;android应用&#xff08;当然了&#xff0c;还有firefoxos&#xff09…

记一次mybatis-plus的argument type mismatch报错

起初以为是boolean和数据库的tinyint不匹配导致&#xff0c;找了一天之后想起来把整个lambda注释掉发现list直接无法运行&#xff0c;说明问题不在boolean List<BmsBillboard> list bmsBillboardService.list(new LambdaQueryWrapper<BmsBillboard>().eq(BmsBillb…

盘点六款颇具潜力的伪原创AI工具

写作作为信息传递的主要媒介&#xff0c;在庞大的信息海洋中&#xff0c;为了在激烈的竞争中脱颖而出&#xff0c;伪原创AI工具成为越来越多写手的神秘利器。在本文中&#xff0c;我们将深入盘点六款颇具潜力的伪原创AI工具&#xff0c;为你揭开它们神秘的面纱。 1. 文心一言 …

【android开发-17】android中SQLite数据库CRUD详细介绍

1&#xff0c;SQLite数据库读写的操作步骤 在Android中&#xff0c;对SQLite数据库的操作主要包括以下步骤&#xff1a; 1&#xff0c;创建数据库&#xff1a;首先&#xff0c;您需要创建一个SQLite数据库。这可以通过在Android项目中创建一个新的类来实现&#xff0c;该类继…

操作系统内部机制学习

切换线程时需要保存什么 函数需要保存吗&#xff1f;函数在Flash上&#xff0c;不会被破坏&#xff0c;无需保存。函数执行到了哪里&#xff1f;需要保存吗&#xff1f;需要保存。全局变量需要保存吗&#xff1f;全局变量在内存上&#xff0c;无需保存。局部变量需要保存吗&am…

OpenWRT搭建本地web站点并结合内网穿透实现公网远程访问

文章目录 前言1. 检查uhttpd安装2. 部署web站点3. 安装cpolar内网穿透4. 配置远程访问地址5. 配置固定远程地址 前言 uhttpd 是 OpenWrt/LuCI 开发者从零开始编写的 Web 服务器&#xff0c;目的是成为优秀稳定的、适合嵌入式设备的轻量级任务的 HTTP 服务器&#xff0c;并且和…

ubuntu22.04安装 nvidia-cudnn

nvidia-cudnn 是 NVIDIA CUDA 深度神经网络库&#xff08;CUDA Deep Neural Network library&#xff09;的缩写。这是一个由 NVIDIA 提供的库&#xff0c;用于加速深度学习应用程序。它包含了针对深度神经网络中常用操作&#xff08;如卷积、池化、归一化、激活层等&#xff0…

如何使用cpolar+Inis在Ubuntu系统快速搭建本地博客网站公网可访问

文章目录 前言1. Inis博客网站搭建1.1. Inis博客网站下载和安装1.2 Inis博客网站测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 3. 公网访问测试总…

go 编译apk

首先进行安装go 安装 wget https://studygolang.com/dl/golang/go1.21.5.linux-amd64.tar.gz tar zxvf go1.21.5.linux-amd64.tar.gz mv go /usr/local/ vim /etc/profile # 进行配置环境变量&#xff1a; export GOROOT/usr/local/go export PATH$PATH:$GOROOT/bin # 保存退…

推荐算法:HNSW【推荐出与用户搜索的类似的/用户感兴趣的商品】

HNSW算法概述 HNSW&#xff08;Hierarchical Navigable Small Word&#xff09;算法算是目前推荐领域里面常用的ANN&#xff08;Approximate Nearest Neighbor&#xff09;算法了。其目的就是在极大量的候选集当中如何快速地找到一个query最近邻的k个元素。 要找到一个query的…

风控之Android设备指纹技术

标识性参数——Android ID、IMEI、OAID非标识性参数 非标识性参数——手机运营商 1 设备指纹 简单来讲&#xff0c;设备指纹是指用于标识出该设备的设备特征。可以是单一设备特征&#xff0c;也可以是多种设备特征的组合&#xff0c;以方便风控系统对设备的唯一性进行识别。…

BSN实名DID服务发布会将于12月12日在北京召开

当前&#xff0c;数字身份已经成为实现经济健康发展与社会和谐安全稳定的重要基础&#xff0c;同时也是激发数据要素价值&#xff0c;支持数字经济快速发展的重要手段&#xff0c;在数字中国建设中发挥着至关重要的作用。 2016年&#xff0c;经国家发展改革委批准&#xff0c;…

2023.12.9 关于 Spring Boot 事务传播机制详解

目录 事务传播机制 七大事务传播机制 支持当前调用链上的事务 Propagation.REQUIRED Propagation.SUPPORTS Propagation.MANDATORY 不支持当前调用链上的事务 Propagation.REQUIRES_NEW Propagation.NOT_SUPPORTED Propagation.NEVER 嵌套事务 Propagation.NESTED…

币圈新贵Blast,一条可以帮助用户赚钱的Layer2!

Blast在短短两天内实现了超过2亿美元的TVL飙升&#xff0c;这一迅猛增长让整个低迷已久的Layer2市场感到震惊。尽管Blast主网要到二月份才正式上线&#xff0c;但这并未能阻挡用户们热情地锁仓。截至目前&#xff0c;Blast已经吸引了超过75,000名用户&#xff0c;总锁定价值已经…

直流电和交流电

直流电&#xff08;Direct Current&#xff0c;简称DC&#xff09;和交流电&#xff08;Alternating Current&#xff0c;简称AC&#xff09;是电流的两种基本形式。 1. 直流电 直流电是指电流方向始终保持不变的电流。在直流电中&#xff0c;电子只能沿着一个方向移动。直流电…

UEFI下Windows10和Ubuntu22.04双系统安装图解

目录 简介制作U盘启动盘并从U盘启动电脑安装系统安装Windows系统安装Ubuntu 附录双系统时间不一致 简介 传统 Legacy BIOS主板下的操作系统安装可参考本人博客 U盘系统盘制作与系统安装&#xff08;详细图解&#xff09; &#xff0c;本文介绍UEFI主板下的双系统安装&#xff…

快手商品采集API商品列表API商品详情数据API接口获取快手商品信息API

背景介绍 快手商城是快手平台上的一个电商购物频道&#xff0c;类似于淘宝、京东等商城&#xff0c;用户可以通过搜索或者快手 App 首页的一级入口进入。目前&#xff0c;快手商城正在招商中&#xff0c;今年双 11 期间&#xff0c;快手将力推短视频、直播间、店铺、商城这一全…

基于AWS Serverless的Glue服务进行ETL(提取、转换和加载)数据分析(三)——serverless数据分析

3 serverless数据分析 大纲 3 serverless数据分析3.1 创建Lambda3.2 创建API Gateway3.3 结果3.4 总结 3.1 创建Lambda 在Lambda中&#xff0c;我们将使用python3作为代码语言。 步骤图例1、入口2、创建&#xff08;我们选择使用python3.7&#xff09;3、IAM权限&#xff08;…

C# 数据的保存和提取(.TXT格式)

红色部分的才是最终版 一、将页面内容保存到文件中 第一步 创建Visual的Windows窗体应用,使用的是 第二步 创建几个Label控件、TextBox控件、以及Button按钮,而TextBox控件放入Panel中 第三步 先对写法进行了解,了解保存的语句 StreamWriter sw= new StreamWriter(TXT…

自定义类型详解(1)

文章目录 目录1. 结构体1.1 结构的基础知识1.2 结构的声明1.3 特殊的声明1.4 结构的自引用1.5 结构体变量的定义和初始化1.6 结构体内存对齐1.7 修改默认对齐数1.8 结构体传参 2. 位段2.1 什么是位段2.2 位段的内存分配2.3 位段的跨平台问题2.4 位段的应用 3. 枚举3.1 枚举类型…