android 佳博蓝牙打印机功能开发

news/2024/11/29 0:52:32/

蓝牙自动连接已配对设备

    private void connectBluetooth(){BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();if (pairedDevices.size()!=0){for (BluetoothDevice device : pairedDevices) {connect(device.getAddress());}}else {Toasts.show("暂无配对设备");}}

根据蓝牙地址,初始化线程池去做连接操作

 private void connect(String address){//初始化话DeviceConnFactoryManagerdeviceConnFactoryManager=new DeviceConnFactoryManager.Build().setId(0)//设置连接方式.setConnMethod(DeviceConnFactoryManager.CONN_METHOD.BLUETOOTH)//设置连接的蓝牙mac地址.setMacAddress(address).build();//打开端口ThreadPool.getInstantiation().addTask(new Runnable() {@Overridepublic void run() {DeviceConnFactoryManager.getDeviceConnFactoryManagers()[0].openPort();}});}

DeviceConnFactoryManager.java


public class DeviceConnFactoryManager {public PortManager mPort;private static final String TAG = DeviceConnFactoryManager.class.getSimpleName();public CONN_METHOD connMethod;private String ip;private int port;private String macAddress;private UsbDevice mUsbDevice;private Context mContext;private String serialPortPath;private int baudrate;private int id;private static DeviceConnFactoryManager[] deviceConnFactoryManagers = new DeviceConnFactoryManager[4];private boolean isOpenPort;/*** ESC查询打印机实时状态指令*/private byte[] esc = {0x10, 0x04, 0x02};/*** ESC查询打印机实时状态 缺纸状态*/private static final int ESC_STATE_PAPER_ERR = 0x20;/*** ESC指令查询打印机实时状态 打印机开盖状态*/private static final int ESC_STATE_COVER_OPEN = 0x04;/*** ESC指令查询打印机实时状态 打印机报错状态*/private static final int ESC_STATE_ERR_OCCURS = 0x40;/*** TSC查询打印机状态指令*/private byte[] tsc = {0x1b, '!', '?'};/*** TSC指令查询打印机实时状态 打印机缺纸状态*/private static final int TSC_STATE_PAPER_ERR = 0x04;/*** TSC指令查询打印机实时状态 打印机开盖状态*/private static final int TSC_STATE_COVER_OPEN = 0x01;/*** TSC指令查询打印机实时状态 打印机出错状态*/private static final int TSC_STATE_ERR_OCCURS = 0x80;private byte[] cpcl={0x1b,0x68};/*** CPCL指令查询打印机实时状态 打印机缺纸状态*/private static final int CPCL_STATE_PAPER_ERR = 0x01;/*** CPCL指令查询打印机实时状态 打印机开盖状态*/private static final int CPCL_STATE_COVER_OPEN = 0x02;private byte[] sendCommand;/*** 判断打印机所使用指令是否是ESC指令*/private PrinterCommand currentPrinterCommand;public static final byte FLAG = 0x10;private static final int READ_DATA = 10000;private static final String READ_DATA_CNT = "read_data_cnt";private static final String READ_BUFFER_ARRAY = "read_buffer_array";public static final String ACTION_CONN_STATE = "action_connect_state";public static final String ACTION_QUERY_PRINTER_STATE = "action_query_printer_state";public static final String STATE = "state";public static final String DEVICE_ID = "id";public static final int CONN_STATE_DISCONNECT = 0x90;public static final int CONN_STATE_CONNECTING = CONN_STATE_DISCONNECT << 1;public static final int CONN_STATE_FAILED = CONN_STATE_DISCONNECT << 2;public static final int CONN_STATE_CONNECTED = CONN_STATE_DISCONNECT << 3;public PrinterReader reader;private String status="打印机连接正常";public enum CONN_METHOD {//蓝牙连接BLUETOOTH("BLUETOOTH"),//USB连接USB("USB"),//wifi连接WIFI("WIFI"),//串口连接SERIAL_PORT("SERIAL_PORT");private String name;private CONN_METHOD(String name) {this.name = name;}@Overridepublic String toString() {return this.name;}}public static DeviceConnFactoryManager[] getDeviceConnFactoryManagers() {return deviceConnFactoryManagers;}/*** 打开端口** @return*/public void openPort() {deviceConnFactoryManagers[id].isOpenPort = false;sendStateBroadcast(CONN_STATE_CONNECTING);switch (deviceConnFactoryManagers[id].connMethod) {case BLUETOOTH:System.out.println("id -> " + id);mPort = new BluetoothPort(macAddress);isOpenPort = deviceConnFactoryManagers[id].mPort.openPort();break;case USB:mPort = new UsbPort(mContext, mUsbDevice);isOpenPort = mPort.openPort();if (isOpenPort) {IntentFilter filter = new IntentFilter(ACTION_USB_DEVICE_DETACHED);mContext.registerReceiver(usbStateReceiver, filter);}break;case WIFI:mPort = new EthernetPort(ip, port);isOpenPort = mPort.openPort();break;case SERIAL_PORT:mPort = new SerialPort(serialPortPath, baudrate, 0);isOpenPort = mPort.openPort();break;default:break;}//端口打开成功后,检查连接打印机所使用的打印机指令ESC、TSCif (isOpenPort) {queryCommand();} else {if (this.mPort != null) {this.mPort=null;}sendStateBroadcast(CONN_STATE_FAILED);}}/*** 查询当前连接打印机所使用打印机指令(ESC(EscCommand.java)、TSC(LabelCommand.java))*/private void queryCommand() {//开启读取打印机返回数据线程reader = new PrinterReader();reader.start(); //读取数据线程//查询打印机所使用指令queryPrinterCommand(); //}/*** 获取端口连接方式** @return*/public CONN_METHOD getConnMethod() {return connMethod;}/*** 获取端口打开状态(true 打开,false 未打开)** @return*/public boolean getConnState() {return isOpenPort;}/*** 获取连接蓝牙的物理地址** @return*/public String getMacAddress() {return macAddress;}/*** 获取连接网口端口号** @return*/public int getPort() {return port;}/*** 获取连接网口的IP** @return*/public String getIp() {return ip;}/*** 获取连接的USB设备信息** @return*/public UsbDevice usbDevice() {return mUsbDevice;}/*** 关闭端口*/public void closePort(int id) {if (this.mPort != null) {System.out.println("id -> " + id);reader.cancel();boolean b= this.mPort.closePort();if(b) {this.mPort=null;isOpenPort = false;currentPrinterCommand = null;}}sendStateBroadcast(CONN_STATE_DISCONNECT);}/*** 获取串口号** @return*/public String getSerialPortPath() {return serialPortPath;}/*** 获取波特率** @return*/public int getBaudrate() {return baudrate;}public static void closeAllPort() {for (DeviceConnFactoryManager deviceConnFactoryManager : deviceConnFactoryManagers) {if (deviceConnFactoryManager != null) {Log.e(TAG, "cloaseAllPort() id -> " + deviceConnFactoryManager.id);deviceConnFactoryManager.closePort(deviceConnFactoryManager.id);deviceConnFactoryManagers[deviceConnFactoryManager.id] = null;}}}private DeviceConnFactoryManager(Build build) {this.connMethod = build.connMethod;this.macAddress = build.macAddress;this.port = build.port;this.ip = build.ip;this.mUsbDevice = build.usbDevice;this.mContext = build.context;this.serialPortPath = build.serialPortPath;this.baudrate = build.baudrate;this.id = build.id;deviceConnFactoryManagers[id] = this;}/*** 获取当前打印机指令** @return PrinterCommand*/public PrinterCommand getCurrentPrinterCommand() {return deviceConnFactoryManagers[id].currentPrinterCommand;}public static final class Build {private String ip;private String macAddress;private UsbDevice usbDevice;private int port;private CONN_METHOD connMethod;private Context context;private String serialPortPath;private int baudrate;private int id;public DeviceConnFactoryManager.Build setIp(String ip) {this.ip = ip;return this;}public DeviceConnFactoryManager.Build setMacAddress(String macAddress) {this.macAddress = macAddress;return this;}public DeviceConnFactoryManager.Build setUsbDevice(UsbDevice usbDevice) {this.usbDevice = usbDevice;return this;}public DeviceConnFactoryManager.Build setPort(int port) {this.port = port;return this;}public DeviceConnFactoryManager.Build setConnMethod(CONN_METHOD connMethod) {this.connMethod = connMethod;return this;}public DeviceConnFactoryManager.Build setContext(Context context) {this.context = context;return this;}public DeviceConnFactoryManager.Build setId(int id) {this.id = id;return this;}public DeviceConnFactoryManager.Build setSerialPort(String serialPortPath) {this.serialPortPath = serialPortPath;return this;}public DeviceConnFactoryManager.Build setBaudrate(int baudrate) {this.baudrate = baudrate;return this;}public DeviceConnFactoryManager build() {return new DeviceConnFactoryManager(this);}}public void sendDataImmediately(final Vector<Byte> data) {if (this.mPort == null) {return;}try {//  Log.e(TAG, "data -> " + new String(com.gprinter.command.GpUtils.convertVectorByteTobytes(data), "gb2312"));this.mPort.writeDataImmediately(data, 0, data.size());} catch (Exception e) {e.printStackTrace();}}public int readDataImmediately(byte[] buffer) throws IOException {return this.mPort.readData(buffer);}/*** 查询打印机当前使用的指令(TSC、ESC)*/private void queryPrinterCommand() {//线程池添加任务ThreadPool.getInstantiation().addTask(new Runnable() {@Overridepublic void run() {//发送ESC查询打印机状态指令sendCommand = esc;Vector<Byte> data = new Vector<>(esc.length);for (int i = 0; i < esc.length; i++) {data.add(esc[i]);}sendDataImmediately(data); //发送esc数据//开启计时器,隔2000毫秒没有没返回值时发送TSC查询打印机状态指令final ThreadFactoryBuilder threadFactoryBuilder = new ThreadFactoryBuilder("Timer");final ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1, threadFactoryBuilder);scheduledExecutorService.schedule(threadFactoryBuilder.newThread(new Runnable() {@Overridepublic void run() {if (currentPrinterCommand == null || currentPrinterCommand != PrinterCommand.ESC) {Log.e(TAG, Thread.currentThread().getName());//发送TSC查询打印机状态指令sendCommand = tsc;Vector<Byte> data = new Vector<>(tsc.length);for (int i = 0; i < tsc.length; i++) {data.add(tsc[i]);}sendDataImmediately(data);//开启计时器,隔2000毫秒没有没返回值时发送CPCL查询打印机状态指令scheduledExecutorService.schedule(threadFactoryBuilder.newThread(new Runnable() {@Overridepublic void run() {if (currentPrinterCommand == null||(currentPrinterCommand != PrinterCommand.ESC&&currentPrinterCommand != PrinterCommand.TSC)) {Log.e(TAG, Thread.currentThread().getName());//发送CPCL查询打印机状态指令sendCommand=cpcl;Vector<Byte> data =new Vector<Byte>(cpcl.length);for (int i=0;i<cpcl.length;i++){data.add(cpcl[i]);}sendDataImmediately(data);//开启计时器,隔2000毫秒打印机没有响应者停止读取打印机数据线程并且关闭端口scheduledExecutorService.schedule(threadFactoryBuilder.newThread(new Runnable() {@Overridepublic void run() {if(currentPrinterCommand==null){if (reader != null) {reader.cancel();mPort.closePort();isOpenPort = false;mPort=null;sendStateBroadcast(CONN_STATE_FAILED);}}}}),2000, TimeUnit.MILLISECONDS);}}}), 2000, TimeUnit.MILLISECONDS);}}}), 2000, TimeUnit.MILLISECONDS);}});}public class PrinterReader extends Thread {private boolean isRun = false;private byte[] buffer = new byte[100];public PrinterReader() {isRun = true;}@Overridepublic void run() {try {while (isRun) {//读取打印机返回信息int len = readDataImmediately(buffer);if (len > 0) {Message message = Message.obtain();message.what = READ_DATA;Bundle bundle = new Bundle();bundle.putInt(READ_DATA_CNT, len); //数据长度bundle.putByteArray(READ_BUFFER_ARRAY, buffer); //数据message.setData(bundle);mHandler.sendMessage(message);}}} catch (Exception e) {if (deviceConnFactoryManagers[id] != null) {closePort(id);}}}public void cancel() {isRun = false;}}private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case READ_DATA:int cnt = msg.getData().getInt(READ_DATA_CNT); //数据长度 >0;byte[] buffer = msg.getData().getByteArray(READ_BUFFER_ARRAY);  //数据//这里只对查询状态返回值做处理,其它返回值可参考编程手册来解析if (buffer == null) {return;}int result = judgeResponseType(buffer[0]); //数据右移//String status = AppApplication.getInstance().getString(R.string.str_printer_conn_normal);if (sendCommand == esc) {//设置当前打印机模式为ESC模式if (currentPrinterCommand == null) {currentPrinterCommand = PrinterCommand.ESC;sendStateBroadcast(CONN_STATE_CONNECTED);} else {//查询打印机状态if (result == 0) {//打印机状态查询Intent intent = new Intent(ACTION_QUERY_PRINTER_STATE);intent.putExtra(DEVICE_ID, id);AppApplication.getInstance().sendBroadcast(intent);} else if (result == 1) {//查询打印机实时状态if ((buffer[0] & ESC_STATE_PAPER_ERR) > 0) {//缺纸status =AppApplication.getInstance().getString(R.string.str_printer_out_of_paper);ToastUtil.showToastWithImg(status,R.drawable.ico_fail);}if ((buffer[0] & ESC_STATE_COVER_OPEN) > 0) {//开盖status =AppApplication.getInstance().getString(R.string.str_printer_open_cover);ToastUtil.showToastWithImg(status,R.drawable.ico_fail);}if ((buffer[0] & ESC_STATE_ERR_OCCURS) > 0) {status =AppApplication.getInstance().getString(R.string.str_printer_error);ToastUtil.showToastWithImg(status,R.drawable.ico_fail);}System.out.println(AppApplication.getInstance().getString(R.string.str_state) + status);// String mode=AppApplication.getInstance().getString(R.string.str_printer_printmode_esc);//Utils.toast(AppApplication.getInstance(), mode+" "+status);}}} else if (sendCommand == tsc) {//设置当前打印机模式为TSC模式if (currentPrinterCommand == null) {currentPrinterCommand = PrinterCommand.TSC;sendStateBroadcast(CONN_STATE_CONNECTED);} else {if (cnt == 1) {//查询打印机实时状态if ((buffer[0] & TSC_STATE_PAPER_ERR) > 0) {//缺纸status =AppApplication.getInstance().getString(R.string.str_printer_out_of_paper);}if ((buffer[0] & TSC_STATE_COVER_OPEN) > 0) {//开盖status =AppApplication.getInstance().getString(R.string.str_printer_open_cover);}if ((buffer[0] & TSC_STATE_ERR_OCCURS) > 0) {//打印机报错status =AppApplication.getInstance().getString(R.string.str_printer_error);}System.out.println(AppApplication.getInstance().getString(R.string.str_state) + status);String mode=AppApplication.getInstance().getString(R.string.str_printer_printmode_tsc);Utils.toast(AppApplication.getInstance(), mode+" "+status);} else {//打印机状态查询Intent intent = new Intent(ACTION_QUERY_PRINTER_STATE);intent.putExtra(DEVICE_ID, id);AppApplication.getInstance().sendBroadcast(intent);}}}else if(sendCommand==cpcl){if (currentPrinterCommand == null) {currentPrinterCommand = PrinterCommand.CPCL;sendStateBroadcast(CONN_STATE_CONNECTED);}else {if (cnt == 1) {System.out.println(AppApplication.getInstance().getString(R.string.str_state) + status);if ((buffer[0] ==CPCL_STATE_PAPER_ERR)) {//缺纸status =AppApplication.getInstance().getString(R.string.str_printer_out_of_paper);}if ((buffer[0] ==CPCL_STATE_COVER_OPEN)) {//开盖status =AppApplication.getInstance().getString(R.string.str_printer_open_cover);}String mode=AppApplication.getInstance().getString(R.string.str_printer_printmode_cpcl);Utils.toast(AppApplication.getInstance(), mode+" "+status);} else {//打印机状态查询Intent intent = new Intent(ACTION_QUERY_PRINTER_STATE);intent.putExtra(DEVICE_ID, id);AppApplication.getInstance().sendBroadcast(intent);}}}break;default:break;}}};public String getStatus(){return status;}private void sendStateBroadcast(int state) {Intent intent = new Intent(ACTION_CONN_STATE);intent.putExtra(STATE, state);intent.putExtra(DEVICE_ID, id);AppApplication.getInstance().sendBroadcast(intent);}/*** 判断是实时状态(10 04 02)还是查询状态(1D 72 01)*/private int judgeResponseType(byte r) {return (byte) ((r & FLAG) >> 4);}BroadcastReceiver usbStateReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();switch (action) {case ACTION_USB_DEVICE_DETACHED:sendStateBroadcast(CONN_STATE_DISCONNECT);break;default:break;}}};}

打印操作

//打印切刀命令
byte[] bytes={29,86,0};
//实时状态查询
byte[] bytes1={16,4,2};
  private void sendReceiptWithResponse() {EscCommand esc = new EscCommand();esc.addInitializePrinter();esc.addPrintAndFeedLines((byte) 1);// 设置打印居中esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);// 设置为倍高倍宽esc.addText(""+AppApplication.getInstance().getDaoSession().getBusinessSettingDao().loadAll().get(0).getPRINTTITLE()+"\n");esc.addText("[商户存根]\n");esc.addPrintAndLineFeed();// 设置打印左对齐esc.addSelectJustification(EscCommand.JUSTIFICATION.LEFT);// 打印文字esc.addText("----------------------------\n");// 打印文字esc.addText("商户号:   "+AppApplication.getInstance().getDaoSession().getDeviceInfoDao().loadAll().get(0).getStoreNum()+"\n");esc.addText("商户名称:   "+AppApplication.getInstance().getDaoSession().getDeviceInfoDao().loadAll().get(0).getStoreName()+"\n");esc.addText("员工卡号:   "+businessDetail.getWiegand_id()+"\n");esc.addText("交易账号:   "+businessDetail.getCARDNUM()+"\n");esc.addText("交易类型:   "+businessDetail.getTYPE()+"\n");esc.addText("订单号:   "+businessDetail.getORDERNUM()+"\n");esc.addText("日期时间:   "+businessDetail.getDATE()+"\n");if (businessDetail.getTYPE().equals("消费")){esc.addText("交易金额:  RMB "+businessDetail.getMONEY()+"\n");}else {esc.addText("交易金额:  RMB -"+businessDetail.getMONEY()+"\n");}esc.addText("----------------------------\n");esc.addText("备注\n");esc.addPrintAndLineFeed();esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);// 开钱箱esc.addGeneratePlus(LabelCommand.FOOT.F5, (byte) 255, (byte) 255);esc.addPrintAndFeedLines((byte) 8);// 加入查询打印机状态,用于连续打印esc.addUserCommand(bytes);Vector<Byte> datas = esc.getCommand();// 发送数据DeviceConnFactoryManager.getDeviceConnFactoryManagers()[0].sendDataImmediately(datas);if(Integer.valueOf(AppApplication.getInstance().getDaoSession().getBusinessSettingDao().loadAll().get(0).getPRINTPAGE())>1){sendReceiptWithResponse1();}}

http://www.ppmy.cn/news/653848.html

相关文章

appemit 支持chrome edge谷歌微软浏览器佳博Gprinter 标签打印机 TSCLIB.DLL 函数库使用说明

支持谷歌 firefox edge 360 qq sogou等各种浏览器&#xff0c;在线使用 佳博Gprinter 标签打印机 直接js操作 TSCLIB.DLL 函数库使用说明 请在使用TSCLIB.DLL 前&#xff0c;安装条形码打印机驱动程序。 1. openport(a) 说明: 指定计算机端的输出端口 参数: a: 单机打印时&…

打印机控制 佳博 Gprinter GP-9134T

控制程序 from PyQt5.QtPrintSupport import QPrinterInfo import socket import os from jinja2 import Templatetemplate """ SIZE 50 mm,90 mm GAP 2 mm,0 mm REFERENCE 0,0 SPEED 2.5 DENSITY 3 SET PEEL OFF SET CUTTER OFF SET PARTIAL_CUTTER OFF SET …

2021-07-22 佳博 蓝牙打印

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 佳博 蓝牙打印 前言一、想好所需模板样式&#xff1f;二、引入修改模板样式的js1.引入库2.根据所需样式编辑3.根据uniAPP API文档 uni.writeBLECharacteristicValue4.uni.wri…

web应用 远程调用佳博打印机进行条码打印(详细教程)

需求&#xff1a; 通过html调用本地服务启动打印机&#xff0c;带参数去打印不同内容。 步骤&#xff1a; 1. 生成可直接执行的exe程序。 2. 注册服务。 3. 前端调用测试。 1. 生成可直接执行的exe程序 1.1 前提&#xff1a;代码测试已经通过&#xff0c;可看我的另一篇文章&a…

硬件系列(二)-------------wifi打印机之佳博wifi打印机踩坑之路

一、前言 之前做过USB打印机&#xff0c;但是现在需求变了&#xff0c;不是使用收银台进行打印机的连接了&#xff0c;而是使用手机与打印机进行打印。手机又无法像收银机一样直接使用USB直接与打印机直接连接进行打印。所以只能使用蓝牙打印机或者wifi打印机了&#xff0c;但…

springboot整合佳博打印机打印条码、二维码

引入依赖 <dependency><groupId>net.java.dev.jna</groupId><artifactId>jna</artifactId><version>3.2.5</version></dependency>2、测试代码 import com.sun.jna.Library; import com.sun.jna.Native;public class Gprinte…

uniapp连接佳博打印机实现蓝牙打印票据功能

开始实现搜索蓝牙。获取蓝牙设备。连接蓝牙设备等操作。代码如下 <template><view class"content"><button class"btn" type"primary" :loading"isSearching" tap"startSearch">开始搜索 </button&g…

Android 关于佳博和汉印蓝牙热敏打印机开发,安卓databinding

PrinterHelper.SetMag(“1”, “1”); PrinterHelper.SetBold(“0”); PrinterHelper.InverseLine(“0”, “0”, “700”, 《Android学习笔记总结最新移动架构视频大厂安卓面试真题项目实战源码讲义》 【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享 “0”, “100…