1. 程式人生 > >[Widget]Android小票列印,藍芽列印、固定IP列印、黑白圖片列印

[Widget]Android小票列印,藍芽列印、固定IP列印、黑白圖片列印

Printer

ICON

標準ES-POS命令列印,固定IP或藍芽列印,支援黑白圖片列印

預覽

Screenshots
列印樣例

專案

要求

  • minSdkVersion 5
  • <uses-permission android:name="android.permission.INTERNET" />
  • <uses-permission android:name="android.permission.BLUETOOTH" />

引用

dependencies {
    ⋯
    compile 'am.util:printer:2.0.0'
    ⋯
}

詳情

  • 實現PrintDataMaker介面來實現列印任務
  • 繼承PrinterWriter來實現更多紙張型別的列印
  • PrinterUtils包含了眾多列印指令

使用

1.新增藍芽許可權<uses-permission android:name="android.permission.BLUETOOTH" />或者網路請求許可權<uses-permission android:name="android.permission.INTERNET" />

2.實現PrintDataMaker介面,完成具體列印任務:

public class TestPrintDataMaker implements PrintDataMaker
{
private Context context; private String qr; private int width; private int height; public TestPrintDataMaker(Context context, String qr, int width, int height) { this.context = context; this.qr = qr; this.width = width; this.height = height; } @Override
public List<byte[]> getPrintData(int type) { ArrayList<byte[]> data = new ArrayList<>(); try { PrinterWriter printer; printer = type == PrinterWriter58mm.TYPE_58 ? new PrinterWriter58mm(height, width) : new PrinterWriter80mm(height, width); printer.setAlignCenter(); data.add(printer.getDataAndReset()); ArrayList<byte[]> image1 = printer.getImageByte(context.getResources(), R.drawable.ic_printer_logo); data.addAll(image1); printer.setAlignLeft(); printer.printLine(); printer.printLineFeed(); printer.printLineFeed(); printer.setAlignCenter(); printer.setEmphasizedOn(); printer.setFontSize(1); printer.print("我的餐廳"); printer.printLineFeed(); printer.setFontSize(0); printer.setEmphasizedOff(); printer.printLineFeed(); printer.print("最時尚的明星餐廳"); printer.printLineFeed(); printer.print("客服電話:400-8008800"); printer.printLineFeed(); printer.setAlignLeft(); printer.printLineFeed(); printer.print("訂單號:88888888888888888"); printer.printLineFeed(); printer.print("預計送達:" + new SimpleDateFormat("yyyy/MM/dd HH:mm", Locale.getDefault()) .format(new Date(System.currentTimeMillis()))); printer.printLineFeed(); printer.setEmphasizedOn(); printer.print("#8(已付款)"); printer.printLineFeed(); printer.print("××區××路×××大廈××樓×××室"); printer.printLineFeed(); printer.setEmphasizedOff(); printer.print("13843211234"); printer.print("(張某某)"); printer.printLineFeed(); printer.print("備註:多加點辣椒,多加點香菜,多加點酸蘿蔔,多送點一次性手套"); printer.printLineFeed(); printer.printLine(); printer.printLineFeed(); printer.printInOneLine("星級美食(豪華套餐)×1", "¥88.88", 0); printer.printLineFeed(); printer.printInOneLine("星級美食(限量套餐)×1", "¥888.88", 0); printer.printLineFeed(); printer.printInOneLine("餐具×1", "¥0.00", 0); printer.printLineFeed(); printer.printInOneLine("配送費", "免費", 0); printer.printLineFeed(); printer.printLine(); printer.printLineFeed(); printer.setAlignRight(); printer.print("合計:977.76"); printer.printLineFeed(); printer.printLineFeed(); printer.setAlignCenter(); data.add(printer.getDataAndReset()); String bitmapPath = FileUtils.getExternalFilesDir(context, "Temp") + "tmp_qr.jpg"; if (QRCodeUtil.createQRImage(qr, 380, 380, null, bitmapPath)) { ArrayList<byte[]> image2 = printer.getImageByte(bitmapPath); data.addAll(image2); } else { ArrayList<byte[]> image2 = printer .getImageByte(context.getResources(), R.drawable.ic_printer_qr); data.addAll(image2); } printer.printLineFeed(); printer.print("掃一掃,檢視詳情"); printer.printLineFeed(); printer.printLineFeed(); printer.printLineFeed(); printer.printLineFeed(); printer.printLineFeed(); printer.feedPaperCutPartial(); data.add(printer.getDataAndClose()); return data; } catch (Exception e) { return new ArrayList<>(); } } }

3.建立列印執行者:

PrintExecutor executor = new PrintExecutor(String ip, int port, int type);
PrintExecutor executor = new PrintExecutor(BluetoothDevice device, int type);

4.設定執行者狀態監聽:

executor.setOnStateChangedListener(new PrintSocketHolder.OnStateChangedListener() {
    @Override
    public void onStateChanged(int state) {
        switch (state) {
            case PrintSocketHolder.STATE_0:
                //生成列印頁面資料...
                break;
            case PrintSocketHolder.STATE_1:
                //生成資料成功,開始建立Socket連線...
                break;
            case PrintSocketHolder.STATE_2:
                //建立Socket成功,開始獲取輸出流...
                break;
            case PrintSocketHolder.STATE_3:
                //獲取輸出流成功,開始寫入列印頁面資料...
                break;
            case PrintSocketHolder.STATE_4:
                //寫入列印頁面資料成功,正在完成列印...
                break;
        }
    }
});

4.設定執行者回調監聽:

executor.setOnPrintResultListener(new PrintExecutor.OnPrintResultListener() {
    @Override
    public void onResult(int errorCode) {
        switch (errorCode) {
            case PrintSocketHolder.ERROR_0:
                //列印成功完成!
                break;
            case PrintSocketHolder.ERROR_1:
                //生成列印頁面資料失敗!
                break;
            case PrintSocketHolder.ERROR_2:
                //建立Socket失敗!
                break;
            case PrintSocketHolder.ERROR_3:
                //獲取輸出流失敗!
                break;
            case PrintSocketHolder.ERROR_4:
                //寫入列印頁面資料失敗!
                break;
            case PrintSocketHolder.ERROR_5:
                //必要的引數不能為空!
                break;
            case PrintSocketHolder.ERROR_6:
                //關閉Socket出錯
                break;
            case PrintSocketHolder.ERROR_100:
                //列印失敗
                break;
        }
    }
});

5.執行列印:

int result = executor.doPrinterRequest(PrintDataMaker maker);//同步
executor.doPrinterRequestAsync(PrintDataMaker maker);//非同步

如果你要實現自己的印表機PrinterWriter,那麼你需要繼承

public class PrinterWriter80mm extends PrinterWriter {

    public static final int TYPE_80 = 80;// 紙寬80mm
    public int width = 500;

    public PrinterWriter80mm() throws IOException {
    }

    public PrinterWriter80mm(int parting) throws IOException {
        super(parting);
    }

    public PrinterWriter80mm(int parting, int width) throws IOException {
        super(parting);
        this.width = width;
    }

    @Override
    protected int getLineWidth() {
        //一行能夠放下多少個“-”
        return 24;
    }

    @Override
    protected int getLineStringWidth(int textSize) {
        //根據字型的大小,一行可以放下多少個英文字元
        switch (textSize) {
            default:
            case 0:
                return 47;
            case 1:
                return 23;
        }
    }

    @Override
    protected int getDrawableMaxWidth() {
        //圖片能夠全部列印在紙上的最大寬度
        return width;
    }
}

注意

  • 列印圖片出現亂碼或者打印不出,大部分原因是印表機快取較小導致,可調小PrinterWriter80mm的parting引數,設定其圖片高度分割值(0~255),調小了還不行的話,縮小圖片尺寸或者調整輸出流的寫入方式。
  • 僅提供建立藍芽連線列印,不包括藍芽搜尋及配對功能
  • 不包含二維碼生成功能

歷史