网站、APP、小程序、软件、硬件定制开发,联系QQ:99605319

本文由 资源共享网 – ziyuan 发布,转载请注明出处,如有问题请联系我们![免费]整合了 蓝牙、USB 和 网络 三种连接方式的ESC/POS打印类(用于小票热敏打印机)

收藏

主要功能:

  1. 连接状态检测:提供方法检测打印机是否连接成功。

  2. 多语言支持:支持设置打印机字符集,适配多语言环境。

  3. 打印缓冲区控制:提供方法清空打印缓冲区。

  4. 更详细的错误处理:增加对连接失败、命令发送失败等情况的处理。

  5. 日志优化:增加更详细的日志信息,便于调试。

  6. 代码结构优化:将连接逻辑和打印逻辑分离,提高代码可读性和可维护性。

  7. 打印状态检测:提供方法检测打印机状态(如缺纸、开盖等)。

  8. 打印速度控制:支持设置打印速度。

  9. 黑白反色打印:支持设置黑白反色打印模式。

  10. 走纸控制:支持走纸到指定行。

  1. 打印状态检测:

    • getPrinterStatus() 方法用于获取打印机状态(如缺纸、开盖等)。

  2. 打印速度控制:

    • setPrintSpeed(int speed) 方法用于设置打印速度(慢速、中速、快速)。

  3. 黑白反色打印:

    • setInvertColor(boolean invert) 方法用于设置黑白反色打印模式。

  4. 走纸控制:

    • feedPaper(int lines) 方法用于走纸到指定行。

package com.example.escpos;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
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.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.UUID;

public class EscPosPrinter {

    private static final String TAG = "EscPosPrinter";
    private static final UUID BLUETOOTH_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    // 连接方式枚举
    public enum ConnectionType {
        BLUETOOTH,
        USB,
        NETWORK
    }

    private ConnectionType connectionType;
    private BluetoothSocket bluetoothSocket;
    private Socket networkSocket;
    private UsbDeviceConnection usbConnection;
    private UsbEndpoint usbEndpoint;
    private OutputStream outputStream;
    private InputStream inputStream;
    private boolean isConnected = false;

    /**
     * 构造函数(蓝牙连接)
     *
     * @param device 蓝牙设备对象
     */
    public EscPosPrinter(BluetoothDevice device) {
        this.connectionType = ConnectionType.BLUETOOTH;
        try {
            bluetoothSocket = device.createRfcommSocketToServiceRecord(BLUETOOTH_UUID);
            bluetoothSocket.connect();
            outputStream = bluetoothSocket.getOutputStream();
            inputStream = bluetoothSocket.getInputStream();
            isConnected = true;
            Log.i(TAG, "蓝牙连接成功");
        } catch (IOException e) {
            Log.e(TAG, "蓝牙连接失败", e);
        }
    }

    /**
     * 构造函数(USB 连接)
     *  link:www.08i8.com
     * @param context 上下文对象
     * @param device  USB 设备对象
     */
    public EscPosPrinter(Context context, UsbDevice device) {
        this.connectionType = ConnectionType.USB;
        UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
        if (usbManager != null && device != null) {
            UsbInterface usbInterface = device.getInterface(0);
            usbEndpoint = usbInterface.getEndpoint(0);

            usbConnection = usbManager.openDevice(device);
            if (usbConnection != null && usbConnection.claimInterface(usbInterface, true)) {
                isConnected = true;
                Log.i(TAG, "USB 连接成功");
            } else {
                Log.e(TAG, "USB 连接失败");
            }
        } else {
            Log.e(TAG, "USB 设备未找到");
        }
    }

    /**
     * 构造函数(网络连接)
     *
     * @param ip   打印机 IP 地址
     * @param port 打印机端口(默认 9100)
     */
    public EscPosPrinter(String ip, int port) {
        this.connectionType = ConnectionType.NETWORK;
        try {
            networkSocket = new Socket(ip, port);
            outputStream = networkSocket.getOutputStream();
            inputStream = networkSocket.getInputStream();
            isConnected = true;
            Log.i(TAG, "网络连接成功");
        } catch (IOException e) {
            Log.e(TAG, "网络连接失败", e);
        }
    }

    /**
     * 检查打印机是否连接成功
     *
     * @return 是否连接成功
     */
    public boolean isConnected() {
        return isConnected;
    }

    /**
     * 初始化打印机(重置打印机状态)
     */
    public void initPrinter() {
        sendCommand(new byte[]{0x1B, 0x40}); // ESC @
        Log.i(TAG, "打印机初始化成功");
    }

    /**
     * 打印文本
     *
     * @param text 要打印的文本
     */
    public void printText(String text) {
        try {
            byte[] data = text.getBytes("GBK"); // 使用 GBK 编码
            sendCommand(data);
            Log.i(TAG, "打印文本成功: " + text);
        } catch (IOException e) {
            Log.e(TAG, "打印文本失败", e);
        }
    }

    /**
     * 打印一行文本(自动换行)
     *
     * @param line 要打印的文本
     */
    public void printLine(String line) {
        printText(line + "\n");
    }

    /**
     * 设置字体大小
     *
     * @param width  字体宽度倍数(1-8)
     * @param height 字体高度倍数(1-8)
     */
    public void setFontSize(int width, int height) {
        if (width < 1 || width > 8 || height < 1 || height > 8) {
            throw new IllegalArgumentException("字体大小倍数必须在 1-8 之间");
        }
        byte[] command = new byte[]{0x1D, 0x21, (byte) (((width - 1) << 4) | (height - 1))}; // GS !
        sendCommand(command);
        Log.i(TAG, "设置字体大小成功: 宽度=" + width + ", 高度=" + height);
    }

    /**
     * 设置对齐方式
     *
     * @param alignment 对齐方式:0-左对齐,1-居中对齐,2-右对齐
     */
    public void setAlignment(int alignment) {
        if (alignment < 0 || alignment > 2) {
            throw new IllegalArgumentException("对齐方式必须是 0-左对齐, 1-居中对齐, 2-右对齐");
        }
        byte[] command = new byte[]{0x1B, 0x61, (byte) alignment}; // ESC a
        sendCommand(command);
        Log.i(TAG, "设置对齐方式成功: " + alignment);
    }

    /**
     * 设置加粗模式
     *
     * @param bold 是否加粗:true-加粗,false-取消加粗
     */
    public void setBold(boolean bold) {
        byte[] command = new byte[]{0x1B, 0x45, (byte) (bold ? 1 : 0)}; // ESC E
        sendCommand(command);
        Log.i(TAG, "设置加粗模式成功: " + bold);
    }

    /**
     * 设置下划线模式
     *
     * @param underline 是否启用下划线:true-启用,false-禁用
     */
    public void setUnderline(boolean underline) {
        byte[] command = new byte[]{0x1B, 0x2D, (byte) (underline ? 1 : 0)}; // ESC -
        sendCommand(command);
        Log.i(TAG, "设置下划线模式成功: " + underline);
    }

    /**
     * 设置行间距
     *
     * @param spacing 行间距(单位:点,默认 30)
     */
    public void setLineSpacing(int spacing) {
        byte[] command = new byte[]{0x1B, 0x33, (byte) spacing}; // ESC 3
        sendCommand(command);
        Log.i(TAG, "设置行间距成功: " + spacing);
    }

    /**
     * 设置字符集
     *
     * @param charset 字符集代码(例如:0x1B, 0x74, 0x02 表示中文)
     */
    public void setCharset(byte charset) {
        byte[] command = new byte[]{0x1B, 0x74, charset}; // ESC t
        sendCommand(command);
        Log.i(TAG, "设置字符集成功: " + charset);
    }

    /**
     * 清空打印缓冲区
     */
    public void clearBuffer() {
        sendCommand(new byte[]{0x1B, 0x40}); // ESC @
        Log.i(TAG, "清空打印缓冲区成功");
    }

    /**
     * 打印条码
     *
     * @param barcode 条码内容
     * @param type    条码类型:0-UPC-A, 1-UPC-E, 2-EAN13, 3-EAN8, 4-CODE39, 5-ITF, 6-CODEBAR, 7-CODE93, 8-CODE128
     */
    public void printBarcode(String barcode, int type) {
        if (type < 0 || type > 8) {
            throw new IllegalArgumentException("条码类型必须是 0-8");
        }
        try {
            byte[] command = new byte[]{0x1D, 0x6B, (byte) type}; // GS k
            sendCommand(command);
            sendCommand(barcode.getBytes("GBK"));
            sendCommand(new byte[]{0}); // 结束符
            Log.i(TAG, "打印条码成功: " + barcode);
        } catch (IOException e) {
            Log.e(TAG, "打印条码失败", e);
        }
    }

    /**
     * 打印二维码
     *
     * @param qrCode 二维码内容
     */
    public void printQRCode(String qrCode) {
        try {
            // 设置二维码大小
            byte[] sizeCommand = new byte[]{0x1D, 0x28, 0x6B, 0x03, 0x00, 0x31, 0x43, 0x08}; // GS ( k
            sendCommand(sizeCommand);

            // 设置二维码纠错等级
            byte[] levelCommand = new byte[]{0x1D, 0x28, 0x6B, 0x03, 0x00, 0x31, 0x45, 0x31}; // GS ( k
            sendCommand(levelCommand);

            // 写入二维码数据
            byte[] data = qrCode.getBytes("GBK");
            byte[] dataCommand = new byte[]{0x1D, 0x28, 0x6B, (byte) (data.length + 3), 0x00, 0x31, 0x50, 0x30};
            sendCommand(dataCommand);
            sendCommand(data);

            // 打印二维码
            byte[] printCommand = new byte[]{0x1D, 0x28, 0x6B, 0x03, 0x00, 0x31, 0x51, 0x30}; // GS ( k
            sendCommand(printCommand);
            Log.i(TAG, "打印二维码成功: " + qrCode);
        } catch (IOException e) {
            Log.e(TAG, "打印二维码失败", e);
        }
    }

    /**
     * 打印图片
     *
     * @param bitmap 要打印的图片
     */
    public void printImage(Bitmap bitmap) {
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        byte[] command = new byte[]{0x1D, 0x76, 0x30, 0x00, (byte) (width & 0xFF), (byte) ((width >> 8) & 0xFF), (byte) (height & 0xFF), (byte) ((height >> 8) & 0xFF)};
        sendCommand(command);

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int pixel = bitmap.getPixel(x, y);
                if (Color.red(pixel) < 128 && Color.green(pixel) < 128 && Color.blue(pixel) < 128) {
                    sendCommand(new byte[]{0x01});
                } else {
                    sendCommand(new byte[]{0x00});
                }
            }
        }
        Log.i(TAG, "打印图片成功");
    }

    /**
     * 切纸
     */
    public void cutPaper() {
        sendCommand(new byte[]{0x1D, 0x56, 0x41, 0x10}); // GS V A
        Log.i(TAG, "切纸成功");
    }

    /**
     * 获取打印机状态
     *
     * @return 打印机状态字节
     */
    public byte getPrinterStatus() {
        try {
            sendCommand(new byte[]{0x1B, 0x76, 0x00}); // ESC v
            return (byte) inputStream.read();
        } catch (IOException e) {
            Log.e(TAG, "获取打印机状态失败", e);
            return -1;
        }
    }

    /**
     * 设置打印速度
     *
     * @param speed 打印速度:0-慢速,1-中速,2-快速
     */
    public void setPrintSpeed(int speed) {
        if (speed < 0 || speed > 2) {
            throw new IllegalArgumentException("打印速度必须是 0-慢速, 1-中速, 2-快速");
        }
        byte[] command = new byte[]{0x1B, 0x73, (byte) speed}; // ESC s
        sendCommand(command);
        Log.i(TAG, "设置打印速度成功: " + speed);
    }

    /**
     * 设置黑白反色打印
     *
     * @param invert 是否反色:true-反色,false-正常
     */
    public void setInvertColor(boolean invert) {
        byte[] command = new byte[]{0x1D, 0x42, (byte) (invert ? 1 : 0)}; // GS B
        sendCommand(command);
        Log.i(TAG, "设置黑白反色打印成功: " + invert);
    }

    /**
     * 走纸到指定行
     *
     * @param lines 走纸行数
     */
    public void feedPaper(int lines) {
        byte[] command = new byte[]{0x1B, 0x64, (byte) lines}; // ESC d
        sendCommand(command);
        Log.i(TAG, "走纸成功: " + lines + " 行");
    }

    /**
     * 关闭连接
     */
    public void close() {
        try {
            if (outputStream != null) {
                outputStream.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
            switch (connectionType) {
                case BLUETOOTH:
                    if (bluetoothSocket != null) {
                        bluetoothSocket.close();
                    }
                    break;
                case USB:
                    if (usbConnection != null) {
                        usbConnection.close();
                    }
                    break;
                case NETWORK:
                    if (networkSocket != null) {
                        networkSocket.close();
                    }
                    break;
            }
            isConnected = false;
            Log.i(TAG, "连接已关闭");
        } catch (IOException e) {
            Log.e(TAG, "关闭连接失败", e);
        }
    }

    /**
     * 发送命令到打印机
     *
     * @param command 命令字节数组
     */
    private void sendCommand(byte[] command) {
        try {
            switch (connectionType) {
                case BLUETOOTH:
                case NETWORK:
                    if (outputStream != null) {
                        outputStream.write(command);
                        outputStream.flush();
                    }
                    break;
                case USB:
                    if (usbConnection != null && usbEndpoint != null) {
                        usbConnection.bulkTransfer(usbEndpoint, command, command.length, 5000);
                    }
                    break;
            }
        } catch (IOException e) {
            Log.e(TAG, "发送命令失败", e);
        }
    }
}


用法:蓝牙连接

BluetoothDevice device = ...; // 获取蓝牙设备
EscPosPrinter printer = new EscPosPrinter(device);
if (printer.isConnected()) {
    printer.initPrinter();
    printer.printLine("蓝牙连接测试");
    printer.close();
}


用法:USB 连接

UsbDevice usbDevice = ...; // 获取 USB 设备
EscPosPrinter printer = new EscPosPrinter(context, usbDevice);
if (printer.isConnected()) {
    printer.initPrinter();
    printer.printLine("USB 连接测试");
    printer.close();
}

用法:网络连接

String printerIp = "192.168.1.100"; // 打印机 IP 地址
int printerPort = 9100; // 打印机端口
EscPosPrinter printer = new EscPosPrinter(printerIp, printerPort);
if (printer.isConnected()) {
    printer.initPrinter();
    printer.printLine("网络连接测试");
    printer.close();
}



评论(0条)

admin admin
ziyuan

ziyuan Rank: 16

0

0

0

( 此人很懒并没有留下什么~~ )

首页

栏目

搜索

会员