近期做了用uniapp做了一个WX小程序,主要打印不干胶标签,踩了很多坑,查了很多资料,现在记录一下做个备份。
##微信小程序 搜索蓝牙设备还是有很多局限性,手机系统能搜到的,它搜不到,或者搜到也连接不了,这里主要针对标签打印机的蓝牙连接,而且可以通过RSSI过滤设置和蓝牙名称来筛选获取的蓝牙列表
##首先是搜索html界面代码
<template>
<!-- <view class="tobbg bg-primary"></view> -->
<view class="container">
<view class="mb-3"> </view>
<view class="list-item shadow mb-3 pb-2">
<view class="item-top text-center mb-3">
<view class="refreshbt mb-2" @click="refreshblue">
刷新
</view>
<view class="text-graya9">
设备列表刷新(如果没有数据,点击刷新按钮)
</view>
</view>
<view class="uni-title text-gray mt-2">RSSI过滤设置</view>
<view class="item-unit">
<slider :value="rssinum" @change="sliderChange" min="-100" max="-20" show-value
block-size="15" activeColor="#FFCC33"/>
</view>
<view class="uni-title text-gray mt-2">名字过滤设置</view>
<view class="item-unit mt-1">
<input type="text" placeholder="请输入蓝牙名字后点击刷新" v-model="bluetoothname"/>
</view>
</view>
<view class="mt-5">
已发现{{devicesNumber}}个外围设备:
</view>
<view class="bluetoothlist mt-4" v-if="devicesList.length>=1">
<view class="item-item" v-for="(item, index) in devicesList" :key="index" @click="select(item)">
<text v-if="item.name != ''">设备名称:{{item.name}}</text>
<text v-else-if="item.localName != ''">设备名称:{{item.localName}}</text>
<text>信号强度:{{item.RSSI}}</text>
<text>DeviceID:{{item.deviceId}}</text>
<text>AdvMAC:</text>
</view>
</view>
</view>
</template>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
##这是vue的代码
onHide() {
this.closeBLEConnection()
//解除所有蓝牙监听
uni.offBLECharacteristicValueChange();
console.log("onhide 解除所有蓝牙监听")
},
onUnload() {
this.closeBLEConnection()
//解除所有蓝牙监听
uni.offBLECharacteristicValueChange();
console.log("onUnload 解除所有蓝牙监听")
},
methods: {
refreshblue(){ //刷新按钮
console.log('RSSI:',this.rssinum)
console.log('填写蓝牙名称:',this.bluetoothname)
this.Search();
},
sliderChange(e) {
this.rssinum = e.detail.value
},
// 蓝牙模块 测试好后封装
Search() { // 查看设备状态
var that = this;
// console.log("search:", that.searching);
if (!that.searching) {
that.devicesNumber = 0
//关闭现有的蓝牙连接
uni.closeBluetoothAdapter({
success(res) {
console.log(res)
}
});
// uni.closeBluetoothAdapter({
// complete: function(res) {
// console.log("关闭蓝牙模块-----------------------------------------");
// console.log(res);
//打开蓝牙适配
wx.openBluetoothAdapter({
mode: 'central',
// success: function(res) {
success: (res) => {
uni.showLoading({
title: '搜索设备中...请稍后',
});
console.log(
"初始化蓝牙模块----------------------------------------"
);
console.log(res);
wx.getBluetoothAdapterState({
success: function(res) {
console.log(
"获取本机蓝牙适配器状态----------------------------------------"
);
console.log(res);
},
});
//开始搜索蓝牙设备
wx.startBluetoothDevicesDiscovery({
allowDuplicatesKey: false,//false, //允许重复上报设备,主要是为了统计信号强度
// success: function(res) {
success: (res) => {
console.log(
"搜索设备-----------------------------------------"
);
console.log(res)
that.onBluetoothDeviceFound();
that.searching = true;
that.devicesList = [];
},
// fail: function(err) {
fail: (res) => {
uni.hideLoading()
console.log('搜索蓝牙设备失败', res)
uni.showModal({
title: "温馨提示",
content: "搜索蓝牙报错:"+res,
showCancel: false,
confirmColor: "#008fd6",
})
}
});
},
// fail: function(res) {
fail: (res) => {
console.log('蓝牙未打开',res);
uni.hideLoading()
setTimeout(() => {
uni.showModal({
title: "温馨提示",
content: "蓝牙功能报错:"+res,
showCancel: false,
confirmColor: "#008fd6",
});
// that.isSearch = false;
}, 1000);
},
});
// },
// });
}else{
uni.hideLoading()
wx.stopBluetoothDevicesDiscovery({
success: function(res) {
console.log("正在搜索中,所以停止搜索设备-----++++++++++++++++++++--------");
console.log(res);
that.searching = false;
that.Search()
},
});
}
},
//监听寻找到新设备的事件
onBluetoothDeviceFound() { //搜索周围蓝牙列表
var that = this;
console.log("打开设备监听");
that.bleDevs = [];
let arrele = [];
wx.onBluetoothDeviceFound((res) => {
console.log('发现外围设备');
console.log(JSON.stringify(res))
//遍历周围的设备
res.devices.forEach(ele => {
// console.log(ele.name)
//判断周围设备和当前设备的编号或者其他唯一标识是否相同,相同则匹配
// if (ele.name === that.equipment_name) {
// that.devicesList.push(ele);
// that.createBLEConnection(ele);
// }
// console.log('RSSI:',this.rssinum)
// console.log('填写蓝牙名称:',this.bluetoothname)
if(that.bluetoothname != ''){
var indexnum = ele.name.indexOf(that.bluetoothname);
if(indexnum>0 && ele.RSSI>that.rssinum){
arrele.push(ele);
}
}else{
if(ele.RSSI>that.rssinum){
arrele.push(ele);
}
}
})
that.devicesList = arrele;
// 把搜索到的设备存储起来,方便我们在页面上展示
console.log("筛选后的蓝牙列表");
console.log(JSON.stringify(that.devicesList))
that.devicesNumber = that.devicesList.length;
uni.hideLoading()
if(that.devicesNumber >= 1){
that.searching = false;
}else{
uni.showToast({
title:'没有找到蓝牙设备,请重新点击刷新!',
icon:'none'
})
}
})
// uni.onBluetoothDeviceFound(function(devices) {
},
//写一个按钮调一下 上面给方法返回来的数据,取一个获取就行,看打印日志,跟所需参数
select(e) {
var that = this;
console.log('点击连接蓝牙'+that.gettypeid);
console.log(JSON.stringify(e))
let scalename = uni.getStorageSync('scalepageName');
let printname = uni.getStorageSync('printerpageName');
console.log('当前类型:',that.gettypeid == 1)
console.log('当前类型2:',that.gettypeid == '1')
console.log('称重名称:'+scalename,'打印机名称:'+printname)
if(that.gettypeid == 1 && printname){
if(e.name == printname){
uni.showModal({
title: '提示',
content: '已使用当前选择的蓝牙,请重新选择!',
showCancel: false
})
return false
}
}else if(that.gettypeid == 2 && scalename){
if(e.name == scalename){
uni.showModal({
title: '提示',
content: '已使用当前选择的蓝牙,请重新选择!',
showCancel: false
})
return false
}
}
that.ConnectByID({
"deviceId": e.deviceId,
"name": e.name
}, 1);
},
ConnectByID(item, index) { //连接蓝牙
var that = this;
console.log("连接蓝牙:", item);
that.connectedDeviceId = item.deviceId;
if(that.gettypeid == 1){
uni.setStorageSync('scalepageName', item.name);
uni.setStorageSync('scaleconnectedDeviceId', that.connectedDeviceId)
}else{
uni.setStorageSync('printerpageName', item.name);
uni.setStorageSync('printerconnectedDeviceId', that.connectedDeviceId)
}
uni.showLoading({
title: '正在连接设备...',
})
uni.createBLEConnection({
deviceId: item.deviceId,
success(res) {
// that.open()
console.log("已连接设备----------------------------------------");
console.log(that.gettypeid)
if(that.gettypeid == '1'){
uni.setStorageSync("scaledeviceId", item.deviceId)
uni.setStorageSync("scalename", item.name)
}else{
uni.setStorageSync("printerdeviceId", item.deviceId)
uni.setStorageSync("printername", item.name)
}
wx.stopBluetoothDevicesDiscovery({
success: function(res) {
console.log("已搜索到设备,停止搜索设备-----------------------------------------");
console.log(res);
that.searching = false;
// that.Search()
},
});
that.getBLEDeviceServices(); //获取特征值
},
fail(res) {
console.log(res)
uni.hideLoading()
uni.showModal({
title: '提示',
content: '连接失败',
showCancel: false
})
}
})
// }
},
//获取蓝牙设备的服务uuid //服务uuid可能有多个
getBLEDeviceServices() {
var that = this;
setTimeout(() => {
//获取数据可能会有延迟
uni.getBLEDeviceServices({
deviceId: that.connectedDeviceId,
success: function(res) {
console.log(
"获取蓝牙设备的服务uuid:" + JSON.stringify(res.services)
);
console.log("服务uuid", res)
that.services = res.services;
if(res.services.length>=2){
that.serviceId = res.services[1].uuid;
}else{
that.serviceId = res.services[0].uuid;
}
that.deviceId = that.connectedDeviceId;
if(that.gettypeid == '1'){
uni.setStorageSync("scaleserviceId", that.serviceId);
}else{
uni.setStorageSync("printerserviceId", that.serviceId);
}
that.getBLEDeviceCharacteristics();
},
fail(res) {
console.log('错误', res);
},
});
}, 3000);
},
// 根据服务uuid获取蓝牙特征值开始监听写入和接收
getBLEDeviceCharacteristics() {
console.log("开始监听.....")
let that = this;
uni.getBLEDeviceCharacteristics({
deviceId: that.connectedDeviceId,
serviceId: that.serviceId,
success: function(res) {
console.log(
"获取蓝牙设备的特征" + JSON.stringify(res.characteristics)
);
console.log('默认uuid:',that.characteristicId)
that.characteristicId = ''
for (var i = 0; i < res.characteristics.length; i++) {
console.log("Notify特征值",res.characteristics[i].uuid,res.characteristics[i].properties.notify)
if (res.characteristics[i].properties.notify === true && that.characteristicId == '') {
console.log("权限:",res.characteristics[i].properties.read,res.characteristics[i].properties.write,res.characteristics[i].properties.notify)
that.characteristics = res.characteristics[i];
that.characteristicId = res.characteristics[i].uuid;
}
if (res.characteristics[i].properties.write === true) {
that.characteristics = res.characteristics[i];
that.writeId = res.characteristics[i].uuid;
}
}
console.log("测试UUID:",that.characteristicId)
if(that.gettypeid == '1'){
uni.setStorageSync("scalecharacteristicId", that.characteristicId);
uni.setStorageSync("scalewriteId", that.writeId);
}else{
uni.setStorageSync("printercharacteristicId", that.characteristicId);
uni.setStorageSync("printerwriteId", that.writeId);
}
uni.hideLoading()
uni.showToast({
title: '连接成功',
duration: 2000,
icon: "none"
});
// that.notifyBLECharacteristicValueChange(); //7.0,开始侦听数据
},
});
},
notifyBLECharacteristicValueChange() {
var that = this;
// console.log(that.deviceId, that.serviceId, that.characteristicId)
console.log('获取到的蓝牙设备的特征uuid:',that.characteristicId)
uni.notifyBLECharacteristicValueChange({
deviceId: that.deviceId,
serviceId: that.serviceId,
characteristicId: that.characteristicId,
state: false, // 开启通知
success: function(res) {
console.log("启用notify成功",res);
that.onBLECharacteristicValueChange();
},
fail: function(res) {
that.onBLECharacteristicValueChange();
console.log("启用notify失败",res);
},
});
that.onBLECharacteristicValueChange();
},
onBLECharacteristicValueChange() {
console.log("开始接收蓝牙设备返回的数据!")
var that = this;
uni.onBLECharacteristicValueChange((res) => {
// 此时可以拿到蓝牙设备返回来的数据是一个ArrayBuffer类型数据,
//所以 ArrayBuffer 转 16进制 在转字符串
console.log('接收蓝牙设备返回来的数据ArrayBuffer:')
console.log(JSON.stringify(res))
that.bluereturndata = that.hexCharCodeToStr(that.buf2hex(res.value));
console.log('buf2hex:',that.bluereturndata)
if(res.deviceId == uni.getStorageSync("scaledeviceId")){
let str = that.bluereturndata;
let reversedStr = [...str].reverse().join('');//收到的数据是反着的 所以再次翻转
console.log('接收称重返回数据:',reversedStr,Number(reversedStr))
}
});
},
hexCharCodeToStr(hexCharCodeStr) {
var trimedStr = hexCharCodeStr.trim();
var rawStr = trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr;
var len = rawStr.length;
if (len % 2 !== 0) {
alert("存在非法字符!");
return "";
}
var curCharCode;
var resultStr = [];
for (var i = 0; i < len; i = i + 2) {
curCharCode = parseInt(rawStr.substr(i, 2), 16);
resultStr.push(String.fromCharCode(curCharCode));
}
return resultStr.join("");
},
buf2hex(buffer) { // buffer is an ArrayBuffer
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
},
//断开蓝牙
closeBLEConnection() { // 这个是断开蓝牙
uni.closeBLEConnection({
deviceId: this.deviceId,
success(res) {
console.log('关闭成功', res)
},
fail(res) {
console.log('关闭失败', res)
}
})
},
//关闭蓝牙模块 这个是手机的蓝牙
// closeBluetoothAdapter({
// success(res){
// console.log('关闭成功',res)
// },fail(res){
// console.log('关闭失败',res)
// }
// })
//buffer允许写入的uuid
sendMy() {
var that = this
//this.string2buffer-->字符串转换成ArrayBufer(设备接收数据的格式ArrayBufer)
var buff = that.string2buffer('1B0D0A'); // 你的指令
uni.writeBLECharacteristicValue({
// 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
deviceId: that.deviceId,
// 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
serviceId: that.serviceId,
// 这里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中获取
characteristicId: that.characteristicId,
// 这里的value是ArrayBuffer类型
value: buff,
success: function(res) {
//此时设备已接收到你写入的数据
console.log("写入成功")
},
fail: function(err) {
console.log(err)
},
complete: function() {
console.log("调用结束");
}
})
},
string2buffer(str) {
let val = ""
if (!str) return;
let length = str.length;
let index = 0;
let array = []
while (index < length) {
array.push(str.substring(index, index + 2));
index = index + 2;
}
val = array.join(",");
// 将16进制转化为ArrayBuffer
return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function(h) {
return parseInt(h, 16)
})).buffer
},
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.
- 176.
- 177.
- 178.
- 179.
- 180.
- 181.
- 182.
- 183.
- 184.
- 185.
- 186.
- 187.
- 188.
- 189.
- 190.
- 191.
- 192.
- 193.
- 194.
- 195.
- 196.
- 197.
- 198.
- 199.
- 200.
- 201.
- 202.
- 203.
- 204.
- 205.
- 206.
- 207.
- 208.
- 209.
- 210.
- 211.
- 212.
- 213.
- 214.
- 215.
- 216.
- 217.
- 218.
- 219.
- 220.
- 221.
- 222.
- 223.
- 224.
- 225.
- 226.
- 227.
- 228.
- 229.
- 230.
- 231.
- 232.
- 233.
- 234.
- 235.
- 236.
- 237.
- 238.
- 239.
- 240.
- 241.
- 242.
- 243.
- 244.
- 245.
- 246.
- 247.
- 248.
- 249.
- 250.
- 251.
- 252.
- 253.
- 254.
- 255.
- 256.
- 257.
- 258.
- 259.
- 260.
- 261.
- 262.
- 263.
- 264.
- 265.
- 266.
- 267.
- 268.
- 269.
- 270.
- 271.
- 272.
- 273.
- 274.
- 275.
- 276.
- 277.
- 278.
- 279.
- 280.
- 281.
- 282.
- 283.
- 284.
- 285.
- 286.
- 287.
- 288.
- 289.
- 290.
- 291.
- 292.
- 293.
- 294.
- 295.
- 296.
- 297.
- 298.
- 299.
- 300.
- 301.
- 302.
- 303.
- 304.
- 305.
- 306.
- 307.
- 308.
- 309.
- 310.
- 311.
- 312.
- 313.
- 314.
- 315.
- 316.
- 317.
- 318.
- 319.
- 320.
- 321.
- 322.
- 323.
- 324.
- 325.
- 326.
- 327.
- 328.
- 329.
- 330.
- 331.
- 332.
- 333.
- 334.
- 335.
- 336.
- 337.
- 338.
- 339.
- 340.
- 341.
- 342.
- 343.
- 344.
- 345.
- 346.
- 347.
- 348.
- 349.
- 350.
- 351.
- 352.
- 353.
- 354.
- 355.
- 356.
- 357.
- 358.
- 359.
- 360.
- 361.
- 362.
- 363.
- 364.
- 365.
- 366.
- 367.
- 368.
- 369.
- 370.
- 371.
- 372.
- 373.
- 374.
- 375.
- 376.
- 377.
- 378.
- 379.
- 380.
- 381.
- 382.
- 383.
- 384.
- 385.
- 386.
- 387.
- 388.
- 389.
- 390.
- 391.
- 392.
- 393.
- 394.
- 395.
- 396.
- 397.
- 398.
- 399.
- 400.
- 401.
- 402.
- 403.
- 404.
- 405.
- 406.
- 407.
- 408.
- 409.
- 410.
- 411.
- 412.
- 413.
- 414.
- 415.
- 416.
- 417.
- 418.
- 419.
- 420.
- 421.
- 422.
- 423.
- 424.
- 425.
- 426.
- 427.
- 428.
- 429.
- 430.
- 431.
- 432.
- 433.
- 434.
- 435.
- 436.
- 437.
- 438.
- 439.
- 440.
- 441.
- 442.
- 443.
- 444.
- 445.
- 446.
- 447.
- 448.
- 449.
- 450.
- 451.
- 452.
- 453.
- 454.
- 455.
- 456.
- 457.
- 458.
- 459.
##CSS样式
<style lang="scss" scoped>
.tobbg{
width: 100%;
height: 300rpx;
position: fixed;
top: 0;
left: 0;
z-index: 0;
}
:root{
--primary-color: royalblue;
}
.list-item{
padding: 36rpx;
margin-top: 10rpx;
margin-bottom: 40rpx;
border-radius: 28rpx;
position: relative;
overflow: hidden;
.item-top{
.refreshbt{
width: 120rpx;
height: 120rpx;
line-height: 120rpx;
border-radius: 200rpx;
border: 1px solid #20CAAF;
background-color: #BFFAF1;
color: #20CAAF;
text-align: center;
display: inline-block;
position: relative;
cursor: pointer;
overflow: hidden;
transition: background-color 0.8s; /* 背景颜色过渡动画 */
}
.refreshbt:active {
background-color: #3e8e41;
box-shadow: 0 1px #20CAAF;
transform: translateY(1rpx);
}
}
.item-unit{
slider{
margin: 10rpx 0rpx;
}
input{
border-radius: 24rpx;
border: 1px solid #BBBBBB;
padding: 10rpx 16rpx;
}
input::placeholder{
color: #9e9e9e;
}
}
}
.bluetoothlist{
.item-item{
height: auto;
padding: 10rpx 0;
border-bottom: 1px solid #d9d9d9;
margin-bottom: 10rpx;
background-color: #FFFFFF;
text{
display: block;
}
&:active{
background-color: #BFFAF1;
}
}
}
</style>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.