package com.example.sunmiprintertesting.utils; import static com.example.sunmiprintertesting.BaseApp.KEY_TECHNIQUE_1; import android.content.Context; import android.graphics.Bitmap; import android.os.RemoteException; import android.widget.Toast; import com.orhanobut.hawk.Hawk; import com.sunmi.peripheral.printer.ExceptionConst; import com.sunmi.peripheral.printer.InnerLcdCallback; import com.sunmi.peripheral.printer.InnerPrinterCallback; import com.sunmi.peripheral.printer.InnerPrinterException; import com.sunmi.peripheral.printer.InnerPrinterManager; import com.sunmi.peripheral.printer.InnerResultCallback; import com.sunmi.peripheral.printer.SunmiPrinterService; import com.sunmi.peripheral.printer.WoyouConsts; import java.util.ArrayList; import java.util.List; /** * <pre> * This class is used to demonstrate various printing effects * Developers need to repackage themselves, for details please refer to * http://sunmi-ota.oss-cn-hangzhou.aliyuncs.com/DOC/resource/re_cn/Sunmiprinter%E5%BC%80%E5%8F%91%E8%80%85%E6%96%87%E6%A1%A31.1.191128.pdf * </pre> * * @author kaltin * @since create at 2020-02-14 */ public class SunmiPrintHelper { public static int NoSunmiPrinter = 0x00000000; public static int CheckSunmiPrinter = 0x00000001; public static int FoundSunmiPrinter = 0x00000002; public static int LostSunmiPrinter = 0x00000003; private Context context; private List<String> list = new ArrayList<>(); private static String KEY_DEBUG = KEY_TECHNIQUE_1; /** * sunmiPrinter means checking the printer connection status */ public int sunmiPrinter = CheckSunmiPrinter; /** * SunmiPrinterService for API */ private SunmiPrinterService sunmiPrinterService; private static SunmiPrintHelper helper = new SunmiPrintHelper(); private SunmiPrintHelper() { } public static SunmiPrintHelper getInstance() { return helper; } private InnerPrinterCallback innerPrinterCallback = new InnerPrinterCallback() { @Override protected void onConnected(SunmiPrinterService service) { sunmiPrinterService = service; checkSunmiPrinterService(service); list = Hawk.get(KEY_DEBUG, new ArrayList<>()); String mess = "\nSunmiPrinterService: " + "onConnected() " + service.toString() + "\n"; list.add(mess); Hawk.put(KEY_DEBUG, list); } @Override protected void onDisconnected() { sunmiPrinterService = null; sunmiPrinter = LostSunmiPrinter; list = Hawk.get(KEY_DEBUG, new ArrayList<>()); String mess = "\nSunmiPrinterService: " + "onDisconnected() \n"; list.add(mess); Hawk.put(KEY_DEBUG, list); } }; /** * init sunmi print service */ public void initSunmiPrinterService(Context context) { this.context = context; try { boolean ret = InnerPrinterManager.getInstance().bindService(context, innerPrinterCallback); if (!ret) { sunmiPrinter = NoSunmiPrinter; } list = Hawk.get(KEY_DEBUG, new ArrayList<>()); String mess = "\nINNER PRINTER BindService: " + ret + "\n"; list.add(mess); Hawk.put(KEY_DEBUG, list); } catch (InnerPrinterException e) { e.printStackTrace(); String mess = "\nINNER PRINTER: " + "Catch Block!!!\n"; list.add(mess); Toast.makeText(context, mess, Toast.LENGTH_SHORT).show(); Hawk.put(KEY_DEBUG, list); } } /** * Initialize the printer * All style settings will be restored to default */ public void initPrinter() { list = Hawk.get(KEY_DEBUG, new ArrayList<>()); if (sunmiPrinterService == null) { //TODO Service disconnection processing String mess = "\nPRINTER STYLE Service: " + "NULL\n"; list.add(mess); Hawk.put(KEY_DEBUG, list); return; } try { sunmiPrinterService.printerInit(null); String mess = "\nPRINTER STYLE Service: " + "NOT NULL\n"; list.add(mess); Hawk.put(KEY_DEBUG, list); } catch (RemoteException e) { handleRemoteException(e); Toast.makeText(context, "PRINTER STYLE : Catch Block", Toast.LENGTH_SHORT).show(); } } /** * deInit sunmi print service */ public void deInitSunmiPrinterService(Context context) { try { if (sunmiPrinterService != null) { InnerPrinterManager.getInstance().unBindService(context, innerPrinterCallback); sunmiPrinterService = null; sunmiPrinter = LostSunmiPrinter; } } catch (InnerPrinterException e) { e.printStackTrace(); } } /** * Sample print receipt */ public void printExample(Context context) { String message; list = Hawk.get(KEY_DEBUG, new ArrayList<>()); if (sunmiPrinterService == null) { message = "\n" + KEY_DEBUG + " Example Service: " + "NULL"; list.add(list.size() - 1, message); Hawk.put(KEY_DEBUG, list); return; } message = "\n" + KEY_DEBUG + " Example Service: " + sunmiPrinterService; if (list.get(list.size() - 1).contains("Techni")) list.remove(list.size() - 1); list.add(message); Hawk.put(KEY_DEBUG, list); try { sunmiPrinterService.printerInit(null); sunmiPrinterService.setAlignment(1, null); sunmiPrinterService.printText("\n--------------------------------\n", null); sunmiPrinterService.printTextWithFont(KEY_DEBUG + "!!! \n", null, 28, null); sunmiPrinterService.setFontSize(20, null); sunmiPrinterService.printText("--------------------------------\n", null); for (String item : list) { sunmiPrinterService.printText(item + "\n", null); } sunmiPrinterService.printText("--------------------------------\n", null); } catch (RemoteException e) { e.printStackTrace(); } } /** * Check the printer connection, * like some devices do not have a printer but need to be connected to the cash drawer through a print service */ private void checkSunmiPrinterService(SunmiPrinterService service) { boolean ret = false; try { ret = InnerPrinterManager.getInstance().hasPrinter(service); } catch (InnerPrinterException e) { e.printStackTrace(); } sunmiPrinter = ret ? FoundSunmiPrinter : NoSunmiPrinter; } /** * Some conditions can cause interface calls to fail * For example: the version is too low、device does not support * You can see {@link ExceptionConst} * So you have to handle these exceptions */ private void handleRemoteException(RemoteException e) { //TODO process when get one exception } /** * send esc cmd */ public void sendRawData(byte[] data) { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { sunmiPrinterService.sendRAWData(data, null); } catch (RemoteException e) { handleRemoteException(e); } } /** * Printer cuts paper and throws exception on machines without a cutter */ public void cutpaper() { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { sunmiPrinterService.cutPaper(null); } catch (RemoteException e) { handleRemoteException(e); } } /** * paper feed three lines * Not disabled when line spacing is set to 0 */ public void print3Line() { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { sunmiPrinterService.lineWrap(3, null); } catch (RemoteException e) { handleRemoteException(e); } } /** * Get printer serial number */ public String getPrinterSerialNo() { if (sunmiPrinterService == null) { //TODO Service disconnection processing return ""; } try { return sunmiPrinterService.getPrinterSerialNo(); } catch (RemoteException e) { handleRemoteException(e); return ""; } } /** * Get device model */ public String getDeviceModel() { if (sunmiPrinterService == null) { //TODO Service disconnection processing return ""; } try { return sunmiPrinterService.getPrinterModal(); } catch (RemoteException e) { handleRemoteException(e); return ""; } } /** * Get firmware version */ public String getPrinterVersion() { if (sunmiPrinterService == null) { //TODO Service disconnection processing return ""; } try { return sunmiPrinterService.getPrinterVersion(); } catch (RemoteException e) { handleRemoteException(e); return ""; } } /** * Get paper specifications */ public String getPrinterPaper() { if (sunmiPrinterService == null) { //TODO Service disconnection processing return ""; } try { return sunmiPrinterService.getPrinterPaper() == 1 ? "58mm" : "80mm"; } catch (RemoteException e) { handleRemoteException(e); return ""; } } /** * Get paper specifications */ public void getPrinterHead(InnerResultCallback callbcak) { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { sunmiPrinterService.getPrinterFactory(callbcak); } catch (RemoteException e) { handleRemoteException(e); } } /** * Get printing distance since boot * Get printing distance through interface callback since 1.0.8(printerlibrary) */ public void getPrinterDistance(InnerResultCallback callback) { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { sunmiPrinterService.getPrintedLength(callback); } catch (RemoteException e) { handleRemoteException(e); } } /** * Set printer alignment */ public void setAlign(int align) { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { sunmiPrinterService.setAlignment(align, null); } catch (RemoteException e) { handleRemoteException(e); } } /** * Due to the distance between the paper hatch and the print head, * the paper needs to be fed out automatically * But if the Api does not support it, it will be replaced by printing three lines */ public void feedPaper() { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { sunmiPrinterService.autoOutPaper(null); } catch (RemoteException e) { print3Line(); } } /** * print text * setPrinterStyle:Api require V4.2.22 or later, So use esc cmd instead when not supported * More settings reference documentation {@link WoyouConsts} * printTextWithFont: * Custom fonts require V4.14.0 or later! * You can put the custom font in the 'assets' directory and Specify the font name parameters * in the Api. */ public void printText(String content, float size, boolean isBold, boolean isUnderLine, String typeface) { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { try { sunmiPrinterService.setPrinterStyle(WoyouConsts.ENABLE_BOLD, isBold ? WoyouConsts.ENABLE : WoyouConsts.DISABLE); } catch (RemoteException e) { if (isBold) { sunmiPrinterService.sendRAWData(ESCUtil.boldOn(), null); } else { sunmiPrinterService.sendRAWData(ESCUtil.boldOff(), null); } } try { sunmiPrinterService.setPrinterStyle(WoyouConsts.ENABLE_UNDERLINE, isUnderLine ? WoyouConsts.ENABLE : WoyouConsts.DISABLE); } catch (RemoteException e) { if (isUnderLine) { sunmiPrinterService.sendRAWData(ESCUtil.underlineWithOneDotWidthOn(), null); } else { sunmiPrinterService.sendRAWData(ESCUtil.underlineOff(), null); } } sunmiPrinterService.printTextWithFont(content, typeface, size, null); } catch (RemoteException e) { e.printStackTrace(); } } /** * print Bar Code */ public void printBarCode(String data, int symbology, int height, int width, int textposition) { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { sunmiPrinterService.printBarCode(data, symbology, height, width, textposition, null); } catch (RemoteException e) { e.printStackTrace(); } } /** * print Qr Code */ public void printQr(String data, int modulesize, int errorlevel) { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { sunmiPrinterService.printQRCode(data, modulesize, errorlevel, null); } catch (RemoteException e) { e.printStackTrace(); } } /** * Print a row of a table */ public void printTable(String[] txts, int[] width, int[] align) { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { sunmiPrinterService.printColumnsString(txts, width, align, null); } catch (RemoteException e) { e.printStackTrace(); } } /** * Print pictures and text in the specified orde * After the picture is printed, * the line feed output needs to be called, * otherwise it will be saved in the cache * In this example, the image will be printed because the print text content is added */ public void printBitmap(Bitmap bitmap, int orientation) { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { if (orientation == 0) { sunmiPrinterService.printBitmap(bitmap, null); sunmiPrinterService.printText("横向排列\n", null); sunmiPrinterService.printBitmap(bitmap, null); sunmiPrinterService.printText("横向排列\n", null); } else { sunmiPrinterService.printBitmap(bitmap, null); sunmiPrinterService.printText("\n纵向排列\n", null); sunmiPrinterService.printBitmap(bitmap, null); sunmiPrinterService.printText("\n纵向排列\n", null); } } catch (RemoteException e) { e.printStackTrace(); } } /** * Gets whether the current printer is in black mark mode */ public boolean isBlackLabelMode() { if (sunmiPrinterService == null) { //TODO Service disconnection processing return false; } try { return sunmiPrinterService.getPrinterMode() == 1; } catch (RemoteException e) { return false; } } /** * Gets whether the current printer is in label-printing mode */ public boolean isLabelMode() { if (sunmiPrinterService == null) { //TODO Service disconnection processing return false; } try { return sunmiPrinterService.getPrinterMode() == 2; } catch (RemoteException e) { return false; } } /** * Transaction printing: * enter->print->exit(get result) or * enter->first print->commit(get result)->twice print->commit(get result)->exit(don't care * result) */ public void printTrans(Context context, InnerResultCallback callbcak) { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { sunmiPrinterService.enterPrinterBuffer(true); printExample(context); sunmiPrinterService.exitPrinterBufferWithCallback(true, callbcak); } catch (RemoteException e) { e.printStackTrace(); } } /** * Open cash box * This method can be used on Sunmi devices with a cash drawer interface * If there is no cash box (such as V1、P1) or the call fails, an exception will be thrown * <p> * Reference to https://docs.sunmi.com/general-function-modules/external-device-debug/cash-box-driver/} */ public void openCashBox() { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { sunmiPrinterService.openDrawer(null); } catch (RemoteException e) { handleRemoteException(e); } } /** * LCD screen control * * @param flag 1 —— Initialization * 2 —— Light up screen * 3 —— Extinguish screen * 4 —— Clear screen contents */ public void controlLcd(int flag) { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { sunmiPrinterService.sendLCDCommand(flag); } catch (RemoteException e) { handleRemoteException(e); } } /** * Display text SUNMI,font size is 16 and format is fill * sendLCDFillString(txt, size, fill, callback) * Since the screen pixel height is 40, the font should not exceed 40 */ public void sendTextToLcd() { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { sunmiPrinterService.sendLCDFillString("SUNMI", 16, true, new InnerLcdCallback() { @Override public void onRunResult(boolean show) throws RemoteException { //TODO handle result } }); } catch (RemoteException e) { e.printStackTrace(); } } /** * Display two lines and one empty line in the middle */ public void sendTextsToLcd() { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { String[] texts = {"SUNMI", null, "SUNMI"}; int[] align = {2, 1, 2}; sunmiPrinterService.sendLCDMultiString(texts, align, new InnerLcdCallback() { @Override public void onRunResult(boolean show) throws RemoteException { //TODO handle result } }); } catch (RemoteException e) { e.printStackTrace(); } } /** * Display one 128x40 pixels and opaque picture */ public void sendPicToLcd(Bitmap pic) { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { sunmiPrinterService.sendLCDBitmap(pic, new InnerLcdCallback() { @Override public void onRunResult(boolean show) throws RemoteException { //TODO handle result } }); } catch (RemoteException e) { e.printStackTrace(); } } /** * Used to report the real-time query status of the printer, which can be used before each * printing */ public void showPrinterStatus(Context context) { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } String result = "Interface is too low to implement interface"; try { int res = sunmiPrinterService.updatePrinterState(); switch (res) { case 1: result = "printer is running"; break; case 2: result = "printer found but still initializing"; break; case 3: result = "printer hardware interface is abnormal and needs to be reprinted"; break; case 4: result = "printer is out of paper"; break; case 5: result = "printer is overheating"; break; case 6: result = "printer's cover is not closed"; break; case 7: result = "printer's cutter is abnormal"; break; case 8: result = "printer's cutter is normal"; break; case 9: result = "not found black mark paper"; break; case 505: result = "printer does not exist"; break; default: break; } } catch (RemoteException e) { e.printStackTrace(); } Toast.makeText(context, result, Toast.LENGTH_LONG).show(); } /** * Demo printing a label * After printing one label, in order to facilitate the user to tear the paper, call * labelOutput to push the label paper out of the paper hatch * 演示打印一张标签 * 打印单张标签后为了方便用户撕纸可调用labelOutput,将标签纸推出纸舱口 */ public void printOneLabel() { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { sunmiPrinterService.labelLocate(); printLabelContent(); sunmiPrinterService.labelOutput(); } catch (RemoteException e) { e.printStackTrace(); } } /** * Demo printing multi label * <p> * After printing multiple labels, choose whether to push the label paper to the paper hatch according to the needs * 演示打印多张标签 * 打印多张标签后根据需求选择是否推出标签纸到纸舱口 */ public void printMultiLabel(int num) { if (sunmiPrinterService == null) { //TODO Service disconnection processing return; } try { for (int i = 0; i < num; i++) { sunmiPrinterService.labelLocate(); printLabelContent(); } sunmiPrinterService.labelOutput(); } catch (RemoteException e) { e.printStackTrace(); } } /** * Custom label ticket content * In the example, not all labels can be applied. In actual use, please pay attention to adapting the size of the label. You can adjust the font size and content position. * 自定义的标签小票内容 * 例子中并不能适用所有标签纸,实际使用时注意要自适配标签纸大小,可通过调节字体大小,内容位置等方式 */ private void printLabelContent() throws RemoteException { sunmiPrinterService.setPrinterStyle(WoyouConsts.ENABLE_BOLD, WoyouConsts.ENABLE); sunmiPrinterService.lineWrap(1, null); sunmiPrinterService.setAlignment(0, null); sunmiPrinterService.printText("商品 豆浆\n", null); sunmiPrinterService.printText("到期时间 12-13 14时\n", null); sunmiPrinterService.printBarCode("{C1234567890123456", 8, 90, 2, 2, null); sunmiPrinterService.lineWrap(1, null); } }