Android连接汉印打印机打印文件

1,338 阅读2分钟

Android连接汉印打印机打印文件

项目地址:gitee.com/print

这个项目包含多个Android模块,其中的print模块就是汉印打印机功能。

汉印打印机使用1.png

汉印打印机使用2.jpg

他们的技术人员也提供了一个demo,这里写这个功能的原因为:

  • 1.原demo写的比较粗糙,这里对一些方法进行优化
  • 2.增加PrintFragment弹窗页面让打印功能使用更方便
  • 3.增加Download下载Pdf文件功能,先下载后打开Paf并打印

具体代码看项目即可,这里讲一下比较关键的代码:

一、关键代码分析:

  • 1.打印机连接成功之后,下次可以直接使用而不需要再次连接。在MyApplication中增加ConnectRes字段记录打印机连接状态。
  • 2.连接打印机的方法HPRTPrinterHelper.INSTANCE.connect是子线程操作的,如果要显示连接结果就要回传到主线程里面。这里使用Handler回传结果并更新UI。
    class PrintStep1Holder {
        ......
    
        private void initRecyclerView() {
            devicesAdapter = new DevicesAdapter(getActivity(), bluetoothDevice -> {
                //第二步:连接打印机
                if (bluetoothDevice != null) {
                    showShort("连接打印机中...");
                    mHandler.post(() -> {
                        Message message = Message.obtain();
                        try {
                            connectRes = HPRTPrinterHelper.INSTANCE.connect(bluetoothDevice.getAddress());
                            message.what = CONNECT_RESULT;
                            message.arg1 = 0;
                        } catch (CustomerCodeException e) {
                            e.printStackTrace();
                            message.arg1 = -1;
                        }
                        mHandler.sendMessage(message);
                    });
                }
            });
            device_rv.setAdapter(devicesAdapter);
            device_rv.setLayoutManager(new LinearLayoutManager(getActivity()));
        }
    }
    
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case CONNECT_RESULT:
                    int connect = msg.arg1;
                    if (connect == -1) showShort(R.string.customer_code_error);
                    else showShort(connectRes ? "连接成功!" : "连接失败!");
                    MyApplication.getInstance().setConnectRes(connectRes);
                    if (connectRes) {
                        printStep1Holder.setStep1Visibility(View.GONE);
                        printStep2Holder.setStep2Visibility(View.VISIBLE);
                        getDeviceInfo();
                    }
                    break;
                ......
            }
        }
    };
    
  • 3.获取打印机信息,每一个方法都是在子线程执行,如果同时执行多个可能会出现错误。这里使用info_flag标志来逐步获取每个信息。
    private void getDeviceInfo() {
        if (info_flag == 1)
            HPRTPrinterHelper.INSTANCE.getPrintName(s -> printStep2Holder.setInfoText(s));
        if (info_flag == 2)
            HPRTPrinterHelper.INSTANCE.getPrinterNo(s -> printStep2Holder.setInfoText(s));
        if (info_flag == 3)
            HPRTPrinterHelper.INSTANCE.getFirmwareVersion(s -> printStep2Holder.setInfoText(s));
        if (info_flag == 4)
            HPRTPrinterHelper.INSTANCE.getCarbonNo(s -> printStep2Holder.setInfoText(s));
        if (info_flag == 5)
            HPRTPrinterHelper.INSTANCE.getCarbonSurplus(i -> printStep2Holder.setInfoText(String.valueOf(i)));
        else {
            initStateListener();
            getDeviceState(null);
        }
    }
    
    class PrintStep2Holder {
        public void setInfoText(String text) {
            getActivity().runOnUiThread(() -> {
                if (info_flag == 1) device_name_tv.setText("设备名称:" + text);
                if (info_flag == 2) device_number_tv.setText("设备编号:" + text);
                if (info_flag == 3) device_firmware_code_tv.setText("固件版本:" + text);
                if (info_flag == 4) device_carbon_belt_tv.setText("碳带型号:" + text);
                if (info_flag == 5)
                    device_carbon_belt_remain_tv.setText("碳带剩余:" + text + " (单位:mm)");
                info_flag++;
                getDeviceInfo();
            });
        }
    }
    
  • 4.获取打印机状态逻辑优化,每次执行打印前都执行HPRTPrinterHelper.INSTANCE.checkState();检查打印机状态。如果打印机状态异常则提示异常信息,不执行打印方法。
    private void getDeviceState(GetStateListener getStateListener) {
        HPRTPrinterHelper.INSTANCE.checkState();
        this.getStateListener = getStateListener;
    }
    
    private void initStateListener() {
        //在设置监听的时候就添加【getStateListener】接口回调,有回调的时候就回调错误信息,没有的时候就不回调
        HPRTPrinterHelper.INSTANCE.attachPrinterStateListener(new PrinterStateListener() {
                @Override
                public void onState(int state) {
                    if (getStateListener != null) {
                        getStateListener.backState(PrintUtils.getState(state));
                        getStateListener = null;
                    }
                }
                ...
            });
        }
    }
    //单纯获取设备状态时,设置回调为null则不回调错误信息。
    private void getDeviceInfo() {
        ...
        initStateListener();
        getDeviceState(null);
    }
    //每次执行打印的时候,设置回调后将返回的错误信息提示出来。
    private void startPrint() {
        getDeviceState(msg -> {
            getActivity().runOnUiThread(() -> {
                if (!msg.equals("打印机就绪")) {
                    showShort(msg);
                    return;
                }
                ...
            });
        });
    }
    
  • 5.打印机打印方法是子线程执行HPRTPrinterHelper.INSTANCE.printBitmap。同样使用Handler将打印结果回传到主线程更新UI
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case PRINT_RESULT:
                    boolean result = (boolean) msg.obj;
                    showShort(result ? "打印成功!" : "打印失败!");
                    printStep2Holder.setPrintBtnEnable(true);
                    break;
            }
        }
    };
    
    private void startPrint() {
        getDeviceState(msg -> {
            getActivity().runOnUiThread(() -> {
                ...
                if (pdfFile != null) {
                    printStep2Holder.setPrintBtnEnable(false);
                    mHandler.post(() -> {
                        Bitmap printBitmap = HPRTPrinterHelper.INSTANCE.pdfToPrintImage(pdfFile, 0);
                        //type ->0:二值, 1:文档, 2:图片, 无参数做二值处理
                        HPRTPrinterHelper.INSTANCE.preparePrint();
                        Boolean result = HPRTPrinterHelper.INSTANCE.printBitmap(printBitmap, 1);
                        Message message = Message.obtain();
                        message.what = PRINT_RESULT;
                        message.obj = result;
                        mHandler.sendMessage(message);
                    });
                } else {
                    showShort("请先下载PDF文件!");
                }
            });
        });
    }