文章目录

  • 前言
  • 一、效果图
  • 二、使用步骤
    • 1.UsbPrinter类
    • 2.ESCUtil类
    • 3.BytesUtil工具类
    • 4.Activity使用

前言

最近公司需要连接芯烨云的串口打印机,因为云打印有很多弊端,这个大家都懂,费什么话,上菜!


一、效果图

常规出牌,先来效果图,不然你们都不感兴趣往下看了!

二、使用步骤

1.UsbPrinter类

有注释就不用多讲什么了吧!

package com.example.cashiersystem.utils;import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;import java.io.UnsupportedEncodingException;
import java.util.HashMap;/*** 作者:CaoLiulang* ❤* Date:2022/5/30* ❤* 模块:USB打印类*/
public class UsbPrinter{private static final String TAG = "UsbPrinter";public static final String ACTION_USB_PERMISSION = "com.usb.printer.USB_PERMISSION";@SuppressLint("StaticFieldLeak")private static UsbPrinter mInstance;private Context mContext;private PendingIntent mPermissionIntent;private UsbManager mUsbManager;private UsbDeviceConnection mUsbDeviceConnection;private UsbEndpoint ep, printerEp;private UsbInterface usbInterface;private static final int TIME_OUT = 100000;private UsbPrinter() {}public static UsbPrinter getInstance() {if (mInstance == null) {synchronized (UsbPrinter.class) {if (mInstance == null) {mInstance = new UsbPrinter();}}}return mInstance;}/*** 初始化打印机,需要与destroy对应** @param context 上下文*/public void initPrinter(Context context) {init(context);}@TargetApi(Build.VERSION_CODES.LOLLIPOP)private void init(Context context) {mContext = context;mUsbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);mPermissionIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_USB_PERMISSION), 0);// 注册广播监听usb设备IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);mContext.registerReceiver(mUsbDeviceReceiver, filter);// 列出所有的USB设备,并且都请求获取USB权限HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();for (UsbDevice device : deviceList.values()) {// 得到此设备的一个接口usbInterface = device.getInterface(0);// 获取接口的类别 7代表连接的是打印机if (usbInterface.getInterfaceClass() == 7) {// 1137     85      1027// 26728     1280      1045+2if (!mUsbManager.hasPermission(device)) {mUsbManager.requestPermission(device, mPermissionIntent);} else {connectUsbPrinter(device);}}}}private final BroadcastReceiver mUsbDeviceReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();UsbDevice mUsbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);if (ACTION_USB_PERMISSION.equals(action)) {synchronized (this) {if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false) && mUsbDevice != null) {connectUsbPrinter(mUsbDevice);} else {ToastUtils.ToastCllShow( "USB设备请求被拒绝");}}} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {if (mUsbDevice != null) {ToastUtils.ToastCllShow( "有设备拔出");}} else if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {ToastUtils.ToastCllShow( "有设备插入");if (mUsbDevice != null) {if (!mUsbManager.hasPermission(mUsbDevice)) {mUsbManager.requestPermission(mUsbDevice, mPermissionIntent);}}}}};/*** 关闭usb的端口及取消注册的广播监听*/public void close() {if (mUsbDeviceConnection != null) {mUsbDeviceConnection.close();mUsbDeviceConnection = null;}mContext.unregisterReceiver(mUsbDeviceReceiver);mContext = null;mUsbManager = null;}/*** 连接打印机设备** @param mUsbDevice 识别到的打印机设备*/private void connectUsbPrinter(UsbDevice mUsbDevice) {if (mUsbDevice != null) {for (int i = 0; i < usbInterface.getEndpointCount(); i++) {// 获取指定的index 获得此接口的一个节点 返回一个UsbEndpointep = usbInterface.getEndpoint(i);if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {int pid = mUsbDevice.getProductId();int vid = mUsbDevice.getVendorId();mUsbDeviceConnection = mUsbManager.openDevice(mUsbDevice);printerEp = ep;if (mUsbDeviceConnection != null) {ToastUtils.ToastCllShow( "设备已连接");// 在使用UsbInterface进行数据的写入写出之前,要申明对其的专有访问权限,防止通信混乱mUsbDeviceConnection.claimInterface(usbInterface, true);}}}}} else {ToastUtils.ToastCllShow( "未发现可用的打印机");}}/*** 安卓9.0之前* 只要你传送的数据不大于16384 bytes,传送不会出问题,一旦数据大于16384 bytes,也可以传送,* 只是大于16384后面的数据就会丢失,获取到的数据永远都是前面的16384 bytes,* 所以,android USB Host 模式与HID使用bulkTransfer(endpoint,buffer,length,timeout)通讯时* buffer的长度不能超过16384。* <p>* controlTransfer( int requestType, int request , int value , int index , byte[] buffer , int length , int timeout)* 该方法通过0节点向此设备传输数据,传输的方向取决于请求的类别,如果requestType 为 USB_DIR_OUT 则为写数据 , USB _DIR_IN ,则为读数据*/private void write(byte[] bytes) {if (mUsbDeviceConnection != null) {// 通过给定的endpoint 来进行大量的数据传输,传输的方向取决于该节点的方向,// buffer是要发送或接收的字节数组,length是该字节数组的长度,失败则返回负数// 下行端点,字节数组消息,消息长度,响应时间int len = mUsbDeviceConnection.bulkTransfer(printerEp, bytes, bytes.length, TIME_OUT);} else {if (Looper.myLooper()==null) {Looper.prepare();}handler.sendEmptyMessage(0);Looper.loop();}}@SuppressLint("HandlerLeak")private final Handler handler = new Handler(Looper.getMainLooper()) {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);ToastUtils.ToastCllShow( "未发现可用的打印机");}};/*** 初始化*/public void init() {write(ESCUtil.initPrinter());}/*** 打印文字** @param msg 打印的内容*/public void printText(String msg) {byte[] bytes = new byte[0];try {bytes = msg.getBytes("gbk");} catch (UnsupportedEncodingException e) {e.printStackTrace();}write(bytes);}/*** 换行打印文字** @param msg 打印的内容*/public void printTextNewLine(String msg) {byte[] bytes = new byte[0];try {bytes = msg.getBytes("gbk");} catch (UnsupportedEncodingException e) {e.printStackTrace();}write(new String("\n").getBytes());write(bytes);}/*** 换行*/public void printLine() {//        write(new byte[]{10});write(new String("\n").getBytes());}/*** 打印空行** @param size 几行*/public void printLine(int size) {for (int i = 0; i < size; i++) {printText("\n");}}/*** 设置字体大小** @param size 0:正常大小 1:两倍高 2:两倍宽 3:两倍大小 4:三倍高 5:三倍宽 6:三倍大 7:四倍高 8:四倍宽 9:四倍大小 10:五倍高 11:五倍宽 12:五倍大小*/public void setTextSize(int size) {write(ESCUtil.setTextSize(size));}/*** 字体加粗** @param isBold true/false*/public void bold(boolean isBold) {if (isBold) {write(ESCUtil.boldOn());} else {write(ESCUtil.boldOff());}}/*** 打印一维条形码** @param data 条码*/public void printBarCode(String data) {//        write(ESCUtil.getPrintBarCode(data, 5, 90, 5, 2));write(ESCUtil.getPrintBarCode(data, 5, 90, 4, 2));}/*** 打印二维码** @param data 打印的内容*/public void printQrCode(String data) {write(ESCUtil.getPrintQrCode(data, 250));}/*** 设置对齐方式** @param position 0居左 1居中 2居右*/public void setAlign(int position) {byte[] bytes = null;switch (position) {case 0:bytes = ESCUtil.alignLeft();
//                bytes = new byte[]{ 0x1b, 0x61, 0x30 };
//                bytes = new byte[]{27, 97, (byte) 0};break;case 1:bytes = ESCUtil.alignCenter();
//                bytes = new byte[]{ 0x1b, 0x61, 0x31 };
//                bytes = new byte[]{27, 97, (byte) 1};break;case 2:bytes = ESCUtil.alignRight();
//                bytes = new byte[]{ 0x1b, 0x61, 0x32 };
//                bytes = new byte[]{27, 97, (byte) 2};break;default:break;}write(bytes);}/*** 获取字符串的宽度** @param str 取字符* @return 宽度*/public int getStringWidth(String str) {int width = 0;for (char c : str.toCharArray()) {width += isChinese(c) ? 2 : 1;}return width;}/*** 判断是否中文* GENERAL_PUNCTUATION 判断中文的“号* CJK_SYMBOLS_AND_PUNCTUATION 判断中文的。号* HALFWIDTH_AND_FULLWIDTH_FORMS 判断中文的,号** @param c 字符* @return 是否中文*/public static boolean isChinese(char c) {Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);return ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION;}/*** 切纸*/public void cutPager() {write(ESCUtil.cutter());}}

2.ESCUtil类

代码如下(示例):

package com.example.cashiersystem.utils;import android.graphics.Bitmap;import java.io.ByteArrayOutputStream;/*** 作者:CaoLiulang* ❤* Date:2022/5/30* ❤* 模块:常用指令封装ESCUtil工具类*/
public class ESCUtil {/*** Escape*/public static final byte ESC = 0x1B;/*** Text delimiter 文本分隔符*/public static final byte FS = 0x1C;/*** Group separator 组分离器*/public static final byte GS = 0x1D;/*** data link escape*/public static final byte DLE = 0x10;/*** End of transmission*/public static final byte EOT = 0x04;/*** Enquiry character*/public static final byte ENQ = 0x05;/*** Spaces*/public static final byte SP = 0x20;/*** Horizontal list*/public static final byte HT = 0x09;/*** 打印和包装(水平方向)*/public static final byte LF = 0x0A;/*** Home key*/public static final byte CR = 0x0D;/*** Carriage control (print and return to the standard mode (in page mode))*/public static final byte FF = 0x0C;/*** Canceled (cancel print data in page mode)*/public static final byte CAN = 0x18;/*** 初始化打印机*/public static byte[] initPrinter() {byte[] result = new byte[2];result[0] = ESC;result[1] = 0x40;return result;}/*** 打印浓度指令*/public static byte[] setPrinterDarkness(int value) {byte[] result = new byte[9];result[0] = GS;result[1] = 40;result[2] = 69;result[3] = 4;result[4] = 0;result[5] = 5;result[6] = 5;result[7] = (byte) (value >> 8);result[8] = (byte) value;return result;}/*** 打印单个二维码 sunmi自定义指令** @param code: 二维码数据* @param :     二维码块大小(单位:点, 取值 1 至 16 )* @param :     二维码纠错等级(0 至 3)*              0 -- 纠错级别L ( 7%)*              1 -- 纠错级别M (15%)*              2 -- 纠错级别Q (25%)*              3 -- 纠错级别H (30%)*/public static byte[] getPrintQrCode(String code, int moduleSize, int errorLevel) {ByteArrayOutputStream buffer = new ByteArrayOutputStream();try {buffer.write(setQrCodeSize(moduleSize));buffer.write(setQrCodeErrorLevel(errorLevel));buffer.write(getQrCodeBytes(code));buffer.write(getBytesForPrintQrCode(true));} catch (Exception e) {e.printStackTrace();}return buffer.toByteArray();}/*** 横向两个二维码 sunmi自定义指令** @param code1: 二维码数据* @param code2: 二维码数据* @param :      二维码块大小(单位:点, 取值 1 至 16 )* @param :      二维码纠错等级(0 至 3)*               0 -- 纠错级别L ( 7%)*               1 -- 纠错级别M (15%)*               2 -- 纠错级别Q (25%)*               3 -- 纠错级别H (30%)*/public static byte[] getPrintDoubleQrCode(String code1, String code2, int moduleSize, int errorLevel) {ByteArrayOutputStream buffer = new ByteArrayOutputStream();try {buffer.write(setQrCodeSize(moduleSize));buffer.write(setQrCodeErrorLevel(errorLevel));buffer.write(getQrCodeBytes(code1));buffer.write(getBytesForPrintQrCode(false));buffer.write(getQrCodeBytes(code2));// 加入横向间隔buffer.write(new byte[]{0x1B, 0x5C, 0x18, 0x00});buffer.write(getBytesForPrintQrCode(true));} catch (Exception e) {e.printStackTrace();}return buffer.toByteArray();}/*** 光栅打印二维码*/public static byte[] getPrintQrCode(String data, int size) {byte[] bytes1 = new byte[4];bytes1[0] = GS;bytes1[1] = 0x76;bytes1[2] = 0x30;bytes1[3] = 0x00;byte[] bytes2 = BytesUtil.getZxingQrCode(data, size);return bytes2 == null ? new byte[]{} : BytesUtil.byteMerger(bytes1, bytes2);}/*** 打印一维条形码*/public static byte[] getPrintBarCode(String data, int logy, int height, int width, int textPosition) {if (logy < 0 || logy > 10) {return new byte[]{LF};}if (width < 2 || width > 6) {width = 2;}if (textPosition < 0 || textPosition > 3) {textPosition = 0;}if (height < 1 || height > 255) {height = 162;}ByteArrayOutputStream buffer = new ByteArrayOutputStream();try {buffer.write(new byte[]{0x1D, 0x66, 0x01, 0x1D, 0x48, (byte) textPosition,0x1D, 0x77, (byte) width, 0x1D, 0x68, (byte) height, 0x0A});byte[] barcode;if (logy == 10) {barcode = BytesUtil.getBytesFromDecString(data);} else {barcode = data.getBytes("GB18030");}if (logy > 7) {buffer.write(new byte[]{0x1D, 0x6B, 0x49, (byte) (barcode.length + 2), 0x7B, (byte) (0x41 + logy - 8)});} else {buffer.write(new byte[]{0x1D, 0x6B, (byte) (logy + 0x41), (byte) barcode.length});}buffer.write(barcode);} catch (Exception e) {e.printStackTrace();}return buffer.toByteArray();}/*** 光栅位图打印*/public static byte[] printBitmap(Bitmap bitmap) {byte[] bytes1 = new byte[4];bytes1[0] = GS;bytes1[1] = 0x76;bytes1[2] = 0x30;bytes1[3] = 0x00;byte[] bytes2 = BytesUtil.getBytesFromBitMap(bitmap);return BytesUtil.byteMerger(bytes1, bytes2);}/*** 光栅位图打印 设置mode*/public static byte[] printBitmap(Bitmap bitmap, int mode) {byte[] bytes1 = new byte[4];bytes1[0] = GS;bytes1[1] = 0x76;bytes1[2] = 0x30;bytes1[3] = (byte) mode;byte[] bytes2 = BytesUtil.getBytesFromBitMap(bitmap);return BytesUtil.byteMerger(bytes1, bytes2);}/*** 光栅位图打印*/public static byte[] printBitmap(byte[] bytes) {byte[] bytes1 = new byte[4];bytes1[0] = GS;bytes1[1] = 0x76;bytes1[2] = 0x30;bytes1[3] = 0x00;return BytesUtil.byteMerger(bytes1, bytes);}/*** 选择位图指令 设置mode* 需要设置1B 33 00将行间距设为0*/public static byte[] selectBitmap(Bitmap bitmap, int mode) {return BytesUtil.byteMerger(BytesUtil.byteMerger(new byte[]{0x1B, 0x33, 0x00}, BytesUtil.getBytesFromBitMap(bitmap, mode)), new byte[]{0x0A, 0x1B, 0x32});}/*** 跳指定行数*/public static byte[] nextLine(int lineNum) {byte[] result = new byte[lineNum];for (int i = 0; i < lineNum; i++) {result[i] = LF;}return result;}/*** 设置下划线1点*/public static byte[] underlineWithOneDotWidthOn() {byte[] result = new byte[3];result[0] = ESC;result[1] = 45;result[2] = 1;return result;}/*** 设置下划线2点*/public static byte[] underlineWithTwoDotWidthOn() {byte[] result = new byte[3];result[0] = ESC;result[1] = 45;result[2] = 2;return result;}/*** 取消下划线*/public static byte[] underlineOff() {byte[] result = new byte[3];result[0] = ESC;result[1] = 45;result[2] = 0;return result;}// ------------------------bold-----------------------------/*** 字体加粗*/public static byte[] boldOn() {byte[] result = new byte[3];result[0] = ESC;result[1] = 69;result[2] = 0xF;return result;}/*** 取消字体加粗*/public static byte[] boldOff() {byte[] result = new byte[3];result[0] = ESC;result[1] = 69;result[2] = 0;return result;}// ------------------------character-----------------------------/*** 单字节模式开启*/public static byte[] singleByte() {byte[] result = new byte[2];result[0] = FS;result[1] = 0x2E;return result;}/*** 单字节模式关闭*/public static byte[] singleByteOff() {byte[] result = new byte[2];result[0] = FS;result[1] = 0x26;return result;}/*** 设置单字节字符集*/public static byte[] setCodeSystemSingle(byte charset) {byte[] result = new byte[3];result[0] = ESC;result[1] = 0x74;result[2] = charset;return result;}/*** 设置多字节字符集*/public static byte[] setCodeSystem(byte charset) {byte[] result = new byte[3];result[0] = FS;result[1] = 0x43;result[2] = charset;return result;}// ------------------------Align-----------------------------/*** 居左对齐*/public static byte[] alignLeft() {byte[] result = new byte[3];result[0] = ESC;result[1] = 97;result[2] = 0;return result;}/*** 居中对齐*/public static byte[] alignCenter() {byte[] result = new byte[3];result[0] = ESC;result[1] = 97;result[2] = 1;return result;}/*** 居右对齐*/public static byte[] alignRight() {byte[] result = new byte[3];result[0] = ESC;result[1] = 97;result[2] = 2;return result;}/*** 切刀*/public static byte[] cutter() {//        byte[] data = new byte[]{0x1d, 0x56, 0x01};
//        byte[] data = new byte[]{29, 86, (byte) 1};return new byte[]{GS, 'V', 0x00};}/*** 走纸到黑标*/public static byte[] go() {return new byte[]{0x1C, 0x28, 0x4C, 0x02, 0x00, 0x42, 0x31};}/*** 二维码块大小设置指令*/private static byte[] setQrCodeSize(int moduleSize) {byte[] dtmp = new byte[8];dtmp[0] = GS;dtmp[1] = 0x28;dtmp[2] = 0x6B;dtmp[3] = 0x03;dtmp[4] = 0x00;dtmp[5] = 0x31;dtmp[6] = 0x43;dtmp[7] = (byte) moduleSize;return dtmp;}/*** 二维码纠错等级设置指令*/private static byte[] setQrCodeErrorLevel(int errorLevel) {byte[] dtmp = new byte[8];dtmp[0] = GS;dtmp[1] = 0x28;dtmp[2] = 0x6B;dtmp[3] = 0x03;dtmp[4] = 0x00;dtmp[5] = 0x31;dtmp[6] = 0x45;dtmp[7] = (byte) (48 + errorLevel);return dtmp;}/*** 打印已存入数据的二维码*/private static byte[] getBytesForPrintQrCode(boolean single) {byte[] dtmp;// 同一行只打印一个QRCode, 后面加换行if (single) {dtmp = new byte[9];dtmp[8] = 0x0A;} else {dtmp = new byte[8];}dtmp[0] = 0x1D;dtmp[1] = 0x28;dtmp[2] = 0x6B;dtmp[3] = 0x03;dtmp[4] = 0x00;dtmp[5] = 0x31;dtmp[6] = 0x51;dtmp[7] = 0x30;return dtmp;}/*** 二维码存入指令*/private static byte[] getQrCodeBytes(String code) {ByteArrayOutputStream buffer = new ByteArrayOutputStream();try {byte[] d = code.getBytes("GB18030");int len = d.length + 3;if (len > 7092) {len = 7092;}buffer.write((byte) 0x1D);buffer.write((byte) 0x28);buffer.write((byte) 0x6B);buffer.write((byte) len);buffer.write((byte) (len >> 8));buffer.write((byte) 0x31);buffer.write((byte) 0x50);buffer.write((byte) 0x30);for (int i = 0; i < d.length && i < len; i++) {buffer.write(d[i]);}} catch (Exception e) {e.printStackTrace();}return buffer.toByteArray();}/*** 设置字体大小*/public static byte[] setTextSize(int size) {return fontSize(size).getBytes();}/*** 字体的大小** @param fontSize 0:正常大小 1:两倍高 2:两倍宽 3:两倍大小 4:三倍高 5:三倍宽 6:三倍大小*                 7:四倍高 8:四倍宽 9:四倍大小 10:五倍高 11:五倍宽 12:五倍大小*/public static String fontSize(int fontSize) {String cmdstr = "";// 设置字体大小switch (fontSize) {case -1:
//                // 29 33
//                cmdstr = new StringBuffer().append((char) 29).append((char) 33)
//                        .append((char) 0).toString();
//                break;case 0:cmdstr = new StringBuffer().append((char) 29).append((char) 33).append((char) 0).toString();break;case 1:cmdstr = new StringBuffer().append((char) 29).append((char) 33).append((char) 1).toString();break;case 2:cmdstr = new StringBuffer().append((char) 29).append((char) 33).append((char) 16).toString();break;case 3:cmdstr = new StringBuffer().append((char) 29).append((char) 33).append((char) 17).toString();break;case 4:cmdstr = new StringBuffer().append((char) 29).append((char) 33).append((char) 2).toString();break;case 5:cmdstr = new StringBuffer().append((char) 29).append((char) 33).append((char) 32).toString();break;case 6:cmdstr = new StringBuffer().append((char) 29).append((char) 33).append((char) 34).toString();break;case 7:cmdstr = new StringBuffer().append((char) 29).append((char) 33).append((char) 3).toString();break;case 8:cmdstr = new StringBuffer().append((char) 29).append((char) 33).append((char) 48).toString();break;case 9:cmdstr = new StringBuffer().append((char) 29).append((char) 33).append((char) 51).toString();break;case 10:cmdstr = new StringBuffer().append((char) 29).append((char) 33).append((char) 4).toString();break;case 11:cmdstr = new StringBuffer().append((char) 29).append((char) 33).append((char) 64).toString();break;case 12:cmdstr = new StringBuffer().append((char) 29).append((char) 33).append((char) 68).toString();break;default:break;}return cmdstr;}
}

3.BytesUtil工具类

代码如下(示例):

package com.example.cashiersystem.utils;import android.annotation.SuppressLint;
import android.graphics.Bitmap;import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;import java.util.Hashtable;/*** 作者:CaoLiulang* ❤* Date:2022/5/30* ❤* 模块:BytesUtil工具类*/
public class BytesUtil {/*** 字节流转16进制字符串*/public static String getHexStringFromBytes(byte[] data) {if (data == null || data.length <= 0) {return null;}String hexString = "0123456789ABCDEF";int size = data.length * 2;StringBuilder sb = new StringBuilder(size);for (int i = 0; i < data.length; i++) {sb.append(hexString.charAt((data[i] & 0xF0) >> 4));sb.append(hexString.charAt((data[i] & 0x0F) >> 0));}return sb.toString();}/*** 单字符转字节*/private static byte charToByte(char c) {return (byte) "0123456789ABCDEF".indexOf(c);}/*** 16进制字符串转字节数组*/@SuppressLint("DefaultLocale")public static byte[] getBytesFromHexString(String hexString) {if (hexString == null || "".equals(hexString)) {return null;}hexString = hexString.replace(" ", "");hexString = hexString.toUpperCase();int size = hexString.length() / 2;char[] hexArray = hexString.toCharArray();byte[] rv = new byte[size];for (int i = 0; i < size; i++) {int pos = i * 2;rv[i] = (byte) (charToByte(hexArray[pos]) << 4 | charToByte(hexArray[pos + 1]));}return rv;}/*** 十进制字符串转字节数组*/@SuppressLint("DefaultLocale")public static byte[] getBytesFromDecString(String decString) {if (decString == null || "".equals(decString)) {return null;}decString = decString.replace(" ", "");int size = decString.length() / 2;char[] decarray = decString.toCharArray();byte[] rv = new byte[size];for (int i = 0; i < size; i++) {int pos = i * 2;rv[i] = (byte) (charToByte(decarray[pos]) * 10 + charToByte(decarray[pos + 1]));}return rv;}/*** 字节数组组合操作1*/public static byte[] byteMerger(byte[] byte_1, byte[] byte_2) {byte[] byte_3 = new byte[byte_1.length + byte_2.length];System.arraycopy(byte_1, 0, byte_3, 0, byte_1.length);System.arraycopy(byte_2, 0, byte_3, byte_1.length, byte_2.length);return byte_3;}/*** 字节数组组合操作2*/public static byte[] byteMerger(byte[][] byteList) {int length = 0;
//        for (int i = 0; i < byteList.length; i++) {//            length += byteList[i].length;
//        }for (byte[] bytes : byteList) {length += bytes.length;}byte[] result = new byte[length];int index = 0;for (int i = 0; i < byteList.length; i++) {byte[] nowByte = byteList[i];for (int k = 0; k < byteList[i].length; k++) {result[index] = nowByte[k];index++;}}
//        for (int i = 0; i < index; i++) {//            // CommonUtils.LogWuwei("", "result[" + i + "] is " + result[i]);
//        }return result;}/*** 生成表格字节流*/public static byte[] initTable(int h, int w) {int hh = h * 32;int ww = w * 4;byte[] data = new byte[hh * ww + 5];// xLdata[0] = (byte) ww;// xHdata[1] = (byte) (ww >> 8);data[2] = (byte) hh;data[3] = (byte) (hh >> 8);int k = 4;int m = 31;for (int i = 0; i < h; i++) {for (int j = 0; j < w; j++) {data[k++] = (byte) 0xFF;data[k++] = (byte) 0xFF;data[k++] = (byte) 0xFF;data[k++] = (byte) 0xFF;}if (i == h - 1) m = 30;for (int t = 0; t < m; t++) {for (int j = 0; j < w - 1; j++) {data[k++] = (byte) 0x80;data[k++] = (byte) 0;data[k++] = (byte) 0;data[k++] = (byte) 0;}data[k++] = (byte) 0x80;data[k++] = (byte) 0;data[k++] = (byte) 0;data[k++] = (byte) 0x01;}}for (int j = 0; j < w; j++) {data[k++] = (byte) 0xFF;data[k++] = (byte) 0xFF;data[k++] = (byte) 0xFF;data[k++] = (byte) 0xFF;}data[k++] = 0x0A;return data;}/*** 生成二维码字节流*/public static byte[] getZxingQrCode(String data, int size) {try {Hashtable<EncodeHintType, String> hints = new Hashtable<>();hints.put(EncodeHintType.CHARACTER_SET, "utf-8");// 图像数据转换,使用了矩阵转换BitMatrix bitMatrix = new QRCodeWriter().encode(data, BarcodeFormat.QR_CODE, size, size, hints);return getBytesFromBitMatrix(bitMatrix);} catch (WriterException e) {e.printStackTrace();}return null;}public static byte[] getBytesFromBitMatrix(BitMatrix bits) {if (bits == null) {return null;}int h = bits.getHeight();int w = (bits.getWidth() + 7) / 8;byte[] rv = new byte[h * w + 4];// xLrv[0] = (byte) w;// xHrv[1] = (byte) (w >> 8);rv[2] = (byte) h;rv[3] = (byte) (h >> 8);int k = 4;for (int i = 0; i < h; i++) {for (int j = 0; j < w; j++) {for (int n = 0; n < 8; n++) {byte b = getBitMatrixColor(bits, j * 8 + n, i);rv[k] += rv[k] + b;}k++;}}return rv;}private static byte getBitMatrixColor(BitMatrix bits, int x, int y) {int width = bits.getWidth();int height = bits.getHeight();if (x >= width || y >= height || x < 0 || y < 0) return 0;if (bits.get(x, y)) {return 1;} else {return 0;}}/*** 将bitmap图转换为头四位有宽高的光栅位图*/public static byte[] getBytesFromBitMap(Bitmap bitmap) {int width = bitmap.getWidth();int height = bitmap.getHeight();int bw = (width - 1) / 8 + 1;byte[] rv = new byte[height * bw + 4];// xLrv[0] = (byte) bw;// xHrv[1] = (byte) (bw >> 8);rv[2] = (byte) height;rv[3] = (byte) (height >> 8);int[] pixels = new int[width * height];bitmap.getPixels(pixels, 0, width, 0, 0, width, height);for (int i = 0; i < height; i++) {for (int j = 0; j < width; j++) {int clr = pixels[width * i + j];int red = (clr & 0x00ff0000) >> 16;int green = (clr & 0x0000ff00) >> 8;int blue = clr & 0x000000ff;byte gray = (RGB2Gray(red, green, blue));rv[(width * i + j) / 8 + 4] = (byte) (rv[(width * i + j) / 8 + 4] | (gray << (7 - ((width * i + j) % 8))));}}return rv;}/*** 将bitmap转成按mode指定的N点行数据*/public static byte[] getBytesFromBitMap(Bitmap bitmap, int mode) {int width = bitmap.getWidth();int height = bitmap.getHeight();int[] pixels = new int[width * height];if (mode == 0 || mode == 1) {byte[] res = new byte[width * height / 8 + 5 * height / 8];bitmap.getPixels(pixels, 0, width, 0, 0, width, height);for (int i = 0; i < height / 8; i++) {res[0 + i * (width + 5)] = 0x1b;res[1 + i * (width + 5)] = 0x2a;res[2 + i * (width + 5)] = (byte) mode;res[3 + i * (width + 5)] = (byte) (width % 256);res[4 + i * (width + 5)] = (byte) (width / 256);for (int j = 0; j < width; j++) {byte gray = 0;for (int m = 0; m < 8; m++) {int clr = pixels[j + width * (i * 8 + m)];int red = (clr & 0x00ff0000) >> 16;int green = (clr & 0x0000ff00) >> 8;int blue = clr & 0x000000ff;gray = (byte) ((RGB2Gray(red, green, blue) << (7 - m)) | gray);}res[5 + j + i * (width + 5)] = gray;}}return res;} else if (mode == 32 || mode == 33) {byte[] res = new byte[width * height / 8 + 5 * height / 24];bitmap.getPixels(pixels, 0, width, 0, 0, width, height);for (int i = 0; i < height / 24; i++) {res[0 + i * (width * 3 + 5)] = 0x1b;res[1 + i * (width * 3 + 5)] = 0x2a;res[2 + i * (width * 3 + 5)] = (byte) mode;res[3 + i * (width * 3 + 5)] = (byte) (width % 256);res[4 + i * (width * 3 + 5)] = (byte) (width / 256);for (int j = 0; j < width; j++) {for (int n = 0; n < 3; n++) {byte gray = 0;for (int m = 0; m < 8; m++) {int clr = pixels[j + width * (i * 24 + m + n * 8)];int red = (clr & 0x00ff0000) >> 16;int green = (clr & 0x0000ff00) >> 8;int blue = clr & 0x000000ff;gray = (byte) ((RGB2Gray(red, green, blue) << (7 - m)) | gray);}res[5 + j * 3 + i * (width * 3 + 5) + n] = gray;}}}return res;} else {return new byte[]{0x0A};}}private static byte RGB2Gray(int r, int g, int b) {return (false ? ((int) (0.29900 * r + 0.58700 * g + 0.11400 * b) > 200): ((int) (0.29900 * r + 0.58700 * g + 0.11400 * b) < 200)) ? (byte) 1 : (byte) 0;}/*** 生成间断性黑块数据** @param w : 打印纸宽度, 单位点*/public static byte[] initBlackBlock(int w) {int ww = (w + 7) / 8;int n = (ww + 11) / 12;int hh = n * 24;byte[] data = new byte[hh * ww + 5];// xLdata[0] = (byte) ww;// xHdata[1] = (byte) (ww >> 8);data[2] = (byte) hh;data[3] = (byte) (hh >> 8);int k = 4;for (int i = 0; i < n; i++) {for (int j = 0; j < 24; j++) {for (int m = 0; m < ww; m++) {if (m / 12 == i) {data[k++] = (byte) 0xFF;} else {data[k++] = 0;}}}}data[k++] = 0x0A;return data;}/*** 生成一大块黑块数据** @param h : 黑块高度, 单位点* @param w : 黑块宽度, 单位点, 8的倍数*/public static byte[] initBlackBlock(int h, int w) {int hh = h;int ww = (w - 1) / 8 + 1;byte[] data = new byte[hh * ww + 6];// xLdata[0] = (byte) ww;// xHdata[1] = (byte) (ww >> 8);data[2] = (byte) hh;data[3] = (byte) (hh >> 8);int k = 4;for (int i = 0; i < hh; i++) {for (int j = 0; j < ww; j++) {data[k++] = (byte) 0xFF;}}data[k++] = 0x00;data[k++] = 0x00;return data;}/*** 基本覆盖热敏小票打印中所有epson指令的操作*/public static byte[] customData() {byte[] rv = new byte[]{(byte) 0xB4, (byte) 0xF2, (byte) 0xD3, (byte) 0xA1, (byte) 0xBB, (byte) 0xFA, (byte) 0xD7, (byte) 0xD4, (byte) 0xBC, (byte) 0xEC, 0x0A,// 打印机自检0x1F, 0X1B, 0x1F, 0x53,// 初始化打印机0x1B, 0x40,// 分割线---0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A,(byte) 0xB8, (byte) 0xC4, (byte) 0xB1, (byte) 0xE4, (byte) 0xD7, (byte) 0xD6, (byte) 0xBC, (byte) 0xE4, (byte) 0xBE, (byte) 0xE0, 0x0A,0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A,// 设置字符右间距0x30, 0x2E, 0x30, 0x3A, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, 0x0A,0x30, 0x2E, 0x35, 0x3A, 0x1B, 0x20, 0x0C, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, 0x0A,0x1B, 0x20, 0x00,0x31, 0x2E, 0x30, 0x3A, 0x1B, 0x20, 0x18, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, 0x0A,0x1B, 0x20, 0x00,0x32, 0x2E, 0x30, 0x3A, 0x1B, 0x20, 0x30, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, 0x0A,0x1B, 0x20, 0x00,// 分割线===0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A,(byte) 0xD7, (byte) 0xD6, (byte) 0xCC, (byte) 0xE5, (byte) 0xD0, (byte) 0xA7, (byte) 0xB9, (byte) 0xFB, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A,// 字体效果 商米科技// 设置加粗、倍高、倍宽、下划线、反白0x1B, 0x21, 0x08, (byte) 0xBC, (byte) 0xD3, (byte) 0xB4, (byte) 0xD6, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,0x1B, 0x21, 0x00,0x1B, 0x45, 0x01, (byte) 0xBC, (byte) 0xD3, (byte) 0xB4, (byte) 0xD6, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,0x1B, 0x45, 0x00,0x1B, 0x21, 0x10, (byte) 0xB1, (byte) 0xB6, (byte) 0xB8, (byte) 0xDF, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,0x1B, 0x21, 0x20, (byte) 0xB1, (byte) 0xB6, (byte) 0xBF, (byte) 0xED, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,0x1D, 0x21, 0x11, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC,0x1D, 0x21, 0x22, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,0x1D, 0x21, 0x00,0x1B, 0x21, (byte) 0x80, (byte) 0xCF, (byte) 0xC2, (byte) 0xBB, (byte) 0xAE, (byte) 0xCF, (byte) 0xDF, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,0x1B, 0x21, 0x00,0x1B, 0x2D, 0x01, (byte) 0xCF, (byte) 0xC2, (byte) 0xBB, (byte) 0xAE, (byte) 0xCF, (byte) 0xDF, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,0x1B, 0x2D, 0x00,0x1D, 0x42, 0x01, 0x1B, 0x21, 0x08, (byte) 0xB7, (byte) 0xB4, (byte) 0xB0, (byte) 0xD7, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,0x1D, 0x42, 0x00, 0x1B, 0x21, 0x00,// 分割线***0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x0A,(byte) 0xC5, (byte) 0xC5, (byte) 0xB0, (byte) 0xE6, (byte) 0xCE, (byte) 0xBB, (byte) 0xD6, (byte) 0xC3, 0x0A,0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x0A,// 排版位置// 设置绝对位置和设置相对位置(byte) 0xD5, (byte) 0xE2, (byte) 0xBE, (byte) 0xE4, (byte) 0xBB, (byte) 0xB0, (byte) 0xB4, (byte) 0xD3, (byte) 0xD0, (byte) 0xD0, (byte) 0xCA, (byte) 0xD7, (byte) 0xBF, (byte) 0xAA, (byte) 0xCA, (byte) 0xBC, 0x0A,(byte) 0xBE, (byte) 0xF8, (byte) 0xB6, (byte) 0xD4, (byte) 0xCE, (byte) 0xBB, (byte) 0xD6, (byte) 0xC3, 0x1B, 0x24, (byte) 0xC0, 0x00, (byte) 0xC6, (byte) 0xAB, (byte) 0xD2, (byte) 0xC6, 0x38, (byte) 0xB8, (byte) 0xF6, (byte) 0xD7, (byte) 0xD6, 0x0A,(byte) 0xCF, (byte) 0xE0, (byte) 0xB6, (byte) 0xD4, (byte) 0xCE, (byte) 0xBB, (byte) 0xD6, (byte) 0xC3, 0x1B, 0x5C, 0x30, 0x00, (byte) 0xC6, (byte) 0xAB, (byte) 0xD2, (byte) 0xC6, 0x32, (byte) 0xB8, (byte) 0xF6, (byte) 0xD7, (byte) 0xD6, 0x0A,//设置对齐方式(byte) 0xBE, (byte) 0xD3, (byte) 0xD7, (byte) 0xF3, 0x0A,0x1B, 0x61, 0x01, (byte) 0xBE, (byte) 0xD3, (byte) 0xD6, (byte) 0xD0, 0x0A,0x1B, 0x61, 0x02, (byte) 0xBE, (byte) 0xD3, (byte) 0xD3, (byte) 0xD2, 0x0A,0x1B, 0x61, 0x00,// 设置左边距0x1D, 0x4C, 0x30, 0x00,(byte) 0xC9, (byte) 0xE8, (byte) 0xD6, (byte) 0xC3, (byte) 0xD7, (byte) 0xF3, (byte) 0xB1, (byte) 0xDF, (byte) 0xBE, (byte) 0xE0, 0x34, 0x38, (byte) 0xCF, (byte) 0xF1, (byte) 0xCB, (byte) 0xD8, 0x0A,// 设置打印区域宽度0x1D, 0x57, (byte) 0xF0, 0x00,(byte) 0xB8, (byte) 0xC4, (byte) 0xB1, (byte) 0xE4, (byte) 0xBF, (byte) 0xC9, (byte) 0xB4, (byte) 0xF2, (byte) 0xD3, (byte) 0xA1, (byte) 0xC7, (byte) 0xF8, (byte) 0xD3, (byte) 0xF2, (byte) 0xCE, (byte) 0xAA, 0x32, 0x34, 0x30, (byte) 0xCF, (byte) 0xF1, (byte) 0xCB, (byte) 0xD8, 0x0A,// 设置左边距0x1D, 0x4C, 0x60, 0x00,(byte) 0xC9, (byte) 0xE8, (byte) 0xD6, (byte) 0xC3, (byte) 0xD7, (byte) 0xF3, (byte) 0xB1, (byte) 0xDF, (byte) 0xBE, (byte) 0xE0, 0x39, 0x36, (byte) 0xCF, (byte) 0xF1, (byte) 0xCB, (byte) 0xD8, 0x0A,// 设置打印区域宽度0x1D, 0x57, (byte) 0x78, 0x00,(byte) 0xB8, (byte) 0xC4, (byte) 0xB1, (byte) 0xE4, (byte) 0xBF, (byte) 0xC9, (byte) 0xB4, (byte) 0xF2, (byte) 0xD3, (byte) 0xA1, (byte) 0xC7, (byte) 0xF8, (byte) 0xD3, (byte) 0xF2, (byte) 0xCE, (byte) 0xAA, 0x31, 0x32, 0x30, (byte) 0xCF, (byte) 0xF1, (byte) 0xCB, (byte) 0xD8, 0x0A,0x1D, 0x4C, 0x00, 0x00,0x1D, 0x57, (byte) 0x80, 0x01,// 水平制表符-跳格(byte) 0xC4, (byte) 0xAC, 0x09, (byte) 0xC8, (byte) 0xCF, 0x09, (byte) 0xCC, (byte) 0xF8, 0x09, (byte) 0xB8, (byte) 0xF1, 0x09, 0x0A,0x1B, 0x44, 0x01, 0x02, 0x04, 0x08, 0x0A, 0x00,(byte) 0xD7, (byte) 0xD4, 0x09, (byte) 0xB6, (byte) 0xA8, 0x09, (byte) 0xD2, (byte) 0xE5, 0x09, (byte) 0xCC, (byte) 0xF8, 0x09, (byte) 0xB8, (byte) 0xF1, 0x09, 0x0A,// 设置行高0x1B, 0x33, 0x60, (byte) 0xC9, (byte) 0xE8, (byte) 0xD6, (byte) 0xC3, (byte) 0xD0, (byte) 0xD0, (byte) 0xB8, (byte) 0xDF, 0x3A, 0x39, 0x36, (byte) 0xB5, (byte) 0xE3, (byte) 0xD0, (byte) 0xD0, 0x0A,0x1B, 0x33, 0x40, (byte) 0xC9, (byte) 0xE8, (byte) 0xD6, (byte) 0xC3, (byte) 0xD0, (byte) 0xD0, (byte) 0xB8, (byte) 0xDF, 0x3A, 0x36, 0x34, (byte) 0xB5, (byte) 0xE3, (byte) 0xD0, (byte) 0xD0, 0x0A,0x1B, 0x33, 0x00, (byte) 0xC9, (byte) 0xE8, (byte) 0xD6, (byte) 0xC3, (byte) 0xD0, (byte) 0xD0, (byte) 0xB8, (byte) 0xDF, 0x3A, 0x30, (byte) 0xB5, (byte) 0xE3, (byte) 0xD0, (byte) 0xD0, 0x0A,0x1B, 0x32, (byte) 0xC4, (byte) 0xAC, (byte) 0xC8, (byte) 0xCF, (byte) 0xD0, (byte) 0xD0, (byte) 0xB8, (byte) 0xDF, 0x0A,// 分割线---0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A,(byte) 0xD6, (byte) 0xAE, (byte) 0xBA, (byte) 0xF3, (byte) 0xBD, (byte) 0xAB, (byte) 0xD7, (byte) 0xDF, (byte) 0xD6, (byte) 0xBD, 0x0A,0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A,// 打印并走纸0x1B, 0x4A, 0x40, (byte) 0xD7, (byte) 0xDF, (byte) 0xD6, (byte) 0xBD, 0x36, 0x34, (byte) 0xB5, (byte) 0xE3, (byte) 0xD0, (byte) 0xD0, 0x0A,0x1B, 0x4A, 0x60, (byte) 0xD7, (byte) 0xDF, (byte) 0xD6, (byte) 0xBD, 0x39, 0x36, (byte) 0xB5, (byte) 0xE3, (byte) 0xD0, (byte) 0xD0, 0x0A,0x1B, 0x64, 0x0A, (byte) 0xD7, (byte) 0xDF, (byte) 0xD6, (byte) 0xBD, 0x31, 0x30, (byte) 0xD0, (byte) 0xD0, 0x0A,0x1B, 0x64, 0x01, (byte) 0xD7, (byte) 0xDF, (byte) 0xD6, (byte) 0xBD, 0x31, (byte) 0xD0, (byte) 0xD0, 0x0A,// 分割线===0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A,(byte) 0xB4, (byte) 0xF2, (byte) 0xD3, (byte) 0xA1, (byte) 0xCC, (byte) 0xF5, (byte) 0xC2, (byte) 0xEB, 0x0A,0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A,// 打印条码0x1D, 0x48, 0x02,// upca0x1B, 0x61, 0x00, 0x1D, 0x68, 0x20, 0x1D, 0x77, 0x02,0x1D, 0x6B, 0x41, 0x0c, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x0A,0x1D, 0x6B, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x00, 0x0A,// upce0x1B, 0x61, 0x01, 0x1D, 0x68, 0x40, 0x1D, 0x77, 0x04,0x1D, 0x6B, 0x42, 0x08, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x0A,0x1D, 0x6B, 0x01, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x00, 0x0A,// ean130x1B, 0x61, 0x02, 0x1D, 0x68, 0x60, 0x1D, 0x77, 0x02,0x1D, 0x6B, 0x43, 0x0D, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x0A,0x1D, 0x6B, 0x02, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x00, 0x0A,// ean80x1B, 0x61, 0x00, 0x1D, 0x68, (byte) 0x80, 0x1D, 0x77, 0x05,0x1D, 0x6B, 0x44, 0x08, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x0A,0x1D, 0x6B, 0x03, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x00, 0x0A,// code390x1B, 0x61, 0x01, 0x1D, 0x68, (byte) 0xA0, 0x1D, 0x77, 0x02,0x1D, 0x6B, 0x45, 0x0A, 0x33, 0x36, 0x39, 0x53, 0x55, 0x4E, 0x4D, 0x49, 0x25, 0x24, 0x0A,0x1D, 0x6B, 0x04, 0x33, 0x36, 0x39, 0x53, 0x55, 0x4E, 0x4D, 0x49, 0x25, 0x24, 0x00, 0x0A,// itf0x1B, 0x61, 0x02, 0x1D, 0x68, (byte) 0xC0, 0x1D, 0x77, 0x03,0x1D, 0x6B, 0x46, 0x0C, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x0A,0x1D, 0x6B, 0x05, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x00, 0x0A,// codebar0x1B, 0x61, 0x00, 0x1D, 0x68, (byte) 0xE0, 0x1D, 0x77, 0x03,0x1D, 0x6B, 0x47, 0x0A, 0x41, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x41, 0x0A,// 0x1D, 0x6B, 0x06, 0x41, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x41, 0x00, 0x0A,// code930x1B, 0x61, 0x01, 0x1D, 0x68, (byte) 0xFF, 0x1D, 0x77, 0x02,0x1D, 0x6B, 0x48, 0x0C, 0x53, 0x55, 0x4E, 0x4D, 0x49, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x0A,// code1280x1B, 0x61, 0x00, 0x1D, 0x68, (byte) 0xB0, 0x1D, 0x77, 0x02,0x1D, 0x6B, 0x49, 0x0A, 0x7B, 0x41, 0x53, 0x55, 0x4E, 0x4D, 0x49, 0x30, 0x31, 0x32, 0x0A,0x1D, 0x6B, 0x49, 0x0C, 0x7B, 0x42, 0x53, 0x55, 0x4E, 0x4D, 0x49, 0x73, 0x75, 0x6E, 0x6D, 0x69, 0x0A,0x1D, 0x6B, 0x49, 0x0B, 0x7B, 0x43, 0x01, 0xc, 0x17, 0x22, 0x2d, 0x38, 0x4e, 0x59, 0x5a, 0x0A,// 分割线***0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x0A,(byte) 0xB4, (byte) 0xF2, (byte) 0xD3, (byte) 0xA1, (byte) 0xB6, (byte) 0xFE, (byte) 0xCE, (byte) 0xAC, (byte) 0xC2, (byte) 0xEB, 0x0A,0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x0A,// 打印二维码0x1B, 0x61, 0x01,0x1D, 0x28, 0x6B, 0x03, 0x00, 0x31, 0x43, 0x09,0x1D, 0x28, 0x6B, 0x03, 0x00, 0x31, 0x45, 0x32,0x1D, 0x28, 0x6B, 0x0B, 0x00, 0x31, 0x50, 0x30, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC,0x1D, 0x28, 0x6B, 0x03, 0x00, 0x31, 0x51, 0x30, 0x0A,0x1B, 0x61, 0x00,// 分割线---      (之后将实现打印光栅位图的方法,再次之前使用1b 61 01 居中)0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A,(byte) 0xB4, (byte) 0xF2, (byte) 0xD3, (byte) 0xA1, (byte) 0xB9, (byte) 0xE2, (byte) 0xD5, (byte) 0xA4, (byte) 0xCD, (byte) 0xBC, (byte) 0xCF, (byte) 0xF1, 0x0A,0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A,0x1B, 0x61, 0x01,};return rv;}/*** 部分字符打印的分割线标志*/public static byte[] wordData() {byte[] bytes = new byte[]{// 分割线===0x1B, 0x61, 0x00,0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A,(byte) 0xD7, (byte) 0xD6, (byte) 0xB7, (byte) 0xFB, (byte) 0xBC, (byte) 0xAF, (byte) 0xC9, (byte) 0xE8, (byte) 0xD6, (byte) 0xC3, 0x0A,0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x0A,0x1C, 0x26, 0x1C, 0x43, 0x00,};return bytes;}
}

4.Activity使用

说明:for循环里面是自己的数据

UsbPrinter usbPrinter;//USB打印
usbPrinter = UsbPrinter.getInstance();
usbPrinter.initPrinter(this);/*** USB串口打印*/private void USBPrinter() {// 设置加粗usbPrinter.bold(true);// 文字大小usbPrinter.setTextSize(3);// 设置文字居中usbPrinter.setAlign(1);// 打印文字并换行usbPrinter.printTextNewLine("结账单");// 取消加粗usbPrinter.bold(false);// 换2行usbPrinter.printLine(2);usbPrinter.setTextSize(0);// 设置文字居左对齐usbPrinter.setAlign(0);usbPrinter.printTextNewLine("流水号:20225301314");usbPrinter.printTextNewLine("单号:CF15545655454");usbPrinter.printTextNewLine("结账时间:2022/5/30");usbPrinter.printTextNewLine("收银员:***");// 换2行usbPrinter.printLine(1);usbPrinter.printTextNewLine("菜品       数量 重量    金额");usbPrinter.printTextNewLine("-------------------------------");for (int i = 0; i < addcpbean.size(); i++) {if (addcpbean.get(i).getName().length() == 1) {usbPrinter.printTextNewLine(addcpbean.get(i).getName() + "          " + addcpbean.get(i).getQuantity() + "   -     " + addcpbean.get(i).getSubtotal());} else if (addcpbean.get(i).getName().length() == 2) {usbPrinter.printTextNewLine(addcpbean.get(i).getName() + "        " + addcpbean.get(i).getQuantity() + "   -     " + addcpbean.get(i).getSubtotal());} else if (addcpbean.get(i).getName().length() == 3) {usbPrinter.printTextNewLine(addcpbean.get(i).getName() + "      " + addcpbean.get(i).getQuantity() + "   -     " + addcpbean.get(i).getSubtotal());} else if (addcpbean.get(i).getName().length() == 4) {usbPrinter.printTextNewLine(addcpbean.get(i).getName() + "    " + addcpbean.get(i).getQuantity() + "   -     " + addcpbean.get(i).getSubtotal());} else if (addcpbean.get(i).getName().length() == 5) {usbPrinter.printTextNewLine(addcpbean.get(i).getName() + "  " + addcpbean.get(i).getQuantity() + "   -     " + addcpbean.get(i).getSubtotal());} else {usbPrinter.printTextNewLine(addcpbean.get(i).getName());usbPrinter.printTextNewLine("            " + addcpbean.get(i).getQuantity() + "   -     " + addcpbean.get(i).getSubtotal());}}usbPrinter.printTextNewLine("-------------------------------");// 设置文字居右对齐usbPrinter.setAlign(0);usbPrinter.printTextNewLine("订单金额:¥200元");usbPrinter.printTextNewLine("优惠金额:¥50元");// 支付金额usbPrinter.printTextNewLine("支付金额:¥150元");usbPrinter.printTextNewLine("-------------------------------");usbPrinter.bold(true);// 文字大小usbPrinter.setTextSize(2);usbPrinter.printTextNewLine("备注:不要放辣椒,早点配送");// 换2行usbPrinter.printLine(2);// 文字大小usbPrinter.setTextSize(1);//居中usbPrinter.setAlign(1);usbPrinter.printTextNewLine("欢迎下次光临");usbPrinter.printLine(6);// 切纸usbPrinter.cutPager();}

提示:如果有问题请联系我,我马上把你拉黑,哈哈,开玩笑,有问题私聊我或者评论,欢迎指正!

Android之USB打印相关推荐

  1. Android使用usb线传输大文件笔记

    使用usb线传输大文件 参考资料: 使用USB数据线连接PC端和Android端进行数据的交互 安卓设备通过USB接口实现与pc端的简单数据通信 Socket TCP/IP协议数据传输过程中的粘包和分 ...

  2. 【单片机】Android手机USB外接STM32单片机通过ADB实现投屏反向控制的功能

    Android手机USB外接STM32单片机通过ADB实现投屏反向控制的功能 前言 一.功能演示 二.实现步骤 1.开发环境 2.代码分析 (1)USBHost处理函数 (2)ADB事务处理函数 (3 ...

  3. android检测usb设备——usb打印机

    最近弄了一个安卓的项目,需要外接usb打印机,从网上找了一些方法,下面这个是测试了以后,没有问题的.主要是担心再次访问404,所以我做个备份,这里附一下原文链接. 在此之前,我先说几个我踩的坑. 这个 ...

  4. android通过USB连接佳博80打印机

    GitHub项目地址 条件:1安卓主板上有USB口,2,rom内置了打印驱动 不行就用其他方式或者换主板吧(本人当初使用的工控主板坑得不要不要的) 本文介绍的是使用USB方式 佳博提供两个函数打印 1 ...

  5. Android 开源USB读写demo,实现串口通信

    CSDN 下载链接https://download.csdn.net/download/gao511147456/87226599(可0积分免费下载) 如果你不想下载可以阅读下面教程并复制代码到自己的 ...

  6. android驱动USB摄像头了

    终于搞定android驱动USB摄像头了! 2014-05-28  liuwei200...  文章来源  阅 7655  转 5 转藏到我的图书馆 微信 分享: 多亏了stackoverflow看到 ...

  7. android检查usb广播,Android 检测USB 音频设备

    1.广播检测USB 音频设备 注册广播: "android.hardware.usb.action.USB_DEVICE_ATTACHED"; "android.hard ...

  8. android 申请usb权限,USB 权限申请流程

    USB android授权方式 权限的控制分三块: 1:USB host端有个线程循环检测系统是否USB设备插拔,如果有就找到申请权限的APP并调用起来 2:APP运行后主动申请权限,也就是reque ...

  9. 即插即打!教你快速上手数码复合机USB打印

    在复合机设备的诸多功能中,USB直连打印功能是一项不可忽视的便捷功能.在企业的日常办公中,常规的网络打印固然方便快捷,可是相应的网络故障或者电脑端的驱动异常都有可能造成无法打印的情况,在这种情况下,U ...

  10. android外接usb摄像头demo_手机USB接口有哪些功能 手机USB接口功能介绍【详解】

    手机身上的USB接口主要的任务就是充电,连接PC传输数据,你还能想到其他的功能吗?没错,它还能连接USB小风扇.小台灯等外设.但是,你以为所有手机在实现这些功能时的体验和效果都是一样的吗? 充电速度和 ...

最新文章

  1. LeetCode简单题之只出现一次的数字
  2. STM32 电机教程 17 - 基于ST MotorControl Workbench的电机调试
  3. Mybatis-typeAliases的作用
  4. 动态规划—最长公共子串
  5. ABAP新的关键字:BASE
  6. 支付价格计算中精度问题之double,float
  7. 虚拟机Linux图形界面配置NAT-桥接
  8. java对象初始化顺序的简单验证
  9. exit函数_Linux进程间通信详解(三) 消息队列及函数
  10. Spring MVC - 介绍
  11. 三种射频通信接收机原理框图及优缺点
  12. HackerRank - Stock Maximize
  13. 塞班S60v3版平台手机证书权限内容大解析
  14. 关于静态博客的评论系统
  15. oracle vm server for x86,扛起Xen的大旗!体验Oracle VM Server 3.4.6与基于OL7.7的OVM Manager...
  16. Golang导出并下载excel封装
  17. 【centos8】问题解决:Failed to download metadata for repo ‘appstream‘: Cannot prepare internal mirrorlist:.
  18. html 手指状态,HTML5技术教程 手指按下和手指抬起触发事件
  19. C语言:正负交替的问题
  20. Python项目:外星人入侵(汇总)

热门文章

  1. 闪讯(NetKeeper)——OpenWrt安装闪讯(NetKeeper)插件(校园网电信宽带闪讯(NetKeeper)认证解决方案)
  2. 【计算机组成原理】定点乘法运算之补码一位乘法(Booth算法)(对初学者的步骤详解)
  3. 使程序在后台运行,后台进程实现原理
  4. 模拟CMOS集成电路设计中的电流基准源及用Cadence Virtuoso IC617设计并仿真有关电路
  5. 每台计算机需要配置网关吗,怎么设置一台电脑作为网关
  6. 常见开发工具下载链接
  7. 关于淘宝出售的杀毒软件激活码
  8. 嵌入式系统开发环境的构建08:在Hyper-V中安装Windows XP操作系统
  9. 20211104 为什么相似矩阵的迹相同
  10. Oracle9i学习之boobooke小布版001