Vue h5项目添加蓝牙打印标签功能

背景:

        已完成的h5项目(移动端网页、基于vue框架+vant组件)现在要求加入蓝牙打印功能。

问题描述

      Native.js for Android封装一条通过JS语法直接调用Native Java接口通道,通过plus.android可调用几乎所有的系统。这里通过  Native.js获取监听连接等操作Android蓝牙设备。

需求描述:

      1. 点击“切换打印机”按钮可以搜索周围蓝牙设备加入未配对列表,点击未配对蓝牙设备进行配对,点击已配对的蓝牙设置进行连接打印

      2. 点击“打印”按钮,直接自动调用上次连接的打印机进行打印

解决方法:      

 1.新增一个搜索蓝牙,蓝牙配对连接并打印的页面

 BluetoothMatch.vue

<template>
  <div class="print-wrap" v-if="showPrint">
    <div class="print-main">
      <div class="btn-wrap">
        <van-button
          type="info"
          @click="searchDevices('')"
          :disabled="btnDisabled"
          >{{ btnText }}</van-button
        >
        <van-button type="info" plain @click="close">
          取消</van-button
        >
      </div>
      <div style="margin: 15px 0">
        已配对蓝牙:
        <ul id="matchDevice">
          <van-cell
            v-for="(item, index) in matchDeviceList"
            :key="index"
            :title="item.name"
            @click="handlePrint(item.id, index)"
          >
            <template #right-icon>
              <van-loading type="spinner" v-if="item.isConnecting" />
              <van-icon name="success" v-if="item.isConnected" />
              <span
                v-if="!item.isConnected && !item.isConnecting"
                style="color: #ccc"
                >未连接</span
              >
            </template>
          </van-cell>
        </ul>
      </div>
      <div>
       未配对蓝牙:
        <ul id="unmatchDevice">
          <van-cell
            v-for="(item, index) in unmatchDeviceList"
            :key="index"
            :title="item.name"
            @click="searchDevices(item.id, index)"
          >
            <template #right-icon>
              <van-loading type="spinner" v-if="item.isConnecting" />
            </template>
          </van-cell>
        </ul>
      </div>
    </div>
  </div>
</template>
 
<script>
export default {
  name: "BluetoothMatch",
  data() {
    return {
      device: null,
      BAdapterL: null,
      BluetoothAdapter: null,
      uuid: null,
      main: null,
      bluetoothSocket: null,
      BleDevice: null,
      matchDeviceList: [],
      unmatchDeviceList: [],
      btnText: "搜索设备",
      btnDisabled: false,
      lastIndex: -1, //上一个链接的设备
      matchAddress: [],
      unmatchAddress: [],
      isMatching: false, //配对设备
      isConnecting: false, //连接设备打印
      isArray: false,
    };
  },
  props: {
    printValue: {
      type: Array,
      defalut() {
        return [];
      },
    },
    address: {
      type: String,
      default: "",
    },
    showPrint: {
      type: Boolean,
      defalut: false,
    },
  },
  watch: {
    "matchDeviceList.length": {
      handler(newVal) {
        localStorage.setItem(
          "matchDeviceList",
          JSON.stringify(this.matchDeviceList)
        );
      },
    },
    "matchAddress.length": {
      handler(newVal) {
        localStorage.setItem("matchAddress", JSON.stringify(this.matchAddress));
      },
    },
  },
  mounted() {
    this.openBluetoothAdapter();
    console.log("print mounted---------------");
    if (JSON.parse(localStorage.getItem("matchDeviceList"))) {
      this.matchDeviceList = JSON.parse(
        localStorage.getItem("matchDeviceList")
      );
    }
    if (JSON.parse(localStorage.getItem("matchAddress"))) {
      this.matchAddress = JSON.parse(localStorage.getItem("matchAddress"));
    }
    console.log(this.matchDeviceList);
  },
  methods: {
    // 监听蓝牙设备连接状态
    listenerConnection() {
      plus.bluetooth.onBLEConnectionStateChange(function (e) {
        console.log("connection state changed: " + JSON.stringify(e));
      });
    },
    openBluetoothAdapter() {
      console.log("初始化蓝牙模块--------");
      var _this = this;
      plus.bluetooth.openBluetoothAdapter({
        success: function (e) {
          console.log("open success: " + JSON.stringify(e));
        },
        fail: function (e) {
          console.log("open failed: " + JSON.stringify(e));
        },
        complete(e) {
          console.log(e);
          if (!e.errCode) {
            console.log("初始化完成");
          } else if (e.errCode == 10001) {
            uni.showToast({
              icon: "none",
              title:"请打开手机蓝牙",
            });
          } else {
            uni.showToast({
              icon: "none",
              title: e.errMsg,
            });
          }
        },
      });
    },
    close() {
      this.btnDisabled = false;
      this.btnText = "搜索设备";
      this.unmatchDeviceList = [];
      this.unmatchAddress = [];
 
      this.isConnecting = false;
      this.isMatching = false;
      if (this.bluetoothSocket) {
        this.bluetoothSocket.close();
      }
      this.$emit("closePrint");
    },
    // Android权限查询
    requestAndroidPermission(permissionID) {
      return new Promise((resolve, reject) => {
        plus.android.requestPermissions(
          [permissionID], // 理论上支持多个权限同时查询,但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装
          function (resultObj) {
            var result = 0;
            for (var i = 0; i < resultObj.granted.length; i++) {
              var grantedPermission = resultObj.granted[i];
              console.log("已获取的权限:" + grantedPermission);
              result = 1;
            }
            for (var i = 0; i < resultObj.deniedPresent.length; i++) {
              var deniedPresentPermission = resultObj.deniedPresent[i];
              console.log("拒绝本次申请的权限:" + deniedPresentPermission);
              result = 0;
            }
            for (var i = 0; i < resultObj.deniedAlways.length; i++) {
              var deniedAlwaysPermission = resultObj.deniedAlways[i];
              console.log("永久拒绝申请的权限:" + deniedAlwaysPermission);
              result = -1;
            }
            resolve(result);
            // // 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限
            // if (result != 1) {
            //   console.log("跳转到设置")
            //   // Toast('打印需要位置权限,正在跳转到设置界面...');
            //   this.gotoAppPermissionSetting()
            // }
          },
          function (error) {
            console.log("申请权限错误:" + error.code + " = " + error.message);
            resolve({
              code: error.code,
              message: error.message,
            });
          }
        );
      });
    },
    gotoAppPermissionSetting() {
      // console.log(plus.device.vendor);
      var Intent = plus.android.importClass("android.content.Intent");
      var Settings = plus.android.importClass("android.provider.Settings");
      var Uri = plus.android.importClass("android.net.Uri");
      var mainActivity = plus.android.runtimeMainActivity();
      var intent = new Intent();
      intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
      var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
      intent.setData(uri);
      mainActivity.startActivity(intent);
    },
    handlePrint(mac_address, index) {
      console.log("打印:", this.isConnecting);
      if (this.isConnecting) {
        return;
      }
      this.isConnecting = true;
      console.log("准备连接设备:", mac_address);
      if (!mac_address) {
        this.$toast("请选择打印机");
        return;
      }
      this.main = plus.android.runtimeMainActivity();
      this.BluetoothAdapter = plus.android.importClass(
        "android.bluetooth.BluetoothAdapter"
      );
      let UUID = plus.android.importClass("java.util.UUID");
      this.uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
      this.BAdapter = this.BluetoothAdapter.getDefaultAdapter();
      this.device = this.BAdapter.getRemoteDevice(mac_address);
      plus.android.importClass(this.device);
      this.bluetoothSocket =
        this.device.createInsecureRfcommSocketToServiceRecord(this.uuid);
      plus.android.importClass(this.bluetoothSocket);
      if (!this.bluetoothSocket.isConnected()) {
        console.log("检测到设备未连接,尝试连接....");
        this.matchDeviceList[index].isConnecting = true;
        this.matchDeviceList[index].isConnected = false;
        console.log(this.matchDeviceList[index]);
        console.log("连接中...");
 
        this.bluetoothSocket.connect();
      }
      if (this.lastIndex != -1) {
        //关闭上个连接设备
        this.matchDeviceList[this.lastIndex].isConnecting = false;
        this.matchDeviceList[this.lastIndex].isConnected = false;
      }
      this.isConnecting = false;
      this.matchDeviceList[index].isConnecting = false;
      this.matchDeviceList[index].isConnected = true;
      this.lastIndex = index;
      console.log("设备已连接");
      localStorage.setItem("lastConnectAddress", mac_address);
 
      if (this.bluetoothSocket.isConnected()) {
        console.log("test begin");
        // TestDemo  = plus.android.importClass("com.topband.TestDemo");
        let outputStream = this.bluetoothSocket.getOutputStream();
        console.log("outputStream:%o", outputStream);
        plus.android.importClass(outputStream);
        this.printValue.forEach((item) => {
          if (this.device) {
            console.log("this.BleDevice.getName():%o", this.device.getName());
          }
 
          let bytes = plus.android.invoke(item, "getBytes", "GB2312");
          outputStream.write(bytes);
          outputStream.flush();
        });
        this.device = null; //这里关键
        this.bluetoothSocket.close(); //必须关闭蓝牙连接否则意外断开的话打印错误
      }
    },
 
    /**
     *
     * @param {string} address 设备地址
     * @param {string} index 设备索引
     */
    async searchDevices(address, index) {
      console.log("address:" + address);
 
      if (!address) {
        //点击搜索设备按钮  清空 重新搜索
        this.matchAddress = [];
        this.unmatchAddress = [];
        this.unmatchDeviceList = []; //清空容器
        this.matchDeviceList = []; //清空容器
        this.isConnecting = false;
        this.isMatching = false;
        this.btnDisabled = true;
        this.btnText = "正在搜索请稍候...";
      } else if (this.isMatching) {
        //正在配对
        return;
      } else {
        //开始配对设备
        this.isMatching = true;
        this.unmatchDeviceList[index].isConnecting = true;
      }
      //注册类
      let _this = this;
      let main = plus.android.runtimeMainActivity();
 
      //check location permission
 
      let promiseV = await this.requestAndroidPermission(
        "android.permission.ACCESS_COARSE_LOCATION"
      );
      console.log("promiseV:%o", promiseV);
      // 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限
      if (promiseV != 1) {
        console.log("跳转到设置");
        // Toast('打印需要位置权限,正在跳转到设置界面...');
        plus.nativeUI.toast("打印需要位置权限,正在跳转到设置界面");
        this.gotoAppPermissionSetting();
        _this.btnDisabled = false;
        _this.btnText = "搜索设备"
        return;
      }
 
      let IntentFilter = plus.android.importClass(
        "android.content.IntentFilter"
      );
      let BluetoothAdapter = plus.android.importClass(
        "android.bluetooth.BluetoothAdapter"
      );
      let BluetoothDevice = plus.android.importClass(
        "android.bluetooth.BluetoothDevice"
      );
      let BAdapter = BluetoothAdapter.getDefaultAdapter();
      let filter = new IntentFilter();
      let bdevice = new BluetoothDevice();
      let on = null;
      let un = null;
 
      BAdapter.startDiscovery(); //开启搜索
      let receiver;
      receiver = plus.android.implements(
        "io.dcloud.android.content.BroadcastReceiver",
        {
          onReceive: function (context, intent) {
            //实现onReceiver回调函数
            plus.android.importClass(intent); //通过intent实例引入intent类,方便以后的‘.’操作
            console.log(intent.getAction()); //获取action
            if (
              intent.getAction() ==
              "android.bluetooth.adapter.action.DISCOVERY_FINISHED"
            ) {
              main.unregisterReceiver(receiver); //取消监听
              _this.btnDisabled = false;
              _this.btnText ="搜索设备"
              console.log("搜索结束");
            } else {
              _this.BleDevice = intent.getParcelableExtra(
                BluetoothDevice.EXTRA_DEVICE
              );
              //判断是否配对
              console.log("bledevice:" + _this.BleDevice);
              if (
                _this.BleDevice &&
                _this.BleDevice.getBondState() == bdevice.BOND_NONE
              ) {
                console.log(
                  "蓝牙设备:" +
                    _this.BleDevice.getName() +
                    "    " +
                    _this.BleDevice.getAddress()
                );
                //参数如果跟取得的mac地址一样就配对
                if (address == _this.BleDevice.getAddress()) {
                  console.log("开始配对-------------");
                  if (_this.BleDevice.createBond()) {
                    //配对命令.createBond()
                    console.log("配对成功:", _this.BleDevice.createBond());
                    let obj = {
                      id: _this.BleDevice.getAddress(),
                      name: _this.BleDevice.getName(),
                      isConnecting: false,
                      isConnected: false,
                    };
                    _this.isMatching = false;
                    _this.unmatchDeviceList.splice(index, 1);
                    if (_this.matchAddress.indexOf(obj.id) == -1) {
                      _this.matchAddress.push(obj.id);
                      _this.matchDeviceList.push(obj);
                    }
                    // this.listenerConnection()
                  } else {
                    console.log("配对失败:", _this.BleDevice.createBond());
                    _this.isMatching = false;
                    _this.unmatchDeviceList[index].isConnecting = false;
                  }
                } else {
                  console.log(
                    "未配对蓝牙设备:" +
                      _this.BleDevice.getName() +
                      "    " +
                      _this.BleDevice.getAddress()
                  );
                  if (_this.BleDevice.getName() != on) {
                    //判断防止重复添加
                    let obj = {
                      id: _this.BleDevice.getAddress(),
                      name: _this.BleDevice.getName(),
                      isConnecting: false,
                      isConnected: false,
                    };
                    if (_this.unmatchAddress.indexOf(obj.id) == -1) {
                      _this.unmatchAddress.push(obj.id);
                      _this.unmatchDeviceList.push(obj);
                    }
                  }
                }
              } else {
                if (_this.BleDevice.getName() != un) {
                  //判断防止重复添加
                  console.log(
                    "已配对蓝牙设备:" +
                      _this.BleDevice.getName() +
                      "    " +
                      _this.BleDevice.getAddress()
                  );
                  let obj = {
                    id: _this.BleDevice.getAddress(),
                    name: _this.BleDevice.getName(),
                    isConnecting: false,
                    isConnected: false,
                  };
                  if (_this.matchAddress.indexOf(obj.id) == -1) {
                    _this.matchAddress.push(obj.id);
                    _this.matchDeviceList.push(obj);
                  }
                }
              }
            }
          },
        }
      );
 
      filter.addAction(bdevice.ACTION_FOUND);
      filter.addAction(BAdapter.ACTION_DISCOVERY_STARTED);
      filter.addAction(BAdapter.ACTION_DISCOVERY_FINISHED);
      filter.addAction(BAdapter.ACTION_STATE_CHANGED);
 
      main.registerReceiver(receiver, filter); //注册监听
    },
  },
};
</script>
 
<style scoped>
.print-wrap {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, 0.8);
  z-index: 1000;
}
.print-main {
  width: 80%;
  padding: 20px 10px;
  background-color: #fff;
  border-radius: 10px;
}
.btn-wrap {
  display: flex;
  justify-content: space-between;
}
li {
  margin: 8px 0;
}
button {
  height: 32px;
}
#unmatchDevice,
#matchDevice {
  max-height: 200px;
  overflow: auto;
}
#matchDevice li.isConnected {
  color: #1989fa;
}
.btn-info {
  padding: 0 15px;
  border-radius: 2px;
  font-size: 14px;
  color: #fff;
  background-color: #1989fa;
  border: 1px solid #1989fa;
}
.btn-info.plain {
  color: #1989fa;
  background-color: #fff;
}
.btn-info:disabled {
  background-color: #005ea7;
}
#unmatchDevice .van-cell,
#matchDevice .van-cell {
  padding: 8px 16px 8px 8px;
}
#matchDevice .van-loading__spinner,
#unmatchDevice .van-loading__spinner {
  width: auto;
  height: 100%;
}
/deep/ .van-icon-success {
  color: #2753f5;
}
</style>
<style>
#unmatchDevice li,
#matchDevice li {
  margin: 8px 0;
}
</style>

2.添加调用蓝牙打印的js函数

 bluetoothPrint.js

export function bluetoothPrint(mac_address, printValue) {
    console.log("进入print-----")
    try {
        let BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");
        let UUID = plus.android.importClass("java.util.UUID");
        let uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
        let BAdapter = BluetoothAdapter.getDefaultAdapter();
        let device = BAdapter.getRemoteDevice(mac_address);
        plus.android.importClass(device);
        let bluetoothSocket = device.createInsecureRfcommSocketToServiceRecord(uuid);
        plus.android.importClass(bluetoothSocket);
        if (!bluetoothSocket.isConnected()) {
            console.log('检测到设备未连接,尝试连接....');
            console.log("连接中...")

            bluetoothSocket.connect();
        }
        console.log('设备已连接');

        if (bluetoothSocket.isConnected()) {
            console.log("test begin")
            let outputStream = bluetoothSocket.getOutputStream();
            console.log("outputStream:%o", outputStream);
            plus.android.importClass(outputStream);

            console.log("qrCodeArr:%o", printValue)
            printValue.forEach(item => {
                if (device) {
                    console.log("this.BleDevice.getName():%o", device.getName())
                }
                console.log("version log -------2021-999999")
                console.log("print qr-----")
                let bytes = plus.android.invoke(item, 'getBytes', 'GB2312');
                outputStream.write(bytes);
                outputStream.flush();
            })

            device = null //这里关键
            bluetoothSocket.close(); //必须关闭蓝牙连接否则意外断开的话打印错误
            localStorage.setItem("lastConnectAddress", mac_address)
        }

    } catch (error) {}
}

3.引入蓝牙配对连接页面和蓝牙打印功能函数。

蓝牙打印机为佳博打印机,打印指令可参考佳博标签打印机的编程手册

<template>
  <div class="container">
    <van-button
      type="info"
      size="small"
      native-type="button"
      @click="printLabel(1)"
      ><i class="fa fa-bluetooth" style="margin-right: 5px"></i
      >蓝牙打印</van-button
    >
    <van-button
      type="info"
      size="small"
      icon="exchange"
      native-type="button"
      @click="printLabel(2)"
      >切换打印机</van-button
    >
    <print
      :printValue="printValue"
      :address="address"
      :showPrint="showPrint"
      @closePrint="closePrint"
    ></print>
    <van-overlay :show="loading">
      <van-loading color="#1989fa" v-if="loading" />
    </van-overlay>
  </div>
</template>
<script>
import Vue from "vue";
import Print from "@/components/BluetoothMatch";
import { bluetoothPrint } from "../../utils/bluetoothPrint";
import {  Overlay } from "vant";
Vue.use(Overlay);

export default {
  components: {
    Print,
  },
  data() {
    return {
      show: false,
      loading: false,
      showPrint: false,
      printValue: [],
      address: ""
    };
  },

  mounted() {},
  methods: {
    printLabel(type) {
        let params = {
            prodCode:"12345678",
            workOrder:"11111111",
            prodDate:"20231010",
            number:100,
            batch:"1"
        }
        let boxCode = ["12345678909876541","12345678909876542"]
         this.printByBluetooth(type, params, boxCode);
    },

    closePrint() {
      this.showPrint = false;
    },
    /**
     * @param {String|Number} type 打印类型,1为直接用上次连接的打印机打印   2为切换打印机并打印
     * @param {Object} params 打印的数据
     * @param {Array} boxCode 打印的箱码
     */
    printByBluetooth(type, params, boxCode) {
      boxCode = boxCode.filter((item) => item);
      if (!boxCode.length) {
        this.$toast("无待打印物料");
        return;
      }
      this.printValue = [];
      boxCode.forEach((item, index) => {
        batch = params.batch ? params.batch : "N/A";
        let command = "SIZE 50 mm, 45 mm\r\n"; // 设置标签纸尺寸为 50mm x 40mm
        command += "CLS\r\n"; // 清除打印缓冲区
        command += "BAR 16,16,368,4\r\n"; // 绘制直线
        command += "BAR 16,144,368,4\r\n"; // 绘制直线
        command += "BAR 16,200,368,4\r\n"; // 绘制直线
        command += "BAR 16,248,368,4\r\n"; // 绘制直线
        command += "BAR 16,296,368,4\r\n"; // 绘制直线
        command += "BAR 16,344,368,4\r\n"; // 绘制直线
        command += "BAR 184,296,2,56\r\n"; // 绘制直线
        command += `BARCODE 40,56,\"39\",64,1,0,1,2,\"${item}\"\r\n`;
        command += 'TEXT 120,24,"TSS24.BF2",0,1,1,"物料标签"\r\n';
        command += `TEXT 24,160,\"TSS24.BF2\",0,1,1,\"产品编码:${params.prodCode}\"\r\n`;
        command += `TEXT 24,210,\"TSS24.BF2\",0,1,1,\"工单:${params.workOrder}\"\r\n`;
        command += `TEXT 24,260,\"TSS24.BF2\",0,1,1,\"入仓日期:${params.prodDate}\"\r\n`;
        command += `TEXT 24,306,\"TSS24.BF2\",0,1,1,\"数量:${params.number}\"\r\n`;
        command += `TEXT 200,306,\"TSS24.BF2\",0,1,1,\"批次:${batch}\"\r\n`;
        command += "PRINT 1, 1\r\n"; // 执行打印
        this.printValue.push(command);
      });
      console.log(this.printValue);
      if (type == 1) {
        //蓝牙打印
        let lastConnectAddress = "";
        if (localStorage.getItem("lastConnectAddress")) {
          //默认取上次连接的打印机
          lastConnectAddress = localStorage.getItem("lastConnectAddress");
        }
        console.log(this.lastConnectAddress);
        if (lastConnectAddress) {
          //直接连接第一个
          bluetoothPrint(lastConnectAddress, this.printValue);
        } else {
          this.$toast("请选择打印机");
        }
      } else {
        //切换打印机
        this.showPrint = true;
      }
    },
  },
};
</script>

<style scoped></style>

4.效果展示

5. 添加完蓝牙打印功能后,如何在本地调试以及如何将Vue项目打包为apk,且项目可以不改变现有的模式部署在远程服务器上等,在后续的文章会进行分享

本文参考:安卓Native.js蓝牙连接票据打印机完整代码icon-default.png?t=N7T8http://ask.dcloud.net.cn/article/643

Vue是一种流行的JavaScript框架,用于构建用户界面。Vue也可以用于构建H5应用程序,并与蓝牙打印机进行通信。在Vue中,我们可以使用Web Bluetooth API来访问蓝牙设备。 要在Vue中使用蓝牙打印,我们需要先确保用户的浏览器支持Web Bluetooth API。我们可以使用库如`web-bluetooth`来简化访问蓝牙设备的过程。 首先,在Vue项目中安装`web-bluetooth`库: ```bash npm install web-bluetooth ``` 然后,我们可以创建一个Vue组件,用于管理蓝牙打印功能。在此组件中,我们可以使用`navigator.bluetooth`对象来搜索和连接蓝牙设备,以及发送数据到打印机。 ```javascript <template> <div> <button @click="searchDevices">搜索设备</button> <button @click="connectToDevice">连接设备</button> <button @click="printData">打印数据</button> </div> </template> <script> import WebBluetooth from 'web-bluetooth'; export default { data() { return { device: null, // 当前连接蓝牙设备 printerService: null, // 打印服务 printerCharacteristic: null // 打印特征 }; }, methods: { searchDevices() { navigator.bluetooth.requestDevice({ filters: [{ services: ['printer_service_uuid'] }] }) .then(device => { this.device = device; }) .catch(error => { console.error('搜索设备出错', error); }); }, connectToDevice() { if (this.device) { this.device.gatt.connect() .then(server => { return server.getPrimaryService('printer_service_uuid'); }) .then(service => { this.printerService = service; return service.getCharacteristic('printer_characteristic_uuid'); }) .then(characteristic => { this.printerCharacteristic = characteristic; }) .catch(error => { console.error('连接设备出错', error); }); } }, printData() { if (this.printerCharacteristic) { const data = '要打印的数据'; const encoder = new TextEncoder(); const dataBuffer = encoder.encode(data); this.printerCharacteristic.writeValue(dataBuffer) .then(() => { console.log('数据已发送到打印机'); }) .catch(error => { console.error('发送数据出错', error); }); } } } }; </script> ``` 在上面的示例中,我们先通过`navigator.bluetooth.requestDevice`方法搜索并选择一个蓝牙打印设备。然后,我们使用`device.gatt.connect`方法连接设备并获取打印服务。接下来,我们使用`service.getCharacteristic`方法获取打印特征。最后,我们可以使用`characteristic.writeValue`方法将数据发送到打印机。 需要注意的是,`printer_service_uuid`和`printer_characteristic_uuid`需要替换为实际的蓝牙打印设备的服务UUID和特征UUID。 通过上述步骤,就可以在VueH5应用程序中使用蓝牙打印了。当然,具体的实现可能还需要根据不同的蓝牙打印设备和需求进行调整和扩展。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值