[Widget]Android小票列印,藍芽列印、固定IP列印、黑白圖片列印
阿新 • • 發佈:2019-02-12
Printer
標準ES-POS命令列印,固定IP或藍芽列印,支援黑白圖片列印
預覽
專案
要求
- 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),調小了還不行的話,縮小圖片尺寸或者調整輸出流的寫入方式。
- 僅提供建立藍芽連線列印,不包括藍芽搜尋及配對功能
- 不包含二維碼生成功能