钉钉小程序连接蓝牙打印机并打印内容

关于钉钉小程序连接蓝牙打印机并打印内容。
微信小程序和钉钉小程序在连接蓝牙和打印内容的方面基本一样,同样的套路和思路在微信小程序上可以连接并打印,但是钉钉小程序可以连接单无法打印。

第一步
这里我获取到了所有的服务,和服务的特征值,以及write为true的端口。

img

第二步
然后我调用api方法尝试写入

img

第三步
调用后的返回值如下。

img

但是蓝牙打印机没有任何反应,微信小程序连接并用本套方案可以顺利打印,但是两边的写入值的格式有所不同,望高人帮助,建议私信,如果解决定会追加酬谢。

这是钉钉开发平台蓝牙有关方面文档:https://open.dingtalk.com/document/isvapp/jsapi-overview-2
参考教程:http://www.taodudu.cc/news/show-5752812.html?action=onClick

这篇文章里面写的很详细, 也有具体的实现代码,可以照着来写,你看一下:


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

微信小程序和钉钉小程序在连接蓝牙和打印内容方面可能会有一些差异,因为它们的技术架构和开发规范不同。虽然您在微信小程序上能够连接并打印,但在钉钉小程序上连接成功但不能打印,这可能是由于以下原因:

  1. 权限问题:请确保您的钉钉小程序有足够的权限访问蓝牙设备,并进行打印操作。您可以在钉钉小程序的后台设置中检查并确保相关的权限已经正确配置。
  2. 打印API问题:钉钉小程序可能使用的是与微信小程序不同的打印API。请检查您在钉钉小程序中使用的打印API是否与您的设备兼容,并确保API的使用方式正确。
  3. 设备问题:请确保您的打印机与钉钉小程序兼容,并且打印机已正确连接并配置。尝试将打印机连接到其他设备,或者使用其他应用程序进行打印,以检查打印机是否存在问题。
  4. 网络问题:请检查您的网络连接是否稳定,并且钉钉小程序能够与您的设备和打印机进行通信。

如果您仍然无法在钉钉小程序上打印,建议您参考钉钉小程序的官方文档或者寻求钉钉小程序开发者的帮助,以便更好地解决问题。

参考gpt:
结合自己分析给你如下建议:
您可能没有正确设置钉钉小程序的蓝牙权限。您需要在钉钉小程序的app.json文件中添加以下代码,以开启蓝牙相关的API:

"permission": {
  "bluetooth": {
    "desc": "你的应用需要使用蓝牙功能"
  }
}



您可能没有正确编码您要写入蓝牙打印机的数据。您需要将您要打印的内容转换为二进制数据,并使用base64编码,然后传递给dd.writeBLECharacteristicValue函数。例如,假设您要打印"Hello World",那么您可以使用以下代码来编码和写入:

// 将字符串转换为二进制数据
function stringToBytes(str) {
  var bytes = new Uint8Array(str.length);
  for (var i = 0; i < str.length; i++) {
    bytes[i] = str.charCodeAt(i);
  }
  return bytes;
}

// 将二进制数据转换为base64编码
function bytesToBase64(bytes) {
  return dd.arrayBufferToBase64(bytes.buffer);
}

// 要打印的内容
var content = "Hello World";
// 转换为二进制数据
var bytes = stringToBytes(content);
// 转换为base64编码
var base64 = bytesToBase64(bytes);
// 写入蓝牙打印机
dd.writeBLECharacteristicValue({
  deviceId: deviceId,
  serviceId: serviceId,
  characteristicId: characteristicId,
  value: base64,
  success: function(res) {
    console.log(res);
  },
  fail: function(res) {
    console.log(res);
  }
});

您可能没有正确设置蓝牙打印机的参数。您需要根据您的蓝牙打印机的型号和规格,发送一些控制指令来设置打印机的字体、对齐、行距等参数。例如,假设您要设置字体为16x16点阵,居中对齐,行距为30点,那么您可以使用以下代码来发送控制指令:

// 字体指令,16x16点阵
var font = [0x1B, 0x4D, 0x01];
// 对齐指令,居中对齐
var align = [0x1B, 0x61, 0x01];
// 行距指令,30点
var line = [0x1B, 0x33, 0x1E];
// 合并指令为一个数组
var commands = font.concat(align).concat(line);
// 转换为base64编码
var base64 = bytesToBase64(new Uint8Array(commands));
// 写入蓝牙打印机
dd.writeBLECharacteristicValue({
  deviceId: deviceId,
  serviceId: serviceId,
  characteristicId: characteristicId,
  value: base64,
  success: function(res) {
    console.log(res);
  },
  fail: function(res) {
    console.log(res);
  }
});

引用 皆我百晓生 小程序回复内容作答:
很抱歉,我无法提供具体的代码实现,但是我可以给你一些思路来尝试解决这个问题。

首先,你需要通过钉钉小程序的蓝牙接口进行蓝牙设备的连接和通信。根据你提供的信息,你已经成功连接蓝牙设备并获取到了相关的服务和特征值。但是尝试写入时没有反应,这可能是因为写入的格式不正确。

针对这个问题,你可以参考蓝牙设备的官方文档和手册,查看设备支持的写入格式和指令格式。通常情况下,蓝牙设备都会有一些特定的指令格式来控制打印内容和格式。

你可以尝试调整写入的内容和格式,确保与设备要求的格式相符。可以尝试一些简单的指令来打印一些基本的内容,比如文本、图像等。

同时,可以尝试设置一些打印机的参数,比如字体大小、样式、打印方向等,以确保打印输出的效果符合预期。

另外,还可以尝试使用一些第三方的蓝牙打印插件或SDK来简化连接和通信的过程,这些插件或SDK通常会提供一些简单易用的接口来实现打印功能。

最后,如果你还是无法解决问题,建议你在相关的开发论坛或社区发帖求助,或者联系钉钉小程序的技术支持团队,他们可能会给你进一步的指导和帮助。

结合GPT给出回答如下请题主参考
连接蓝牙打印机并打印内容需要以下几步操作:

  1. 获取当前设备的蓝牙适配器状态,并且判断是否已经打开。
  2. 调用蓝牙适配器的 startBluetoothDevicesDiscovery 方法开始搜寻附近的蓝牙设备。
  3. 监听寻找到新设备的事件,在事件回调中处理新设备的信息。
  4. 调用蓝牙适配器的 createBLEConnection 方法建立与目标蓝牙设备的连接。
  5. 监听蓝牙连接状态的改变,在连接成功后调用蓝牙设备的相关 API,如获取服务列表、特征值等信息。
  6. 调用特定蓝牙服务的特定特征值进行数据的读写操作,从而实现打印内容的功能。

需要注意的是在进行蓝牙打印的时候,需要根据不同的蓝牙打印机进行相应的设置和操作,比如设置打印纸张的大小、选择打印字体、设置打印模式等等,这些操作都需要参考具体的蓝牙打印机的说明文档进行处理。

值得一提的是在钉钉小程序中,打印内容相关的操作有一定的局限性,因为钉钉小程序并没有提供与本地的打印设备直接进行交互的接口,所以在使用钉钉小程序进行打印的时候,可能需要借助第三方的服务或者通过其他方式实现。

题主,这个问题我来替你解决(参考结合AI智能、文心一言),若有帮助,还望采纳,点击回答右侧采纳即可。


这是因为钉钉小程序的API能力有限,无法直接与打印机通信。相对而言,微信小程序的API能力更加强大,可以直接调用蓝牙接口实现连接和打印。所以,如果您需要在小程序中连接和打印,建议选择微信小程序。

它们的API和一些细节可能略有不同
蓝牙打印机通常需要按照特定的通信协议和数据格式来接收和处理打印任务。确保在钉钉小程序中使用的数据格式与蓝牙打印机所需的格式一致。这可能需要查看蓝牙打印机的文档以获取更多信息。
蓝牙设备可能对不同的平台和操作系统有不同的适配性要求。确保您的蓝牙打印机支持与钉钉小程序的通信。
UUID的设置、服务特征值的获取、数据写入等步骤。确保与钉钉小程序的API文档保持一致。

支付宝/钉钉小程序实现蓝牙打印

连接蓝牙打印机的js
Page({
  data: {
    list: [],
    loading: false,//搜索状态
    write: false,//写入的值是否已经确定
    characteristicId: '',
    serviceId: '',
    deviceId: '',
    services: [],
    num: 0,
    printer: ''
  },
  onLoad() {
    //初始化蓝牙
    dd.openBluetoothAdapter({
      success: (res) => {
        //获取本季蓝牙模块的状态
        dd.getBluetoothAdapterState({
          success: (res) => {
            //是否可用
            if (res.available) {
              //是否正在搜索
              this.setData({
                loading: res.discovering
              })
              /*if (res.discovering) {
                //停止搜索
                dd.stopBluetoothDevicesDiscovery({
                  success: (res) => {
                    console.log(res)
                  },
                  fail: (res) => {
                  },
                  complete: (res) => {
                  }
                });
              }*/
              //获取已经搜索到的设备
              this.getBluetoothDevices();
            } else {
              dd.alert({
                title: '提示',
                content: '手机蓝牙模块不可用!'
              })
            }
          },
          fail: (res) => {
            console.log(res)
          },
          complete: (res) => {
            console.log(res)
          }
        });
      },
      fail: (res) => {
        if (res.error == 12) {
          dd.alert({
            title: '提示',
            content: '蓝牙未打开,请尝试打开蓝牙。'
          })
        }
        else if (res.error == 13) {
          dd.alert({
            title: '提示',
            content: '与系统服务的链接暂时丢失,请尝试重新连接。'
          })
        } else if (res.error == 14) {
          dd.alert({
            title: '提示',
            content: '未授权使用蓝牙功能。请授权使用蓝牙功能。'
          })
        } else if (res.error == 10000) {
          dd.alert({
            title: '提示',
            content: '未初始化蓝牙适配器'
          })
        } else {
          dd.alert({
            title: '提示',
            content: '未知错误!'
          })
        }
      },
      complete: (res) => {
      }
    });
    //监听搜索到的设备
    this.callback = this.callback.bind(this);
    dd.onBluetoothDeviceFound(this.callback);
  },
  callback(res) {
    //监听新设备事件
    //console.log(res);
    var list = this.data.list;
    res.devices.forEach(element => {
      //判断list中的id没有这个才可以
      var ok = true;
      for (var i = 0; i < list.length; i++) {
        //console.log(list[i].deviceId, element.deviceId)
        if (list[i].deviceId == element.deviceId) {
          ok = false;
        }
      }
      if (ok && element.localName != '' && element.name != null) {
        list.push(element);
      }
    });
    this.setData({
      list: list
    })
    //console.log(list)
  },
  getBluetoothDevices() {
    //android 6.0需要授权地理位置权限
    dd.getBluetoothDevices({
      success: (res) => {
        this.callback(res);
      },
      fail: (res) => {
        console.log(res)
        dd.alert({
          title: '提示',
          content: '位置权限未开启!请给钉钉开启定位权限'
        })
      },
      complete: (res) => {
        console.log(res)
      }
    });
  },
  onClick(e) {
    console.log(e)
    this.setData({
      deviceId: e.target.dataset.item.deviceId,
      printer: e.target.dataset.item.name
    })
    this.stopBluetoothDevicesDiscovery();//停止搜索蓝牙
    //链接蓝牙设备
    dd.showLoading();
    dd.connectBLEDevice({
      //判断蓝牙搜索的状态如果是正在搜索那么就关闭掉搜索
      // 这里的 deviceId 可通过 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
      deviceId: e.target.dataset.item.deviceId,
      success: (res) => {
        //获取设备的特征值用于收发数据
        dd.getBLEDeviceServices({
          deviceId: e.target.dataset.item.deviceId,
          success: (res) => {
            this.setData({
              services: res.services
            })
            //遍历特征值看都是什么类型的。只需要写入类型
            this.getBLEDeviceServices();
          },
          fail: (res) => {
            console.log(res)
          }, complete: (res) => {
            dd.hideLoading()
          }
        })
      },
      fail: (res) => {
        dd.alert({
          title: '提示',
          content: res.errorMessage
        })
      },
      complete: (res) => {
      }
    });
  },
  getBLEDeviceServices() {
    dd.getBLEDeviceCharacteristics({
      deviceId: this.data.deviceId,
      serviceId: this.data.services[this.data.num].serviceId,
      success: (res) => {
        console.log(res)
        for (var j = 0; j < res.characteristics.length; j++) {
          //判断特征值是否支持写入,读取,通知,操作,如果支持就可以了
          if (res.characteristics[j].properties.write && !this.data.write) {
            //characteristicId = res.characteristics[0].characteristicId;
            //serviceId = res.characteristics[0].serviceId;
            this.setData({
              write: true,
              characteristicId: res.characteristics[j].characteristicId,
              serviceId: res.characteristics[j].serviceId,
            })
          }
        }
        if (this.data.write) {
          dd.showToast({
            type: 'success',
            content: '连接成功!'
          })
          //返回上一个页面
          let pages = getCurrentPages();//获取当前页面js里面的pages里的所有信息。
          //prevPage 是获取上一个页面的js里面的pages的所有信息。 -2 是上一个页面,-3是上上个页面以此类推
          let prevPage = pages[pages.length - 2];
          prevPage.setData({
            characteristicId: this.data.characteristicId,
            deviceId: this.data.deviceId,
            printer: this.data.printer,
            serviceId: this.data.serviceId,
            printtype: '1',
            'printtypes[1].checked': true,
            'printtypes[0].checked': false,
          })
          console.log(this.data.serviceId);
          console.log(this.data.characteristicId)
          dd.navigateBack();
        } else {
          if (this.data.num < this.data.services.length) {
            this.setData({
              num: this.data.num + 1
            })
            this.getBLEDeviceServices();
          }
        }
      }
    })
  },
  stopBluetoothDevicesDiscovery() {
    //停止搜索
    dd.stopBluetoothDevicesDiscovery({
      success: (res) => {
        //获得蓝牙的状态
        dd.getBluetoothAdapterState({
          success: (res) => {
            //是否可用
            if (res.available) {
              //是否正在搜索
              this.setData({
                loading: res.discovering
              })
              //获取已经搜索到的设备
              this.getBluetoothDevices();
            } else {
              dd.alert({
                title: '提示',
                content: '手机蓝牙模块不可用!'
              })
            }
          },
          fail: (res) => {
            console.log(res)
          },
          complete: (res) => {
            console.log(res)
          }
        });
      },
      fail: (res) => {
      },
      complete: (res) => {
      }
    });
  },
  onseaer() {
    //如果但当前正在搜索蓝牙,那么点击就是停止搜索
    if (this.data.loading) {
      this.stopBluetoothDevicesDiscovery();
    } else {
      //开启蓝牙搜索
      dd.startBluetoothDevicesDiscovery({
        //services: ['fff0'],
        success: (res) => {
          //获得蓝牙的状态
          //获取本季蓝牙模块的状态
          dd.getBluetoothAdapterState({
            success: (res) => {
              //是否可用
              if (res.available) {
                //是否正在搜索
                this.setData({
                  loading: res.discovering
                })
                /* if (res.discovering) {
                   //停止搜索
                   dd.stopBluetoothDevicesDiscovery({
                     success: (res) => {
                       console.log(res)
                     },
                     fail: (res) => {
                     },
                     complete: (res) => {
                     }
                   });
                 }*/
                //获取已经搜索到的设备
                this.getBluetoothDevices();
              } else {
                dd.alert({
                  title: '提示',
                  content: '手机蓝牙模块不可用!'
                })
              }
            },
            fail: (res) => {
              console.log(res)
            },
            complete: (res) => {
              console.log(res)
            }
          });
        },
        fail: (res) => {
        },
        complete: (res) => {
        }
      });
    }
  }
});
发送打印标签打印数据js
import { GetSkuList } from "../../../api/api";
import { GetPrintGood } from "../../../api/api"
import { jpPrinter } from "../../../util/tsc"
Page({
  data: {
    hidden: true, //款号选者是否隐藏
    ITCODE_IT: '',
    Price: 0,
    printtypes: [{ value: '0', label: 'WIFI', checked: true }, { value: '1', label: '蓝牙' }],
    printtype: '0',
    printer: '',
    characteristicId: '',
    deviceId: '',
    serviceId: '',
    time: 20,//限制在20字节内
    looptime: 0,//发送字节整数数量
    lastData: 0,//余数
    currentTime: 1,//发送次数
  },
  onLoad() {
    // 注意: 回调方法的注册在整个小程序启动阶段只要做一次,调多次会有多次回调
    dd.onSocketClose((res) => {
      dd.showToast({ type: 'exception', content: '连接打印机失败' });
      this.setData({
        sendMessageAbility: false,
        closeLinkAbility: false,
      });
    });
    // 注意: 回调方法的注册在整个小程序启动阶段只要做一次,调多次会有多次回调
    dd.onSocketOpen((res) => {
      dd.showToast({ type: 'success', content: '已连接打印机!' });
      this.setData({
        sendMessageAbility: true,
        closeLinkAbility: true,
      });
    });
    dd.onSocketError(function (res) {
      dd.showToast({ type: 'exception', content: 'WebSocket 连接打开失败,请检查!' + res });
    });
    // 注意: 回调方法的注册在整个小程序启动阶段只要做一次,调多次会有多次回调
    dd.onSocketMessage((res) => {
      //dd.alert({ content: '收到数据!' + JSON.stringify(res) });
    });
  },
  connect_start() {
    dd.connectSocket({
      url: 'ws://namemeiprintserver1.vaiwan.com', // 开发者服务器接口地址,必须是 wss 协议,且域名必须是后台配置的合法域名
      success: (res) => {
      }
    });
  },
  onPickerTap(e) {
    if (e.currentTarget.dataset.type == 'item') {
      //设置弹出的单选界面为显示
      this.setData(
        {
          hidden: false
        });
    }
    else {
      //跳转到蓝牙打印机
      dd.navigateTo(
        {
          url: '../lianjielanyadayinji/lianjielanyadayinji'
        }
      )
    }
  }, onShowSlect(e)//选者界面回掉韩素
  {
    this.setData({
      hidden: true
    })
    //console.log(e);
    if (e == null) {
      return
    }
    //请求这个款的sku
    var IT_CODE = e.value.split(" ")[0];
    GetSkuList({
      ItCode: IT_CODE
    }).then(res => {
      //console.log(res);
      this.setData(
        {
          ITCODE_IT: IT_CODE,
          Skus: res.data.Data.Skus,
          Price: res.data.Data.ip_priceb
        }
      )
    })

  }, //同步输入的数字
  onInputqty(e) {
    var str = 'Skus[' + e.target.dataset.index + '].qty';
    this.setData(
      {
        [str]: e.detail.value
      }
    )
  },//发送打印的数据
  ontap() {
    //用条码来请求符合要求的数据
    var str = '';
    this.data.Skus.forEach(element => {
      if (element.qty != null && element.qty > 0) {
        str += element.Sku + "','";
      }
    });
    if (this.data.Price <= 0 || this.data.Price > 9000) {
      dd.alert({ title: '价格不对请先修改!' })
      return;
    }
    if (str.length > 0) {
      var app = getApp();
      GetPrintGood({
        Code: str,
        type: 0
      }).then(res => {
        if (res.data.ErrorCode == 0) {
          //把数量都添加到对应的地方上面
          var oksku = [];
          res.data.Data.forEach(item => {
            this.data.Skus.forEach(list => {
              if (item.商品条码 == list.Sku) {
                item.数量 = list.qty
                oksku.push(item);
              }
            })
          })
          //如果是wifi
          if (this.data.printtype == 0) {
            this.connect_start();
            dd.sendSocketMessage({
              data: JSON.stringify(oksku), // 需要发送的内容
              success: (res) => {
                dd.showToast({ type: 'success', content: '发送成功!' });
              },
            });
          } else {
            if (this.data.characteristicId == '' || this.data.deviceId == '' || this.data.serviceId == '') {
              dd.showToast({
                type: 'fail',
                content: '打印机未连接!'
              })
            }
            else {
              console.log(oksku);
              this.setData({
                oksku: oksku,
                printnum: 0
              })
              dd.showLoading();
              this.printsku();
            }
          }
        }
        else {
          dd.alert({
            title: '请输入要打印的数量'
          })
        }
      })
    }
  },
  printsku() {
    //通过蓝牙发送数据

    var command = jpPrinter.createNew();
    command.setSize(60, 40);
    command.setGap(0);
    command.setCls();
    command.setText(0, 30, "TSS24.BF2", 1, 1, "品名:" + this.data.oksku[this.data.printnum].商品名称);
    //command.setText(0, 60, "TSS24.BF2", 1, 1, "款号:" + this.data.oksku[this.data.printnum].款号);
    command.setText(240, 70, "TSS24.BF2", 1, 1, "尺码:" + this.data.oksku[this.data.printnum].尺码描述);
    command.setText(0, 70, "TSS24.BF2", 1, 1, "颜色:" + this.data.oksku[this.data.printnum].颜色描述);
    command.setBar(0, 100, 128, 120, 1, 2, 1, this.data.oksku[this.data.printnum].商品条码);
    command.setText(240, 260, "TSS16.BF2", 2, 2, "零售价:" + this.data.oksku[this.data.printnum].建议零售价);
    command.setPagePrint(this.data.oksku[this.data.printnum].数量);
    var buffer = command.getData();
    var looptime = parseInt(buffer.length / this.data.time);//发送次数
    var lastData = parseInt(buffer.length % this.data.time);//余数
    this.setData({
      looptime: looptime + 1,
      lastData: lastData,
      currentTime: 1
    })
    //console.log(buffer.length);
    this.send(buffer);

  },
  radioChannge(e) {
    //打印方式修改
    this.setData(
      {
        printtype: e.detail.value,
      })
  },
  send(buff) {
    var buf;
    if (this.data.currentTime < this.data.looptime) {
      //如果当前发送次数小于总共需要发送的次数
      buf = buff.substring((this.data.currentTime - 1) * this.data.time, this.data.currentTime * this.data.time);
    } else { //否者发送剩余的字节
      buf = buff.substring((this.data.currentTime - 1) * this.data.time, (this.data.currentTime - 1) * this.data.time + this.data.lastData);
    }
    console.log(buf)
    //console.log('第' + this.data.currentTime + '次发送数据大小为:' + buf.byteLength);
    dd.writeBLECharacteristicValue({
      deviceId: this.data.deviceId,
      serviceId: this.data.serviceId,
      characteristicId: this.data.characteristicId,
      value: buf,
      success: (res) => {
        console.log(res)
      },
      fail: (res) => {
        console.log(res)
      },
      complete: (res) => {
        if (this.data.currentTime < this.data.looptime) {
          //如果当前发送的次数小于或者等于总共要发送的次数,那么就进行加一
          this.data.currentTime++;
          //console.log(this.data.currentTime);
          //开始下一次的发送
          this.send(buff);
        } else {
          //打印下一个条码
          this.data.printnum++;
          if (this.data.printnum < this.data.oksku.length) {
            this.printsku();
          }
          else {
            dd.hideLoading()
            //发送完毕
            dd.showToast({
              type: 'success',
              content: '发送陈工'
            })
          }
        }
      }
    })
  }
});


没反应的话,那为什么console.log输出了成功。你是不是连接到别的打印机了哦