当前位置:   article > 正文

微信小程序获取蓝牙并实现内容打印_微信小程序 蓝牙打印

微信小程序 蓝牙打印

通过微信小程序如何实现获取蓝牙打印机并实现打印能力,之前做过一个测试Dome,能够获取附近的蓝牙打印机设备并实现打印,今天开放出来供大家参考。

wxml

  1. <!--右下角搜索-->
  2. <view class="ly-cass-box">
  3. <view class="ly-cass" bindtap="openBluetoothAdapter">
  4. <image src="/images/search.png" style="width: 70rpx;height: 70rpx;" />
  5. </view>
  6. <text class="ly-text">{{ly_text}}</text>
  7. </view>
  8. <view style="margin: 80rpx 20rpx 30rpx 20rpx;">
  9. <view class="has-devices-list-container">
  10. <view class="tip-search">搜索到的设备</view>
  11. <view class="devices-list">
  12. <view wx:for="{{devices}}" wx:key="index" class="devices-item">
  13. <view style="flex:2">{{item.name? item.name:item.localName}}</view>
  14. <button style="flex:1;" id="{{index}}" bindtap="_createBLEConnection">连接</button>
  15. </view>
  16. </view>
  17. </view>
  18. </view>

以下图片左侧是布局样式,列表中是扫描出来的附近可以连接的蓝牙设备,右侧是我在一个超市扫描附近的设备后的实际打印效果。PS:实际打印前我已和超市收银员沟通,我在做测试代码实际打印效果,请不要用在未经许可的非法用途。

wxss

  1. /* 搜索 */
  2. .ly-cass-box{
  3. width: 150rpx;
  4. height: auto;
  5. display: flex;
  6. align-items: center;
  7. justify-content: center;
  8. flex-direction: column;
  9. position: fixed;
  10. bottom:70rpx;
  11. right: 50rpx;
  12. z-index: 500;
  13. }
  14. .ly-cass{
  15. width: 120rpx;
  16. height: 120rpx;
  17. background-color: #f4f4f5;
  18. border-radius: 50%;
  19. display: flex;
  20. align-items: center;
  21. justify-content: center;
  22. }
  23. .ly-text{
  24. margin-top: 20rpx;
  25. background-color: #eee;
  26. padding: 2rpx 8rpx 2rpx 8rpx;
  27. border-radius: 6rpx;
  28. font-size: 25rpx;
  29. }
  30. .no-open-gps-tip {
  31. width: 100%;
  32. display: flex;
  33. flex-direction: row;
  34. align-items: center;
  35. color: #fa3534;
  36. font-weight: 400;
  37. font-size: 30rpx;
  38. background: rgba(235, 207, 48, 0.8);
  39. padding: 30rpx;
  40. }
  41. .devices-item {
  42. width: 100%;
  43. display: flex;
  44. justify-content: space-between;
  45. margin-top: 20rpx;
  46. align-items: flex-end;
  47. padding-bottom: 5rpx;
  48. border-bottom: 1px solid #f4f4f5;
  49. }
  50. .devices-list {
  51. width: 100%;
  52. padding: 0 20rpx;
  53. display: flex;
  54. flex-direction: column;
  55. }
  56. .tip-search {
  57. width: 100%;
  58. margin: 20rpx 0;
  59. text-align: left;
  60. font-size: 16px;
  61. color: #2979ff;
  62. }
  63. .has-devices-list-container {
  64. width: 100%;
  65. display: flex;
  66. flex-direction: column;
  67. margin: 30rpx 0;
  68. }

这是我刚开发上线的的两个小游戏,欢迎大家扫码体验!

 以上两个《蛇王传说》《番茄花园》已上线微信/抖音平台运营。

《番茄花园》游戏源码已上架Cocos Store 商店,欢迎围观!Cocos StoreCocos商城 Creator扩展icon-default.png?t=N7T8https://store.cocos.com/app/detail/6122

js

  1. const LAST_CONNECTED_DEVICE = 'last_connected_device';
  2. const PrinterJobs = require('../../printer/printerjobs');
  3. const printerUtil = require('../../printer/printerutil');
  4. Page({
  5. data: {
  6. ly_text: "点击搜索",
  7. connected_ly: false, //蓝牙按钮是否显示
  8. blue_list_ly: false, //蓝牙连接列表显示
  9. discoveryStarted: false,
  10. devices: [], //已发现的蓝牙设备列表
  11. name: '', //已连接的设备名称
  12. deviceId: '', //已连接的设备deviceId
  13. chs: [],
  14. canWrite: false,
  15. },
  16. /**
  17. * 第一步 判断初始化蓝牙模块是否可用
  18. */
  19. openBluetoothAdapter() {
  20. if (!wx.openBluetoothAdapter) {
  21. wx.showModal({
  22. title: '提示',
  23. content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
  24. })
  25. return
  26. }
  27. this.openBluetoothAdapters()
  28. },
  29. /**
  30. * 第二步 初始化蓝牙模块
  31. */
  32. openBluetoothAdapters() {
  33. this.setData({
  34. ly_text: '搜索设备中'
  35. })
  36. wx.openBluetoothAdapter({ //请求打开蓝牙情况
  37. success: res => {
  38. //console.log('初始化蓝牙模块->res:', res)
  39. this.startBluetoothDevicesDiscovery(); //打开蓝牙后 开始搜索
  40. },
  41. fail: err => {
  42. console.log('初始化蓝牙模块->err:', err)
  43. // 错误码 错误信息 说明
  44. // 0 ok 正常
  45. // -1 already connect 已连接
  46. // 10000 not init 未初始化蓝牙适配器
  47. // 10001 not available 当前蓝牙适配器不可用
  48. // 10002 no device 没有找到指定设备
  49. // 10003 connection fail 连接失败
  50. // 10004 no service 没有找到指定服务
  51. // 10005 no characteristic 没有找到指定特征
  52. // 10006 no connection 当前连接已断开
  53. // 10007 property not support 当前特征不支持此操作
  54. // 10008 system error 其余所有系统上报的异常
  55. // 10009 system not support Android 系统特有,系统版本低于 4.3 不支持 BLE
  56. // 10012 operate time out 连接超时
  57. // 10013 invalid_data 连接 deviceId 为空或者是格式不正确
  58. // object.fail 回调函数返回的 state 参数(仅 iOS)
  59. // 状态码 说明
  60. // 0 未知
  61. // 1 重置中
  62. // 2 不支持
  63. // 3 未授权
  64. // 4 未开启
  65. if (err.errCode === 10001) { //10001 当前蓝牙适配器不可用
  66. wx.showModal({
  67. title: '错误',
  68. content: '当前蓝牙适配器不可用,请打开手机蓝牙后重试!',
  69. showCancel: false
  70. });
  71. //监听蓝牙适配器状态变化事件
  72. wx.onBluetoothAdapterStateChange(res => {
  73. console.log('蓝牙适配器是否可用->res:', res);
  74. if (res.available) { //available=true 蓝牙适配器可用
  75. wx.onBluetoothAdapterStateChange(() => {});
  76. this.startBluetoothDevicesDiscovery();
  77. }
  78. })
  79. } else {
  80. wx.showModal({
  81. title: '错误',
  82. content: `错误码:[${err.errCode}] 错误信息:[${err.errMsg}]`,
  83. showCancel: false
  84. });
  85. }
  86. }
  87. });
  88. },
  89. /**
  90. * 第三步 开始搜寻附近的蓝牙外围设备
  91. */
  92. startBluetoothDevicesDiscovery() {
  93. this.data.discoveryStarted = true
  94. wx.startBluetoothDevicesDiscovery({
  95. success: res => {
  96. console.log('开始搜寻附近的蓝牙外围设备->res', res)
  97. this.onBluetoothDeviceFound(); //蓝牙搜索成功后监听搜索
  98. },
  99. fail: (err) => {
  100. console.log('开始搜寻附近的蓝牙外围设备->err', err)
  101. }
  102. })
  103. },
  104. /**
  105. * 第四步 监听搜索到新设备的事件
  106. */
  107. onBluetoothDeviceFound() {
  108. wx.onBluetoothDeviceFound(res => {
  109. res.devices.forEach(device => {
  110. if (!device.name && !device.localName) {
  111. return
  112. }
  113. let foundDevices = this.data.devices || []
  114. let idx = this.inArray(foundDevices, 'deviceId', device.deviceId);
  115. if (idx === -1) {
  116. this.data.devices.push(device);
  117. console.log('发现新设备:', device); //添加新设备
  118. } else {
  119. this.data.devices[idx] = device; //更新设备数据
  120. }
  121. })
  122. if (this.data.devices.length >= 1) {
  123. this.setData({
  124. blue_list_ly: true,
  125. ly_text: '发现设备'
  126. })
  127. } else {
  128. this.setData({
  129. ly_text: '未发现设备'
  130. })
  131. }
  132. this.setData({
  133. devices: this.data.devices
  134. })
  135. })
  136. },
  137. /**
  138. * 第五步 连接蓝牙低功耗设备
  139. * @param {手动点击连接蓝牙事件}
  140. * @param {创建连接蓝牙}
  141. * @param {如果已经连接过可直接连接}
  142. */
  143. _createBLEConnection(e) {
  144. let idx = e.currentTarget.id
  145. let name = this.data.devices[idx].name
  146. let deviceId = this.data.devices[idx].deviceId
  147. this.setData({
  148. name,
  149. deviceId
  150. })
  151. console.log(name)
  152. //连接蓝牙低功耗设备。
  153. // 若小程序在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备,无需再次进行搜索操作
  154. wx.createBLEConnection({
  155. deviceId,
  156. success: (res) => {
  157. console.log('连接蓝牙低功耗设备->res:', res);
  158. this.setData({
  159. blue_list_ly: false,
  160. connected_ly: true,
  161. ly_text: '已连接'
  162. })
  163. //获取蓝牙->保存到缓存
  164. this.getBLEDeviceServices(deviceId);
  165. wx.setStorage({
  166. key: LAST_CONNECTED_DEVICE,
  167. data: {
  168. name,
  169. deviceId
  170. }
  171. })
  172. },
  173. fail: (err) => {
  174. console.log('连接蓝牙低功耗设备->err', err.errno);
  175. this.setData({
  176. connected_ly: false,
  177. ly_text: '连接失败'
  178. })
  179. }
  180. })
  181. this.stopBluetoothDevicesDiscovery();
  182. },
  183. /**
  184. * 第六步 停止搜寻附近的蓝牙外围设备
  185. * @param {蓝牙连接成功关闭监听搜索}
  186. * @param {蓝牙搜索比较消耗资源}
  187. */
  188. stopBluetoothDevicesDiscovery() {
  189. wx.stopBluetoothDevicesDiscovery({
  190. complete: () => {
  191. console.log('停')
  192. this.data.discoveryStarted = false
  193. }
  194. })
  195. },
  196. /**
  197. * 第七步 断开与蓝牙低功耗设备的连接
  198. * @param {蓝牙连接成功关闭搜索}
  199. * @param {功能}
  200. */
  201. closeBLEConnection(e) {
  202. wx.closeBLEConnection({
  203. deviceId: e.deviceId
  204. })
  205. this.connected_ly = false;
  206. },
  207. /**
  208. * 第八步 获取蓝牙低功耗设备所有服务
  209. * @param {蓝牙功能查询}
  210. * @param {蓝牙连接成功后}
  211. * @param {找到主要服务功能}
  212. */
  213. getBLEDeviceServices(deviceId) {
  214. wx.getBLEDeviceServices({
  215. deviceId,
  216. success: (res) => {
  217. for (let i = 0; i < res.services?.length; i++) {
  218. //该服务是否为主服务
  219. if (res.services[i].isPrimary) {
  220. this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid);
  221. return
  222. }
  223. }
  224. }
  225. })
  226. },
  227. /**
  228. * 第九步 获取蓝牙低功耗设备某个服务中所有特征
  229. * @param {蓝牙功能特征查询}
  230. * @param {主要功能的特性}
  231. * @param {找到主要服务功能的特征}
  232. * @param {到此步骤连接结束}
  233. */
  234. getBLEDeviceCharacteristics(deviceId, serviceId) {
  235. //获取蓝牙低功耗设备某个服务中所有特征 (characteristic)
  236. // read boolean 该特征是否支持 read 操作
  237. // write boolean 该特征是否支持 write 操作
  238. // notify boolean 该特征是否支持 notify 操作
  239. // indicate boolean 该特征是否支持 indicate 操作
  240. // writeNoResponse boolean 该特征是否支持无回复写操作
  241. // writeDefault boolean 该特征是否支持有回复写操作
  242. let name = this.data.name
  243. wx.getBLEDeviceCharacteristics({
  244. deviceId,
  245. serviceId,
  246. success: res => {
  247. console.log('获取蓝牙低功耗设备某个服务中所有特征 (characteristic)->res:', res)
  248. for (let i = 0; i < res.characteristics?.length; i++) {
  249. const item = res.characteristics[i]
  250. if (item.properties.write) {
  251. this.setData({
  252. canWrite: true
  253. })
  254. console.log('可以连接')
  255. this._deviceId = deviceId
  256. this._serviceId = serviceId
  257. this._characteristicId = item.uuid
  258. wx.setStorage({
  259. key: "BlueKey",
  260. data: {
  261. _close: true,
  262. _name: name,
  263. _deviceId: deviceId,
  264. _serviceId: serviceId,
  265. _characteristicId: item.uuid,
  266. }
  267. })
  268. //pring
  269. this.writeBLECharacteristicValue()
  270. break;
  271. }
  272. }
  273. setTimeout(() => {
  274. if (this.data.canWrite) {
  275. this.setData({
  276. connected_ly: true,
  277. ly_text: '已连接'
  278. })
  279. } else {
  280. wx.showToast({
  281. icon: 'error',
  282. title: '您当前选择的设备不支持打印功能,请重新选择!',
  283. duration: 3000
  284. })
  285. }
  286. }, 1000)
  287. },
  288. fail: (res) => {
  289. console.error('获取蓝牙特征失败', res)
  290. }
  291. })
  292. },
  293. /**
  294. * 第十步 编写蓝牙需要打印的内容
  295. * @param {编写蓝牙需要打印的内容}
  296. * @param {打印按钮的事件}
  297. * @param {打印功能前准备}
  298. */
  299. writeBLECharacteristicValue() {
  300. let pd = {
  301. client: '测试',
  302. name: '张三',
  303. sex: '男',
  304. iPhone: '18888888888',
  305. idcard: '888888888888888888',
  306. }
  307. var that = this
  308. setTimeout(() => {
  309. let printerJobs = new PrinterJobs();
  310. let dayun1 = '打印机自检' + pd?.contactinfo?.client + '\r\n' +
  311. '姓名:' + pd?.name + '\r\n' +
  312. '性别:' + pd?.sex + '\r\n' +
  313. '联系方式:' + pd?.iPhone + '\r\n' +
  314. '身份证号码:' + pd?.idcard + '\r\n'
  315. printerJobs
  316. .setSize(2, 2)
  317. .setAlign('CT')
  318. .print('! 0 100 203 100 1\r\n法决定书\r\nPRINT\r\n')
  319. .setSize(1, 1).setAlign('LT')
  320. .print(dayun1)
  321. let buffer = printerJobs.buffer();
  322. // console.log('ArrayBuffer', 'length: ' + buffer.byteLength, ' hex: ' + this.ab2hex(
  323. // buffer));
  324. // 1.并行调用多次会存在写失败的可能性
  325. // 2.建议每次写入不超过20字节
  326. // 分包处理,延时调用
  327. const maxChunk = 20;
  328. const delay = 20;
  329. for (let i = 0, j = 0, length = buffer.byteLength; i < length; i += maxChunk, j++) {
  330. let subPackage = buffer.slice(i, i + maxChunk <= length ? (i + maxChunk) : length);
  331. setTimeout(this._writeBLECharacteristicValue, j * delay, subPackage);
  332. }
  333. // this.lanyardShow = false;
  334. // this.$refs.uUpload.clear();
  335. // this.clearFormData();
  336. wx.showToast({
  337. title: '打印成功',
  338. icon: 'success'
  339. })
  340. }, 5000)
  341. },
  342. /**
  343. * 第十一步
  344. * @param {最终的打印}
  345. * @param {由第十步骤调用}
  346. * @param {轮询打印}
  347. * @param {打印机输出}
  348. * @param {打印结束}
  349. */
  350. _writeBLECharacteristicValue(buffer) {
  351. wx.writeBLECharacteristicValue({
  352. deviceId: this._deviceId,
  353. serviceId: this._serviceId,
  354. characteristicId: this._characteristicId,
  355. value: buffer,
  356. success(res) {
  357. console.log('打印成功->res:', res)
  358. },
  359. fail(res) {
  360. console.log('打印失败', res)
  361. }
  362. })
  363. },
  364. /**
  365. * 第十二步
  366. * @param {蓝牙相关事件}
  367. * @param {和以上打印不衔接}
  368. * @param {关闭蓝牙}
  369. */
  370. closeBluetoothAdapter() {
  371. wx.closeBluetoothAdapter()
  372. this.data.discoveryStarted = false
  373. },
  374. /**
  375. * 第十三步
  376. * @param {判断蓝牙是否已经连接}
  377. * @param {只支持wx. 不支持wx.}
  378. * @param {只支持安卓, 不支持苹果}
  379. */
  380. isBluetoothDevicePaired() {
  381. var that = this
  382. wx.isBluetoothDevicePaired({
  383. deviceId: wx.getStorageSync("BlueKey")?._deviceId,
  384. success(res) {
  385. console.log(res, "判断连接成功")
  386. that.setData({
  387. connected_ly: true,
  388. ly_text: '连接成功'
  389. })
  390. },
  391. fail(err) {
  392. console.log(err, "判断连接失败");
  393. that.setData({
  394. ly_text: '点击搜索'
  395. })
  396. }
  397. })
  398. },
  399. /**
  400. * 第十四步
  401. * @param {蓝牙相关资源事件}
  402. * @param {搜索 资源 打印}
  403. * @param {转换}
  404. */
  405. inArray(arr, key, val) {
  406. for (let i = 0; i < arr.length; i++) {
  407. if (arr[i][key] === val) {
  408. return i
  409. }
  410. }
  411. return -1
  412. },
  413. ab2hex(buffer) { // ArrayBuffer转16进度字符串示例
  414. const hexArr = Array.prototype.map.call(
  415. new Uint8Array(buffer),
  416. function (bit) {
  417. return ('00' + bit.toString(16)).slice(-2)
  418. }
  419. )
  420. return hexArr.join(',')
  421. },
  422. str2ab(str) {
  423. let buffer = new ArrayBuffer(str?.length)
  424. let dataView = new DataView(buffer)
  425. for (let i = 0; i < str?.length; i++) {
  426. dataView.setUint8(i, str?.charAt(i).charCodeAt(0))
  427. }
  428. return buffer;
  429. },
  430. /**
  431. * 第十五步
  432. * @param {进入页面就自动连接}
  433. * @param {该方法存在BUG}
  434. * @param {目前该方法先不投放使用}
  435. */
  436. createBLEConnectionWithDeviceId(e) {
  437. //创建蓝牙链接
  438. wx.openBluetoothAdapter({
  439. success: (res) => {
  440. let ly_data = {
  441. name: wx.getStorageSync("BlueKey")?._deviceId,
  442. deviceId: wx.getStorageSync("BlueKey")?._name
  443. }
  444. this._createBLEConnection(ly_data);
  445. },
  446. fail: (res) => {
  447. if (res.errCode === 10001) {
  448. wx.showModal({
  449. title: '错误',
  450. content: '未找到蓝牙设备, 请打开蓝牙后重试。',
  451. showCancel: false
  452. });
  453. this.connected_ly = false
  454. } else if (res.errCode === -1 || res.errCode === 10010) { //已连接
  455. this.data.connected_ly = true;
  456. }
  457. }
  458. })
  459. },
  460. /**
  461. * 第十六步
  462. * @param {获取蓝牙适配状态}
  463. * @param {在蓝牙连接成功后调用查看}
  464. * @param {判断连接用}
  465. */
  466. getBluetoothAdapterState() {
  467. wx.getBluetoothAdapterState({
  468. success: (res) => {
  469. console.log(res)
  470. if (res.available) {
  471. this.data.connected_ly = true
  472. this.data.ly_text = "已连接"
  473. console.log("蓝牙已经连接", res)
  474. } else {
  475. this.connected_ly = false;
  476. this.data.ly_text = "点击连接"
  477. console.log("蓝牙已经断开")
  478. }
  479. }
  480. })
  481. },
  482. })

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/965535
推荐阅读
相关标签
  

闽ICP备14008679号