本文由 资源共享网 – 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();
}
