uni-app框架实现app蓝牙打印功能

蓝牙打印

## 关于uni-app框架

这里就不多说什么了 官网的文档写的很清楚

app连接低功耗蓝牙打印

  1. **蓝牙打印机型号很多 这里就介绍两种型号 佳博,斑马 **

  2. 1,先初始化蓝牙设置

  3. //蓝牙模式

  4. var encode = require("./encoding.js")
    // var app = getApp();
    var jpPrinter = {
    createNew: function () {
    var jpPrinter = {};
    var data = [];

    var bar = [“UPC-A”, “UPC-E”, “EAN13”, “EAN8”, “CODE39”, “ITF”, “CODABAR”, “CODE93”, “CODE128”];

    jpPrinter.name = “账单模式”;

    jpPrinter.init = function () { //初始化打印机
    data.push(27)
    data.push(64)
    };

    jpPrinter.setText = function (content) { //设置文本内容
    var code = new encode.TextEncoder(
    ‘gb18030’, {
    NONSTANDARD_allowLegacyEncoding: true
    }).encode(content)
    for (var i = 0; i < code.length; ++i) {
    data.push(code[i])
    }
    }

    jpPrinter.setUnderlineMode = function (n) { // 选择/取消下划线模式
    data.push(28)
    data.push(45)
    data.push(n)
    // 0,48 取消下划线模式
    // 1,49 选择下划线模式(1 点宽)
    // 2,50 选择下划线模式(2 点宽)
    }

    jpPrinter.setBarcodeWidth = function (width) { //设置条码宽度
    data.push(29)
    data.push(119)
    if (width > 6) {
    width = 6;
    }
    if (width < 2) {
    width = 1;
    }
    data.push(width)
    }

    jpPrinter.setBarcodeHeight = function (height) { //设置条码高度
    data.push(29)
    data.push(104)
    data.push(height)
    }

    jpPrinter.setBarcodeContent = function (content) {
    var code = new encode.TextEncoder(
    ‘gb18030’, {
    NONSTANDARD_allowLegacyEncoding: true
    }).encode(content)
    // var ty = 73;
    data.push(29)
    data.push(107)
    // switch (t) {
    // case bar[0]:
    // ty = 65;
    // break;
    // case bar[1]:
    // ty = 66;
    // break;
    // case bar[2]:
    // ty = 67;
    // break;
    // case bar[3]:
    // ty = 68;
    // break;
    // case bar[4]:
    // ty = 69;
    // break;
    // case bar[5]:
    // ty = 70;
    // break;
    // case bar[6]:
    // ty = 71;
    // break;
    // case bar[7]:
    // ty = 72;
    // break;
    // case bar[8]:
    // ty = 73;
    // break;
    // }
    data.push(2) // 固定 打印JAN13(EAN13)的条码类型
    for (var i = 0; i < code.length; ++i) {
    data.push(code[i])
    }
    data.push(0)

    }

    jpPrinter.setSelectSizeOfModuleForQRCode = function (n) { //设置二维码大小
    data.push(29)
    data.push(40)
    data.push(107)
    data.push(3)
    data.push(0)
    data.push(49)
    data.push(67)
    if (n > 15) {
    n = 15
    }
    if (n < 1) {
    n = 1
    }
    data.push(n)
    }

    jpPrinter.setSelectErrorCorrectionLevelForQRCode = function (n) { //设置纠错等级
    /*
    n 功能 纠错能力
    48 选择纠错等级 L 7
    49 选择纠错等级 M 15
    50 选择纠错等级 Q 25
    51 选择纠错等级 H 30
    */
    data.push(29)
    data.push(40)
    data.push(107)
    data.push(3)
    data.push(0)
    data.push(49)
    data.push(69)
    data.push(n)
    }

    jpPrinter.setStoreQRCodeData = function (content) { //设置二维码内容
    var code = new encode.TextEncoder(
    ‘gb18030’, {
    NONSTANDARD_allowLegacyEncoding: true
    }).encode(content)
    data.push(29)
    data.push(40)
    data.push(107)
    data.push(parseInt((code.length + 3) % 256))
    data.push(parseInt((code.length + 3) / 256))
    data.push(49)
    data.push(80)
    data.push(48)

    for (var i = 0; i < code.length; ++i) {
    data.push(code[i])
    }
    }

    jpPrinter.setPrintQRCode = function () { //打印二维码
    data.push(29)
    data.push(40)
    data.push(107)
    data.push(3)
    data.push(0)
    data.push(49)
    data.push(81)
    data.push(48)
    }

    jpPrinter.setHorTab = function () { //移动打印位置到下一个水平定位点的位置
    data.push(9)
    }

    jpPrinter.setAbsolutePrintPosition = function(where) { //设置绝对打印位置
    data.push(27)
    data.push(36)
    data.push(parseInt(where % 256))
    data.push(parseInt(where / 256))
    }

    jpPrinter.setRelativePrintPositon = function (where) { //设置相对横向打印位置
    data.push(27)
    data.push(92)
    data.push(parseInt(where % 256))
    data.push(parseInt(where / 256))
    }

    jpPrinter.setSelectJustification = function (which) { //对齐方式
    /*
    0, 48 左对齐
    1, 49 中间对齐
    2, 50 右对齐
    */
    data.push(27)
    data.push(97)
    data.push(which)
    }

    jpPrinter.setFontSize=function(n){//设置字体大小
    data.push(29)
    data.push(33)
    data.push(n)
    // data.push( 10001000 )
    }

    jpPrinter.bold = function (n) {//加粗
    data.push(27)
    data.push(69)
    data.push(0) // 写死为0,都不加粗
    // data.push(n)
    }

    jpPrinter.rowSpace = function (n) { //设置行间距
    return
    // data.push(27)
    // data.push(51)
    // data.push(n)
    }

    jpPrinter.setLeftMargin = function (n) { //设置左边距
    data.push(29)
    data.push(76)
    data.push(parseInt(n % 256))
    data.push(parseInt(n / 256))
    }

    jpPrinter.setPrintingAreaWidth = function (width) { //设置打印区域宽度
    data.push(29)
    data.push(87)
    data.push(parseInt(width % 256))
    data.push(parseInt(width / 256))
    }

    jpPrinter.setSound = function (n, t) { //设置蜂鸣器
    data.push(27)
    data.push(66)
    if (n < 0) {
    n = 1;
    } else if (n > 9) {
    n = 9;
    }

    if (t < 0) {
    t = 1;
    } else if (t > 9) {
    t = 9;
    }
    data.push(n)
    data.push(t)
    }

    jpPrinter.setBitmap = function (res) { //参数,画布的参数
    console.log(res)
    var width = parseInt((res.width + 7) / 8 * 8 / 8)
    var height = res.height;
    var time = 1;
    var temp = res.data.length - width * 32;
    var point_list = []
    console.log(width + “–” + height)
    data.push(29)
    data.push(118)
    data.push(48)
    data.push(0)
    data.push((parseInt((res.width + 7) / 8) * 8) / 8)
    data.push(0)
    data.push(parseInt(res.height % 256))
    data.push(parseInt(res.height / 256))
    console.log(res.data.length)
    console.log(“temp=” + temp)
    for (var i = 0; i < height; ++i) {
    for (var j = 0; j < width; ++j) {
    for (var k = 0; k < 32; k += 4) {
    var po = {}
    if (res.data[temp] == 0 && res.data[temp + 1] == 0 && res.data[temp + 2] == 0 && res.data[temp + 3] == 0) {
    po.point = 0;
    } else {
    po.point = 1;
    }
    point_list.push(po)
    temp += 4
    }
    }
    time++
    temp = res.data.length - width * 32 * time
    }
    for (var i = 0; i < point_list.length; i += 8) {
    var p = point_list[i].point * 128 + point_list[i + 1].point * 64 + point_list[i + 2].point * 32 + point_list[i + 3].point * 16 + point_list[i + 4].point * 8 + point_list[i + 5].point * 4 + point_list[i + 6].point * 2 + point_list[i + 7].point
    data.push§
    }
    }

    jpPrinter.setPrint = function () { //打印并换行
    data.push(10)
    }

    jpPrinter.setPrintAndFeed = function (feed) { //打印并走纸feed个单位
    data.push(27)
    data.push(74)
    data.push(feed)
    }

    jpPrinter.setPrintAndFeedRow = function (row) { //打印并走纸row行
    data.push(27)
    data.push(100)
    data.push(row)
    }

    jpPrinter.getData = function () { //获取打印数据
    return data;
    };

    return jpPrinter;
    },

Query: function () {
var queryStatus = {};
var buf;
var dateView;
queryStatus.getRealtimeStatusTransmission = function (n) { //查询打印机实时状态
/*
n = 1:传送打印机状态
n = 2:传送脱机状态
n = 3:传送错误状态
n = 4:传送纸传感器状态
*/
buf = new ArrayBuffer(3)
dateView = new DataView(buf)
dateView.setUint8(0, 16)
dateView.setUint8(1, 4)
dateView.setUint8(2, n)
queryStatus.query(buf)
}

queryStatus.query = function (buf) {
  wx.writeBLECharacteristicValue({
    deviceId: app.BLEInformation.deviceId,
    serviceId: app.BLEInformation.writeServiceId,
    characteristicId: app.BLEInformation.writeCharaterId,
    value: buf,
    success: function (res) {

    },
    complete: function (res) {
      console.log(res)
      buf = null
      dateView = null;
    }
  })
}
return queryStatus;

}

};

module.exports.jpPrinter = jpPrinter;
4. 调用方法 // 普通蓝牙 打印方法 ///
print: function(mac_address, string) {
if (!mac_address) {
this.$api.msg(‘请先连接蓝牙打印机’);
return;
}

		this.$store.state.main = plus.android.runtimeMainActivity();
		this.$store.state.BluetoothAdapter = plus.android.importClass('android.bluetooth.BluetoothAdapter');
		var UUID = plus.android.importClass('java.util.UUID');
		this.$store.state.uuid = UUID.fromString('00001101-0000-1000-8000-00805F9B34FB');
		this.$store.state.BAdapter = this.$store.state.BluetoothAdapter.getDefaultAdapter();
		this.$store.state.device = this.$store.state.BAdapter.getRemoteDevice(mac_address);
		plus.android.importClass(this.$store.state.device);
		this.$store.state.bluetoothSocket = this.$store.state.device.createInsecureRfcommSocketToServiceRecord(this.$store.state.uuid);
		plus.android.importClass(this.$store.state.bluetoothSocket);

		if (!this.$store.state.bluetoothSocket.isConnected()) {
			console.log('检测到设备未连接,尝试连接....');
			this.$store.state.bluetoothSocket.connect();
		}

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

		if (this.$store.state.bluetoothSocket.isConnected()) {
			this.$store.state.mac_address = mac_address;
			var outputStream = this.$store.state.bluetoothSocket.getOutputStream();
			plus.android.importClass(outputStream);
			string = string ? string : '连接成功\r\n';
			var bytes = plus.android.invoke(string, 'getBytes', 'gbk');
			console.log(bytes);
			outputStream.write(bytes);
			outputStream.flush();
			this.$store.state.device = null; //这里关键
			this.$store.state.bluetoothSocket.close(); //必须关闭蓝牙连接否则意外断开的话打印错误
		}
	},
		senBlData(deviceId, serviceId, characteristicId, uint8Array) {
			// console.log('************deviceId = [' + deviceId + ']  serviceId = [' + serviceId + '] characteristics=[' +
			// 	characteristicId + "]")
			var that = this
			var uint8Buf = Array.from(uint8Array);
		
			function split_array(datas, size) {
				var result = [];
				var j = 0
				for (var i = 0; i < datas.length; i += size) {
					result[j] = datas.slice(i, i + size)
					j++
				}
				// console.log(result)
				return result
			}
			var sendloop = split_array(uint8Buf, 20);
			// console.log(sendloop.length)
			function realWriteData(sendloop, i) {
				var data = sendloop[i]
				if (typeof(data) == "undefined") {
					return
				}
				// console.log("第【" + i + "】次写数据" + data)
				var buffer = new ArrayBuffer(data.length)
				var dataView = new DataView(buffer)
				for (var j = 0; j < data.length; j++) {
					dataView.setUint8(j, data[j]);
				}
				uni.writeBLECharacteristicValue({
					deviceId,
					serviceId,
					characteristicId,
					value: buffer,
					success(res) {
						if(i == sendloop.length - 1){
							that.closeBLEConnection(deviceId)
						}
						setTimeout(()=>{
							realWriteData(sendloop, i + 1);
						},20)
					},
					fail: (res) => {
						console.log(res)
					}
				})
			}
			var i = 0;
			realWriteData(sendloop, i);
		},
			//连接低功耗蓝牙设备
		createBLEConnection(deviceId) {
			uni.showLoading({
				title: '连接设备中...'
			});
			return new Promise((resolve, reject) => {
				uni.openBluetoothAdapter({
					success: (res) => {
						console.log(res)
						setTimeout(()=> {
							uni.startBluetoothDevicesDiscovery({
								success: (res_t) => {
									// console.log(res_t)
									// 设置定时器counter,防止设备关闭时连接不上,一直在连接状态,,,
									let num = 0
									let firstTime = true // 防止下面 多次进入 uni.createBLEConnection.
									let counter = setInterval(()=>{
										num++
										if(num == 10){
											this.$api.msg('连接失败,请检查设备是否开启')
											clearInterval(counter)
											this.stopBluetoothDevicesDiscovery()
											resolve('fail')
										}
									},1000)
									uni.onBluetoothDeviceFound((res_p) => {
										// console.log(res_p);
										res_p.devices.forEach((item) => {
											if (item.name) {
												if(item.deviceId === deviceId && firstTime){
													firstTime = false
													console.log(item.deviceId)
													clearInterval(counter)
													this.stopBluetoothDevicesDiscovery()
													
													uni.createBLEConnection({
														deviceId: deviceId,
														timeout: 10000, //超时时间,单位ms
														success: (res) => {
															// console.log(res)
															
															// 此处有个bug,uniapp 的 bug。在蓝牙设备关闭的状态下进行连接,到了指定的超时时间,也还是会返回 createBLEConnection:ok , 
															// 导致我后续无法判断,所以在这里 '多此一举',加一段 getBLEDeviceServices 的代码,可以分清楚连接状态。
															// 后面 uniapp 修复了这个bug后,可以优化回来。zz
															setTimeout(()=>{
																uni.getBLEDeviceServices({
																	deviceId: deviceId,
																	success: (response) => {
																		// console.log(response)
																		let that = this
																		let once = true
																		for (let i = 0; i < response.services.length; i++) {
																			uni.getBLEDeviceCharacteristics({ 
																				deviceId: deviceId,
																				serviceId: response.services[i].uuid,
																				success: (res) => {
																					// console.log(res)
																					for (let j = 0; j < res.characteristics.length; j++) {
																						if (res.characteristics[j].properties.write && once) { // 循环 特征值 找到一个可写的即可。然后设备id,服务id,特征值存入本地。
																							console.log(res.characteristics[j].uuid)
																							once = false
																							uni.setStorageSync('deviceId',deviceId)
																							uni.setStorageSync('serviceId',response.services[i].uuid)
																							uni.setStorageSync('characteristicId',res.characteristics[j].uuid)
																							resolve('success')
																							uni.hideLoading()
																							return
																						}
																					}
																
																				}
																			})
																		}
																
																	},
																	fail: (response) => {
																		this.$api.msg('连接失败,请检查设备是否开启')
																		resolve('fail')
																		console.log(response)
																	}
																})
															},2000)
															
														},
														fail:(res) => {
															console.log(res)
															if(res.errCode == -1){
																this.$api.msg('蓝牙设备已经处于连接状态')
															}
															if(res.errCode == 10002){
																this.$api.msg('连接失败,请检查设备是否开启')
															}
															resolve('fail')
														}
													})
													
												}
											}
										})
									});
								},
								fail: (res_t) => {
									console.log(res_t);
									resolve('fail')
								}
							});
						}, 300);
						
					},
					fail: (res) => {
						console.log(res)
						this.$api.msg('请先打开手机蓝牙功能再操作')
						resolve('fail')
					}
				})
				
			})
		},
			//断开与低功耗蓝牙设备的连接
		closeBLEConnection(deviceId){
			uni.closeBLEConnection({
			    deviceId,
			    success(res) {
			        console.log(res)
			    }
			})
		},
			//关闭蓝牙模块
		closeBluetoothAdapter() {
			uni.closeBluetoothAdapter({
				success:(res)=> {
					console.log(res)
				},
				fail:(res)=> {
					console.log(res)
				}
			})
		},
		//停止搜索蓝牙设备
		stopBluetoothDevicesDiscovery() {
			uni.stopBluetoothDevicesDiscovery({
				success: e => {
					console.log(e);
				},
				fail: e => {
					console.log(e);
				}
			});
		},
	//打印样式

printByNormalBlu_Sale(){
let currentTime = formatterTime(new Date().getTime(), “yyyy-MM-dd hh:mm:ss”)
let message = this.mData.salesOrder.message.substr(0,21)
var head;
var height = 0;
var textSize = 30;
var lineSize = 15;
var barCodeHight = 50;
var string = “ENCODING GB18030\r\n”
string += “CENTER\r\n”
string += “SETMAG 1 1\r\n”
string += "TEXT GBUNSG24.CPF 0 0 " + height + " " + this.$store.state.loginProvider.userInfo.appPrintName + “\r\n”;
height += 35;
string += "TEXT GBUNSG24.CPF 0 0 " + height + " " + name + “\r\n”;
height += 35;
string += “LEFT\r\n”
string += “SETMAG 0 0\r\n”
string += “TEXT GBUNSG24.CPF 0 0 " + height + " 客户名称:” + this.mData.salesOrder.customerName + “\r\n”
height += textSize;
string += “TEXT GBUNSG24.CPF 0 0 " + height + " 客户地址:” + this.mData.salesOrder.addressDesc + “\r\n”
height += textSize;
string += “TEXT GBUNSG24.CPF 0 0 " + height + " 销售单号:” + this.mData.salesOrder.documentNum + “\r\n”
height += textSize;
string += “TEXT GBUNSG24.CPF 0 0 " + height + " 打印时间:” + currentTime + “\r\n”
height += textSize;
string += “TEXT GBUNSG24.CPF 0 0 " + height + " 联系人:” + this.mData.salesOrder.customerLinkman + “\r\n”
string += “TEXT GBUNSG24.CPF 0 300 " + height + " 电话:” + this.mData.salesOrder.customerHandset + “\r\n”
height += textSize;
string += “TEXT GBUNSG24.CPF 0 0 " + height + " 仓库:” + this.mData.salesOrder.warehouseName + “\r\n”
height += textSize;
string += “TEXT GBUNSG24.CPF 0 0 " + height + " 备注:” + message + “\r\n”
height += textSize;
string += “LINE 0 " + height + " 580 " + (height) + " 1\r\n”
height += lineSize;
string += “TEXT GBUNSG24.CPF 0 40 " + height + " 规格\r\n”
string += “TEXT GBUNSG24.CPF 0 140 " + height + " 数量\r\n”
string += “TEXT GBUNSG24.CPF 0 280 " + height + " 单价\r\n”
string += “TEXT GBUNSG24.CPF 0 440 " + height + " 金额(元)\r\n”

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值