Android sockot连接打印机EPSON ESC/POS指令打印

sockot连接打印机EPSON ESC/POS指令打印

 接了一个需求,需要用Android pad连接打印机进行打印,以前倒是没接触过,这次在网上找了下资料,简单实现了下需求。
 在这记录下相关代码以及踩的坑
  • 首先第一步就是通过socket连接打印机
  • 再通过socket发送打印指令就行

代码步骤都比较简单,先看下代码

public class EscPos {
    public static final byte FS = 0x1C;
    public static final byte HT = 0x9;
    public static final byte LF = 0x0A;
    public static final byte CR = 0x0D;
    public static final byte ESC = 0x1B;
    public static final byte DLE = 0x10;
    public static final byte GS = 0x1D;
    public static final byte STX = 0x02;
    public static final byte US = 0x1F;
    public static final byte CAN = 0x18;
    public static final byte CLR = 0x0C;
    public static final byte EOT = 0x04;
    /* 初始化打印机 */
    public static final byte[] ESC_INIT = new byte[]{ESC, '@'};
    /* 设置标准模式 */
    public static final byte[] ESC_STANDARD = new byte[]{ESC, 'S'};
    /* 设置汉字打印模式 */
    public static final byte[] ESC_CN_FONT = new byte[]{FS, '&'};
    /* 选择字符集 */
    public static final byte[] ESC_SELECT_CHARACTER = new byte[]{ESC, 'R', 9};
    /* 设置用户自定义汉字字体 焗7118 */
    public static final byte[] ESC_FS_2 = new byte[]{FS, 0x32, 0x71, 0x18};
    /* 取消用户自定义字体 */
    public static final byte[] ESC_CANCEL_DEFINE_FONT = new byte[]{ESC, '%', 0};
    /* 打开钱箱指令 */
    public static final byte[] ESC_OPEN_DRAWER = new byte[]{ESC, 'p', 0x00, 0x10, (byte) 0xff};
    /* 切纸指令GS V m
     * m 0,48 Executes a full cut(cuts the paper completely)
     * 1,49 Excutes a partilal cut(one point left uncut)
     */
    public static final byte[] POS_CUT_MODE_FULL = new byte[]{GS, 'V', 0x00};
    public static final byte[] POS_CUT_MODE_PARTIAL = new byte[]{GS, 'V', 0x01};
    /* 西文字符 (半宽)字体A (6 ×12),汉字字符 (全宽)字体A (12×12) */
    public static final byte[] ESC_FONT_A = new byte[]{ESC, '!', 0};
    /* 西文字符 (半宽)字体B (8×16),汉字字符 (全宽)字体B (16×16) */
    public static final byte[] ESC_FONT_B = new byte[]{ESC, '!', 1};
    /* 12*24 0/48*/
    public static final byte[] ESC_FONTA = new byte[]{ESC, 'M', 48};
    /* 9*17 1/49*/
    public static final byte[] ESC_FONTB = new byte[]{ESC, 'M', 1};
    /* 默认颜色字体指令 */
    public static final byte[] ESC_FONT_COLOR_DEFAULT = new byte[]{ESC, 'r', 0x00};
    /* 红色字体指令 */
    public static final byte[] ESC_FONT_COLOR_RED = new byte[]{ESC, 'r', 0x01};
    /* 标准大小 */
    public static final byte[] FS_FONT_ALIGN = new byte[]{FS, 0x21, 1, ESC, 0x21, 1};
    /* 横向放大一倍 */
    public static final byte[] FS_FONT_ALIGN_DOUBLE = new byte[]{FS, 0x21, 4, ESC, 0x21, 4};
    /* 纵向放大一倍 */
    public static final byte[] FS_FONT_VERTICAL_DOUBLE = new byte[]{FS, 0x21, 8, ESC, 0x21, 8, GS, '!', 0x01};
    /* 横向纵向都放大一倍 */
    public static final byte[] FS_FONT_DOUBLE = new byte[]{FS, 0x21, 12, ESC, 0x21, 48};
    /* 靠左打印命令 */
    public static final byte[] ESC_ALIGN_LEFT = new byte[]{0x1b, 'a', 0x00};
    /* 居中打印命令 */
    public static final byte[] ESC_ALIGN_CENTER = new byte[]{0x1b, 'a', 0x01};
    /* 靠右打印命令 */
    public static final byte[] ESC_ALIGN_RIGHT = new byte[]{0x1b, 'a', 0x02};
    /* 字体加粗 */
    public static final byte[] ESC_SETTING_BOLD = new byte[]{ESC, 0x45, 1};
    /* 取消字体加粗 */
    public static final byte[] ESC_CANCEL_BOLD = new byte[]{ESC, 0x45, 0};
    public static final int STATE_1 = 1;// 创建Socket连接
    public static final int STATE_2 = 2;// 获取输出流
    public static final int STATE_3 = 3;// 关闭Socket
    public static final int STATE_0 = 0;// 成功
    public static final int ERROR_2 = -2;// 创建Socket失败
    public static final int ERROR_3 = -3;// 获取输出流失败
    public static final int ERROR_4 = -4;// 关闭Socket出错
    public static final int ERROR_100 = -100;// 失败
    // 通过socket流进行读写
    private OutputStream socketOut = null;
    // 以ip作为key,EscPos实例作为value的Map
    private static Map posMap = new HashMap();
    private static EscPos escPos = null;
    // 默认端口
    public static int DEFAULT_PORT = 9100;
    private Socket socket;
    private OnPrinterListener listener;
    private String ip;
    private int port;
    /**
     * 根据ip、端口、字符编码构造工具类实例
     *
     * @param ip   打印机ip
     * @param port 打印机端口,默认9100
     * @throws IOException
     */
    public EscPos(String ip, int port) {
        this.ip = ip;
        this.port = port;
    }
    public synchronized static EscPos getInstance(String ip, Integer port) {
        escPos = posMap.get(ip);
        if (escPos == null) {
            escPos = new EscPos(ip, port);
        }
        return escPos;
    }
    public static synchronized EscPos getInstance(String ip) {
        return getInstance(ip, DEFAULT_PORT);
    }
    public static synchronized EscPos getInstance() {
    	//这儿写死或者传入打印机地址和端口
        return getInstance("",
                "";
    }
    public static void myPrinter(final List list, final OnPrinterListener printerListener) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                EscPos escPos = EscPos.getInstance();
                escPos.setListener(printerListener);
                escPos.connectSocket();
                try {
                    escPos.init();
                    for (int i = 0; i < list.size(); i++) {
                        escPos.line(1);
                        escPos.boldOff(true);
                        escPos.printStr(list.get(i));
                        //escPos.printStr("测试字体6");
                    }
                    escPos.line(10);
                    escPos.feedAndCut();
                    escPos.closeIOAndSocket();
                    printerListener.onListener(STATE_0);
                } catch (IOException e) {
                    printerListener.onError(ERROR_100);
                    LOGGER.error("Socket printer write ===> ", e);
                    e.printStackTrace();
                }
            }
        };
        new Thread(runnable).start();
    }
    public void connectSocket() {
        try {
            socket = new Socket();
            SocketAddress socAddress = new InetSocketAddress(ip, port);
            socket.connect(socAddress, 5000);
            if (listener != null) {
                listener.onListener(STATE_1);
            }
            try {
                socketOut = socket.getOutputStream();
                if (listener != null) {
                    listener.onListener(STATE_2);
                }
            } catch (IOException e) {
                if (listener != null) {
                    listener.onError(ERROR_3);
                }
                LOGGER.error("Socket printer getOutputStream ===> ", e);
                e.printStackTrace();
            }
        } catch (IOException e) {
            if (listener != null) {
                listener.onError(ERROR_2);
            }
            LOGGER.error("Socket printer connect ===> ", e);
            e.printStackTrace();
        }
    }
    /**
     * 换行
     *
     * @param lineNum 换行数,0为不换行
     * @return
     * @throws IOException
     */
    public EscPos line(int lineNum) throws IOException {
        for (int i = 0; i < lineNum; i++) {
            socketOut.write("\n".getBytes());
            socketOut.flush();
        }
        return this;
    }
    /**
     * 加粗
     *
     * @param flag false为不加粗
     * @return
     * @throws IOException
     */
    public EscPos bold(boolean flag) throws IOException {
        if (flag) {
            socketOut.write(ESC_SETTING_BOLD);
        }
        return this;
    }
    /**
     * 取消粗体
     *
     * @param flag true为取消粗体模式
     * @return
     * @throws IOException
     */
    public EscPos boldOff(boolean flag) throws IOException {
        if (flag) {
            socketOut.write(ESC_CANCEL_BOLD);
            //socketOut.write(FS_FONT_DOUBLE);
        }
        return this;
    }
    /**
     * 初始化打印机
     *
     * @return
     * @throws IOException
     */
    EscPos init() throws IOException {
        socketOut.write(ESC_INIT);
        return this;
    }
    /**
     * 打印空白
     *
     * @param length 需要打印空白的长度
     * @throws IOException
     */
    private void printSpace(int length) throws IOException {
        for (int i = 0; i < length; i++) {
            socketOut.write(" ".getBytes());
        }
        socketOut.flush();
    }
    /**
     * 进纸并全部切割
     *
     * @return
     * @throws IOException
     */
    public EscPos feedAndCut() throws IOException {
        socketOut.write(POS_CUT_MODE_FULL);
        socketOut.flush();
        return this;
    }
    public void closeIOAndSocket() {
        try {
            socketOut.close();
            socket.close();
            if (listener != null) {
                listener.onListener(STATE_3);
            }
        } catch (IOException e) {
            if (listener != null) {
                listener.onError(ERROR_4);
            }
            LOGGER.error("Socket printer close ===> ", e);
            e.printStackTrace();
        }
    }
    /**
     * 打印字符串
     *
     * @param str 所需打印字符串
     * @return
     * @throws IOException
     */
    public EscPos printStr(String str) throws IOException {
        socketOut.write(ESC_CN_FONT);
        socketOut.write(str.getBytes(Charset.forName("GBK")));
        socketOut.write(LF);
        socketOut.flush();
        return this;
    }
    public void setListener(OnPrinterListener listener) {
        this.listener = listener;
    }
    public interface OnPrinterListener {
        void onListener(int status);
        void onError(int errorCode);
    }
}

打印调用示例代码

//printerData 是list类型的数据   循环打印文案 
EscPos.myPrinter(printerData, new EscPos.OnPrinterListener() {
                    @Override
                    public void onListener(int status) {

                    }

                    @Override
                    public void onError(final int errorCode) {
                        ((Activity) context).runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                //此时已在主线程中,可以更新UI了
                                if (errorCode == EscPos.ERROR_2) {
                                    Toast.makeText(context, "连接打印机失败", Toast.LENGTH_SHORT).show();
                                } else {
                                    Toast.makeText(context, "打印异常", Toast.LENGTH_SHORT).show();
                                }
                            }
                        });
                    }
                });

过程遇到的坑

  • socket连不上打印机
    1.确保打印机的网和手机在同一个网段内
    2.打印机端口和地址正确(可百度查询如何确定打印机IP和端口)

  • socket发送打印指令不起作用
    这个当时坑死我了,我用一个串测试“hello word” ,结果就因为中间多加了空格,就是打印不出来,后来才知道,这种空格没法打印,一定要写个简单的串先测试。

你可能感兴趣的:(android开发)