本文由 资源共享网 – ziyuan 发布,转载请注明出处,如有问题请联系我们![免费]整合了 蓝牙、USB 和 网络 三种连接方式的ESC/POS打印类(用于小票热敏打印机)
收藏主要功能:
连接状态检测:提供方法检测打印机是否连接成功。
多语言支持:支持设置打印机字符集,适配多语言环境。
打印缓冲区控制:提供方法清空打印缓冲区。
更详细的错误处理:增加对连接失败、命令发送失败等情况的处理。
日志优化:增加更详细的日志信息,便于调试。
代码结构优化:将连接逻辑和打印逻辑分离,提高代码可读性和可维护性。
打印状态检测:提供方法检测打印机状态(如缺纸、开盖等)。
打印速度控制:支持设置打印速度。
黑白反色打印:支持设置黑白反色打印模式。
走纸控制:支持走纸到指定行。
打印状态检测:
getPrinterStatus() 方法用于获取打印机状态(如缺纸、开盖等)。
打印速度控制:
setPrintSpeed(int speed) 方法用于设置打印速度(慢速、中速、快速)。
黑白反色打印:
setInvertColor(boolean invert) 方法用于设置黑白反色打印模式。
走纸控制:
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(); }