123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- class BluetoothTools {
- constructor() {
- this.commands = {
- init: [0x1b, 0x40], // 清理buffer数据,重置模式;ASC2: ESC @
- print: [0x0a], //开始打印;
- printL5: [0x1b, 0x64, 0x05],
- printL6: [0x1b, 0x64, 0x06],
- printL8: [0x1b, 0x64, 0x08],
- printL10: [0x1b, 0x64, 0x10],
- }
- this.decimalData = []; //获取buffer之前的二进制数据集合;
- this.deviceId = null;
- this.initStatus = 0; //蓝牙初始化结果;0:初始化中,1-成功;2-失败;
- this.linked = false; //蓝牙是否为连接状态;
- this.timer = null;
- this.writeTime = 0;
- this.byteLength = this.isAndroid() ? 200 : 500;
- this.connectChangeHandler = null;
- }
- /**
- * 低功耗蓝牙API
- */
- // 根据deviceId 设置传输字节最大值;
- setMTU(deviceId) {
- return new Promise((resolve, reject) => {
- uni.setBLEMTU({
- deviceId: deviceId,
- mtu: 512,
- success: (res) => {
- console.log('设置MTu成功', res);
- resolve(res)
- },
- fail: (err) => {
- console.log('设置mtu失败', err);
- this.toaset('设置mtu失败!')
- reject(err)
- }
- })
- })
- }
- // 根据deviceId/mac地址 查询serviceId列表;
- getServiceId(deviceId) {
- return new Promise((resolve, reject) => {
- uni.getBLEDeviceServices({
- deviceId: deviceId,
- success: res => {
- resolve(res)
- },
- fail: err => {
- console.log('获取serviceId失败', err);
- reject(err)
- }
- })
- })
- }
- // 根据deviceId 和 serviceId 获取特征Id;
- getCharId(deviceId, serviceId) {
- return new Promise((resolve, reject) => {
- uni.getBLEDeviceCharacteristics({
- deviceId: deviceId,
- serviceId: serviceId,
- success: res => {
- resolve(res)
- },
- fail: err => {
- console.log('获取特征id失败', err);
- reject(err)
- }
- })
- })
- }
- // 写入数据;
- writeBLE(deviceId, serviceId, charId, buffer) {
- // console.log(deviceId, serviceId, charId, buffer.byteLength);
- // return;
- let _this = this;
- return new Promise((resolve, reject) => {
- uni.writeBLECharacteristicValue({
- deviceId: deviceId, //设备Id、mac地址;
- serviceId: serviceId, //服务id;
- characteristicId: charId, //特征id;
- value: buffer, //指令buffer数据;
- writeType: 'write', //'writeNoResponse',
- success: res => {
- // console.log('数据写入成功', res);
- _this.writeTime = 0;
- resolve(res)
- },
- fail: err => {
- console.log('写入失败:', Date.now());
- reject(err);
- }
- })
- })
- }
-
- /**
- * 具体功能实现
- */
- // 打印传入的位图信息
- async printImage(res) {
- if (!this.deviceId) {
- this.toast('未检测到蓝牙设备id');
- this.hideLoading()
- return;
- }
- this.isAndroid() && await this.setMTU(this.deviceId);
- const imgArr = this.getImgArray(res);
- // return;
- const { serviceId, charId } = await this.getWriteIds(this.deviceId);
- this.startPrint(this.deviceId, serviceId, charId, imgArr);
- }
- // 开始打印;
- async startPrint(deviceId, serviceId, charId, cmd) {
- // 初始化;
- let initArr = Array.from(this.commands.init).concat(Array.from(this.commands.print));
- let initBuffer = new Uint8Array(initArr).buffer;
- await this.writeMidWare(deviceId, serviceId, charId, initBuffer)
- // let cmds = Array.from(this.commands.init).concat(Array.from(cmd)).concat(Array.from(this.commands.printL10));
- // 分别传输指令;
- let cmds = Array.from(cmd);
- console.log(cmds.length);
- if (cmds.length > this.byteLength) {
- let cmdArrs = [];
- let newCmds = Array.from(cmds);
- let length = Math.ceil(cmds.length / this.byteLength);
- for (let i = 0; i < length; i++) {
- cmdArrs.push(newCmds.slice(this.byteLength * i, this.byteLength * (i + 1)));
- }
- for (let i = 0; i < cmdArrs.length; i++) {
- console.log(i, cmdArrs.length);
- let buffer = new Uint8Array(cmdArrs[i]).buffer;
- await this.writeMidWare(deviceId, serviceId, charId, buffer)
- }
- } else {
- let buffer = new Uint8Array(cmds).buffer;
- cmds.length && await this.writeMidWare(deviceId, serviceId, charId, buffer)
- }
- // 打印空行;
- let printLCmd = Array.from(this.commands.printL5);
- let printLBuffer = new Uint8Array(printLCmd).buffer;
- await this.writeMidWare(deviceId, serviceId, charId, printLBuffer);
- }
- // 处理安卓写入失败的问题;
- writeMidWare(deviceId, serviceId, charId, buffer) {
- let _this = this;
- return new Promise((resolve, reject) => {
- this.writeBLE(deviceId, serviceId, charId, buffer).then(res => {
- resolve(res)
- }).catch(err => {
- // console.log(111111, _this.writeTime);
- if (_this.writeTime < 50) {
- _this.writeTime++;
- return new Promise((reso, reje) => {
- clearTimeout(this.timer)
- this.timer = setTimeout(() => {
- reso(this.writeMidWare(deviceId, serviceId, charId, buffer))
- }, 100)
- })
- } else {
- _this.writeTime = 0;
- _this.hideLoading();
- _this.toast('数据写入失败,请走纸后重试!');
- reject(err);
- }
- }).then(res => {
- resolve(res)
- })
- })
- }
- // 位图信息转换为打印指令;
- getImgArray(res) {
- var w = res.width;
- var width = parseInt((res.width + 7) / 8 * 8 / 8);
- var height = res.height;
- let data = [29, 118, 48, 0];
- // let data = [0x1d, 0x76, 0x30, 0];
- data.push(parseInt(width % 256));
- data.push(parseInt(width / 256));
- data.push(parseInt(res.height % 256));
- data.push(parseInt(res.height / 256));
- var bits = new Uint8Array(height * width);
- for (let y = 0; y < height; y++) {
- for (let x = 0; x < w; x++) {
- var color = res.data[(y * w + x) * 4 + 1];
- if (color > 128) {
- bits[parseInt(y * width + x / 8)] |= (0x80 >> (x % 8));
- }
- }
- }
- for (let i = 0; i < bits.length; i++) {
- data.push((~bits[i]) & 0xFF)
- }
- return data;
- }
- // 获取写入数据需要的ids;
- async getWriteIds(deviceId) {
- return new Promise(async (resolve, reject) => {
- let serviceIdData = await this.getServiceId(deviceId);
- let services = serviceIdData.services;
- // console.log(services);
- let charId,
- serviceId;
- for (let i = 0; i < services.length; i++) {
- const chars = await this.getCharId(deviceId, services[i].uuid);
- // console.log(services[i].uuid, chars);
- const charItem = chars.characteristics.filter(item => item.properties.write)[0];
- if (charItem) {
- charId = charItem.uuid;
- serviceId = services[i].uuid;
- // break;
- // console.log(charId, serviceId);
- }
- }
- resolve({ charId: charId, serviceId: serviceId })
- })
- }
- isAndroid() {
- return uni.getSystemInfoSync().osName === 'android'
- }
- }
- export default BluetoothTools;
|