Android之USB打印

android+源码usb驱动,安卓打印驱动最全驱动源码库(usbSerialForAndroid) 【实例简介】此项目用于安卓小票打印驱动。(稳定版)已用于实际项目支持:USB转串口线、纯串口阵脚打印线、纯USB打印线、Cp21xx、USB CDC/ACM serial、FTDI Serial项目说明:android_serialport_api 纯串口阵脚线通信,检测设备,读写串口等工具com.hoho.android.usbserial 其他辅助测试类. 可以忽略com.hoho.andro... 阅读详情
AI摘要

本文详细介绍了如何在Android应用中连接和控制USB打印机,包括初始化打印机、设置打印参数、打印文本、条形码和二维码。文章通过UsbPrinter类展示了USB权限请求、ESC/POS指令的使用,以及BytesUtil工具类用于字节操作。同时,ESCUtil类封装了各种打印机指令,如设置字体大小、加粗、对齐方式等,以实现丰富的打印效果。


前言

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


一、效果图

常规出牌,先来效果图,不然你们都不感兴趣往下看了!
在这里插入图片描述

二、使用步骤

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+2
                if (!mUsbManager.hasPermission(device)) {
                    mUsbManager.requestPermission(device, mPermissionIntent);
                } else {
                    connectUsbPrinter(device);
                }
            }
        }

    }

    private final BroadcastReceiver mUsbDeviceReceiver = new BroadcastReceiver() {

        @Override
        public 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 获得此接口的一个节点 返回一个UsbEndpoint
                ep = 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()) {
        @Override
        public 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];
        // xL
        data[0] = (byte) ww;
        // xH
        data[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];
        // xL
        rv[0] = (byte) w;
        // xH
        rv[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];
        // xL
        rv[0] = (byte) bw;
        // xH
        rv[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];
        // xL
        data[0] = (byte) ww;
        // xH
        data[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];
        // xL
        data[0] = (byte) ww;
        // xH
        data[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,
                // upca
                0x1B, 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,
                // upce
                0x1B, 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,
                // ean13
                0x1B, 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,
                // ean8
                0x1B, 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,
                // code39
                0x1B, 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,
                // itf
                0x1B, 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,
                // codebar
                0x1B, 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,
                // code93
                0x1B, 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,
                // code128
                0x1B, 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.创建usbManager; 2.获取到所有设备 选择出满足的设备; 3.查找设备接口; 4.获取设备endpoint; 5.打开conn连接通道; 6.发送打印信息。 注意点: 1.USB权限,在AndroidManifest.xml中添加: 如果要想监听USB连接动作,在相应的activity加上如下 (qwm_usb_xml为要监听的设备信息,例如 阅读详情

相关推荐

关于安卓19的板子通过usb连接打印机打印问题 (非小票打印机器)

很多打印机有提供windows,linux的打印驱动,但是安卓的驱动几乎没有厂家提供,这就导致很多想通过安卓平板控制打印机连接打印的用户无法实现,而市面上面大多数打印软件也是通过蓝牙或者网络来进行连接打印,而不是我们想要的usb线进行打印 在安卓的原生板子里面,提供了打印支持,且大部分打印机厂家也针对原生打印驱动做了兼容,比如惠普啥的(可以直接连接usb先选择文件进行打印测试) ,惠普提供有打印...

nibinusm22b的博客 1543

Android系统下 USB打印机设备节点

Android系统下 USB打印机设备节点实现指南 在现代的Android应用中,USB打印机的集成可以极大地提高用户体验。实现USB打印机设备节点的过程可能会让初学者感到复杂,但通过将其分解为几个步骤,我们可以让这个过程变得简单易懂。本文将指导你如何在Android系统下实现USB打印机设备节点。 流程概述 步骤表格 以...

weixin_32475629的博客 509

ionic安卓打印终极解决方案,支持USB打印

作为一个仪器设备,需要打印很多图表和报表数据.但是安卓对打印功能支持不是太好,试了很多办法,终于获得了一个满意的解决方案 优化前的方案 ionic printer插件 + HP安卓打印插件 + 支持wifi的hp打印机 printer这个插件是ionic下实现html打印功能的插件,它支持传输html字符串. Hp安卓打印插件是官方提供的,安卓就可以使用,当然也可以使用其他打印插件. HP打印机,...

时雨大人的专栏 1976

Android 平板通过USB口连接小票打印机

Android 平板通过 USB 口连接小票打印机 在现代商业环境中,快速、准确地打印小票是每个商家的基本需求之一。Android 平板通过 USB 口连接小票打印机是一个常见的解决方案。本文将详细介绍如何在 Android 平板上实现这一过程,并提供相关的代码示例。 1. 硬件准备 在开始之前,我们需要准备以下硬件设备:...

weixin_36994175的博客 1202

Android USB通信与打印机

本文介绍了如何在Android应用中通过USB与打印机进行通信,并提供了相应的源代码。在移动设备的普及和便携性的提高下,越来越多的人选择在Android手机上进行打印操作。为了实现Android手机与打印机之间的通信,我们需要使用Android的USB通信功能。至此,我们已经完成了Android手机通过USB与打印机进行通信的基本流程。根据具体的打印机型号和通信协议,我们可以在权限被授予时执行相应的打印功能代码。首先,我们需要准备一个支持USB通信的打印机,并确保打印机的驱动程序已经正确安装。

DevGlider的博客 1107

Android 获取 USB 设备类型

接下来,在我们的 Activity 或 Fragment 中,我们需要注册一个 BroadcastReceiver 来接收 USB 设备的连接和断开事件。我们可以通过 Intent.ACTION_UMS_CONNECTED 和 Intent.ACTION_UMS_DISCONNECTED 来监听 USB 设备的连接和断开。为了正确处理不同类型的 USB 设备,我们需要获取 USB 设备的类型信息。根据 USB 设备的类型,我们可以执行不同的操作。根据实际需求,您可以根据不同的设备类型执行相应的逻辑。

pytorchCode的博客 1081

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

android开发中,外接usb设备,以usb打印机为例。

玄昌盛不会编程 2528

Android打印机--没有设备驱动sdk,自己实现USB打印功能

Android下的设备调试,如果设备提供了驱动,按照厂家的驱动调试即可;设备未提供驱动,只能按照通用的方法进行调试。对于智能POS、收银机以及其他打印设备,如果厂商不提供打印相关sdk,那么打印功能怎么实现呢?其实我们可以基于USB通信机制,自己去实现打印驱动。整个实现流程如下 初始化打印机:首先要获取USB管理器;其次要注册监听USB设备插拔变化和请求权限的广播;最后列出所有的USB设备,并且都请......

学无止境 2万+

Android USB打印开发

USB打印开发 最近对接了一些硬件设备,其中需要通过USB通讯去打印,通过学习自己实现了一下 先看看google官方文档 https://developer.android.google.cn/guide/topics/connectivity/usb/host.html USB通讯主要看的还是业务逻辑 1.注册USB广播,获取到设备上连接的所有USB设备,采用集合的思想管理 HashMap<String, UsbDevice> deviceList = usbManager.getDevice

itheima123456的博客 1621

实现安卓设备与USB打印机的连接指南

USB OTG(On-The-Go)技术是一种允许设备在没有主机的情况下相互通信的协议。它使得USB设备之间可以直接连接,进行数据交换。这项技术主要用于移动设备如智能手机和平板电脑,极大地扩展了它们的功能,使得用户可以直接从设备上打印文件、连接游戏控制器等。UsbManagerUsbManager类是Android SDK中用于管理USB设备连接的类。它提供了访问连接到设备上的USB设备的接口,能够帮助开发者枚举和管理所有连接的USB设备。UsbManager。

weixin_42181686的博客 2602

实现Android USB小票打印机打印功能

USB主机模式,也就是USB On-The-Go(OTG),是一种允许Android设备直接连接到USB设备的模式。通过这一模式,用户可以利用Android手机或平板电脑进行文件传输、视频输出、音频播放等操作。对于打印机而言,这使得从Android设备直接打印文档或照片成为可能。随着技术的进步,打印技术已经从最初的点阵打印机、针式打印机发展到如今的智能打印机。传统打印机主要通过并行端口或串行端口与计算机相连,依赖于大量的纸张和墨水,并且需要用户手动装纸和更换墨盒。

weixin_36019375的博客 1651

Android的USB打印机部署

一、综述 android系统现多用于手持设备,为手机等设备应用提供了很好的系统级支持。但对于PC机常用的打印功能,android到目前并不支持,也没有打印机厂家专门为android设备做打印机驱动。因此在android上实现usb打印功能有一点繁琐。本文提供了androidjava应用程序实现usb打印的一种方案。这个方案在android系统中打开了一条实现usb打印的从上层应用到内核配置的通路

等价交换的专栏 2133

AndroidUSBPrinterDemo 安卓USB连接打印机Demo

AndroidUSBPrinterDemo 安卓USB连接打印机Demo,安卓USB连接打印机实现打印Demo,封装了打印工具类方便使用

android intent 打印,如何从android检测和打印USB打印机

我正在创建一个Android应用程序(最低API级别16),可以从我的Android设备打印文档,其中打印机通过USB连接。 我find了一个从这个链接中检测USB的代码。 我通过USB连接了打印机(HP Laserjet P1007)。 但它无法检测到打印机。编辑我在检测打印机方面取得了一些进展。 我能够检测到打印机。 但我仍然无法通过批量转移进行打印。 我也尝试使用usbRequest.que...

weixin_30047651的博客 640

安卓设备连接USB打印机

安卓设备连接USB打印机,类似超市柜台的收银机等安卓设备连接的USB打印机。

浅谈MOS管的发热原因和解决办法

解读一下开关管发热原因,解决方案和开关损耗测试。

qq_45508321的博客 1万+

Android连接USB打印机

项目中需要用到android设备通过USB连接热敏打印机打印图文混排的小条,总结一下。 外部主要是用这个方法来打印: /** * 打印核验小条 * 子线程中运行 */ private static int times = 0; public void printVerifyData(String tmpName, ...

dami_lixm的专栏 4191

手把手调试Android 10 DHCP服务:从dumpsys network_stack到DhcpServer.java的实战技巧

本文详细介绍了在Android 10中调试DHCP服务的实战技巧,从使用dumpsys network_stack分析服务状态到深入DhcpServer.java源码追踪问题。文章提供了完整的工具链配置、关键调试命令和常见问题解决方案,帮助开发者高效解决DHCP服务未启动、IP分配失败等典型问题,特别适合需要深入理解Android网络架构的开发者参考。

uu89012的博客 743

安卓usb接口与串口打印机_安卓手机USB直连打印机详细教程

最近大家在家上网课,作业、试卷之类都需要自己打印,打印机前所未有地畅销,于是各打印机品牌纷纷涨价,本来预算能够买个微信款的打印机,结果现在只能买USB款了,本来想直接使用手机打印的,现在不得不乖乖回到电脑上打印了……其实普通的USB打印机一样可以享受手机打印哦,只不过不是无线连接,而是用USB线将手机跟打印机连接后再打印,下面就跟着我来试试吧。硬件准备安卓手机一部、USB接口打印机一台、...

weixin_39785422的博客 1万+

使用再生龙还原镜像文件到硬盘

1. 把制作好的再生龙光盘插入需要的电脑,开机按F4使用再生龙启动2. 选择默认的:Clonezailla live(Default settings,VGA 800*600),然后等待几分钟 3. 选择语言:简体中文 4. 选择不修改键盘映射 5. 选择使用再生龙          6. 选择硬盘/分区(存到/来自)镜像文件,此选项既可以制作镜像,也可以恢复镜像。 7. 使用本机的分区     ...

weixin_42168893的博客 1万+

分布式数据采集框架openclaw-worker:模块化设计与实战指南

数据采集是获取网络信息、实现自动化处理的基础技术,其核心原理是通过模拟HTTP请求从目标源提取结构化数据。在工程实践中,传统单体脚本面临维护困难、扩展性差等挑战。分布式采集架构通过解耦任务定义与执行,结合消息队列实现水平扩展,显著提升了系统的弹性与可靠性。openclaw-worker作为模块化的工作节点,将采集流程配置化,支持CSS选择器、XPath等多种提取规则,并集成请求速率控制、代理IP池等反爬策略,适用于竞品监控、内容聚合等需要高效、稳定获取数据的应用场景。

weixin_28706423的博客 299
上一篇: Android之两级联动点餐列表
下一篇: Andorid之拍照及相册选取照片回显
叶已初秋
博客等级 码龄11年 2684粉丝 82原创
评论 30
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叶已初秋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值