├── app ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ └── styles.xml │ │ │ ├── drawable-mdpi │ │ │ │ └── logo.png │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── drawable-v24 │ │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── layout │ │ │ │ └── activity_main.xml │ │ │ └── drawable │ │ │ │ └── ic_launcher_background.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── dantsu │ │ │ │ └── thermalprinter │ │ │ │ ├── async │ │ │ │ ├── AsyncTcpEscPosPrint.java │ │ │ │ ├── AsyncUsbEscPosPrint.java │ │ │ │ ├── AsyncEscPosPrinter.java │ │ │ │ ├── AsyncBluetoothEscPosPrint.java │ │ │ │ └── AsyncEscPosPrint.java │ │ │ │ └── MainActivity.java │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── dantsu │ │ │ └── thermalprinter │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── dantsu │ │ └── thermalprinter │ │ └── ExampleInstrumentedTest.java ├── proguard-rules.pro └── build.gradle ├── escposprinter ├── consumer-rules.pro ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ └── values │ │ │ │ └── strings.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── dantsu │ │ │ └── escposprinter │ │ │ ├── exceptions │ │ │ ├── EscPosParserException.java │ │ │ ├── EscPosBarcodeException.java │ │ │ ├── EscPosEncodingException.java │ │ │ └── EscPosConnectionException.java │ │ │ ├── textparser │ │ │ ├── IPrinterTextParserElement.java │ │ │ ├── PrinterTextParserQRCode.java │ │ │ ├── PrinterTextParserTag.java │ │ │ ├── PrinterTextParserString.java │ │ │ ├── PrinterTextParserLine.java │ │ │ ├── PrinterTextParserBarcode.java │ │ │ ├── PrinterTextParserImg.java │ │ │ ├── PrinterTextParser.java │ │ │ └── PrinterTextParserColumn.java │ │ │ ├── barcode │ │ │ ├── BarcodeEAN8.java │ │ │ ├── BarcodeUPCA.java │ │ │ ├── BarcodeEAN13.java │ │ │ ├── Barcode128.java │ │ │ ├── Barcode39.java │ │ │ ├── BarcodeUPCE.java │ │ │ ├── BarcodeNumber.java │ │ │ └── Barcode.java │ │ │ ├── EscPosCharsetEncoding.java │ │ │ ├── connection │ │ │ ├── usb │ │ │ │ ├── UsbConnections.java │ │ │ │ ├── UsbDeviceHelper.java │ │ │ │ ├── UsbPrintersConnections.java │ │ │ │ ├── UsbConnection.java │ │ │ │ └── UsbOutputStream.java │ │ │ ├── bluetooth │ │ │ │ ├── BluetoothConnections.java │ │ │ │ ├── BluetoothPrintersConnections.java │ │ │ │ └── BluetoothConnection.java │ │ │ ├── DeviceConnection.java │ │ │ └── tcp │ │ │ │ └── TcpConnection.java │ │ │ ├── EscPosPrinterSize.java │ │ │ └── EscPosPrinter.java │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── dantsu │ │ │ └── escposprinter │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── dantsu │ │ └── escposprinter │ │ └── ExampleInstrumentedTest.java ├── proguard-rules.pro ├── LICENSE └── build.gradle ├── .github └── FUNDING.yml ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── LICENSE ├── gradle.properties ├── gradlew.bat ├── gradlew └── README.md /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /escposprinter/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: DantSu 2 | -------------------------------------------------------------------------------- /escposprinter/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':escposprinter' 2 | rootProject.name='ThermalPrinter' 3 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | ThermalPrinter 3 | 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DantSu/ESCPOS-ThermalPrinter-Android/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | .cxx 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DantSu/ESCPOS-ThermalPrinter-Android/HEAD/app/src/main/res/drawable-mdpi/logo.png -------------------------------------------------------------------------------- /escposprinter/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | ThermalPrinter ESC POS Bluetooth 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DantSu/ESCPOS-ThermalPrinter-Android/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DantSu/ESCPOS-ThermalPrinter-Android/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DantSu/ESCPOS-ThermalPrinter-Android/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DantSu/ESCPOS-ThermalPrinter-Android/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DantSu/ESCPOS-ThermalPrinter-Android/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /escposprinter/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DantSu/ESCPOS-ThermalPrinter-Android/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DantSu/ESCPOS-ThermalPrinter-Android/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DantSu/ESCPOS-ThermalPrinter-Android/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DantSu/ESCPOS-ThermalPrinter-Android/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DantSu/ESCPOS-ThermalPrinter-Android/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed May 03 12:31:57 CEST 2023 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/exceptions/EscPosParserException.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.exceptions; 2 | 3 | public class EscPosParserException extends Exception { 4 | public EscPosParserException(String errorMessage) { 5 | super(errorMessage); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/exceptions/EscPosBarcodeException.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.exceptions; 2 | 3 | public class EscPosBarcodeException extends Exception { 4 | public EscPosBarcodeException(String errorMessage) { 5 | super(errorMessage); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/exceptions/EscPosEncodingException.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.exceptions; 2 | 3 | public class EscPosEncodingException extends Exception { 4 | public EscPosEncodingException(String errorMessage) { 5 | super(errorMessage); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/exceptions/EscPosConnectionException.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.exceptions; 2 | 3 | public class EscPosConnectionException extends Exception { 4 | public EscPosConnectionException(String errorMessage) { 5 | super(errorMessage); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/dantsu/thermalprinter/async/AsyncTcpEscPosPrint.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.thermalprinter.async; 2 | 3 | import android.content.Context; 4 | 5 | public class AsyncTcpEscPosPrint extends AsyncEscPosPrint { 6 | public AsyncTcpEscPosPrint(Context context) { 7 | super(context); 8 | } 9 | 10 | public AsyncTcpEscPosPrint(Context context, OnPrintFinished onPrintFinished) { 11 | super(context, onPrintFinished); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/dantsu/thermalprinter/async/AsyncUsbEscPosPrint.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.thermalprinter.async; 2 | 3 | import android.content.Context; 4 | 5 | public class AsyncUsbEscPosPrint extends AsyncEscPosPrint { 6 | public AsyncUsbEscPosPrint(Context context) { 7 | super(context); 8 | } 9 | 10 | public AsyncUsbEscPosPrint(Context context, OnPrintFinished onPrintFinished) { 11 | super(context, onPrintFinished); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/test/java/com/dantsu/thermalprinter/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.thermalprinter; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /escposprinter/src/test/java/com/dantsu/escposprinter/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/textparser/IPrinterTextParserElement.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.textparser; 2 | 3 | import com.dantsu.escposprinter.EscPosPrinterCommands; 4 | import com.dantsu.escposprinter.exceptions.EscPosConnectionException; 5 | import com.dantsu.escposprinter.exceptions.EscPosEncodingException; 6 | 7 | public interface IPrinterTextParserElement { 8 | int length() throws EscPosEncodingException; 9 | IPrinterTextParserElement print(EscPosPrinterCommands printerSocket) throws EscPosEncodingException, EscPosConnectionException; 10 | } 11 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/barcode/BarcodeEAN8.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.barcode; 2 | 3 | import com.dantsu.escposprinter.EscPosPrinterCommands; 4 | import com.dantsu.escposprinter.EscPosPrinterSize; 5 | import com.dantsu.escposprinter.exceptions.EscPosBarcodeException; 6 | 7 | public class BarcodeEAN8 extends BarcodeNumber { 8 | public BarcodeEAN8(EscPosPrinterSize printerSize, String code, float widthMM, float heightMM, int textPosition) throws EscPosBarcodeException { 9 | super(printerSize, EscPosPrinterCommands.BARCODE_TYPE_EAN8, code, widthMM, heightMM, textPosition); 10 | } 11 | 12 | @Override 13 | public int getCodeLength() { 14 | return 8; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/barcode/BarcodeUPCA.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.barcode; 2 | 3 | import com.dantsu.escposprinter.EscPosPrinterCommands; 4 | import com.dantsu.escposprinter.EscPosPrinterSize; 5 | import com.dantsu.escposprinter.exceptions.EscPosBarcodeException; 6 | 7 | public class BarcodeUPCA extends BarcodeNumber { 8 | 9 | public BarcodeUPCA(EscPosPrinterSize printerSize, String code, float widthMM, float heightMM, int textPosition) throws EscPosBarcodeException { 10 | super(printerSize, EscPosPrinterCommands.BARCODE_TYPE_UPCA, code, widthMM, heightMM, textPosition); 11 | } 12 | 13 | @Override 14 | public int getCodeLength() { 15 | return 12; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/barcode/BarcodeEAN13.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.barcode; 2 | 3 | import com.dantsu.escposprinter.EscPosPrinterCommands; 4 | import com.dantsu.escposprinter.EscPosPrinterSize; 5 | import com.dantsu.escposprinter.exceptions.EscPosBarcodeException; 6 | 7 | public class BarcodeEAN13 extends BarcodeNumber { 8 | 9 | public BarcodeEAN13(EscPosPrinterSize printerSize, String code, float widthMM, float heightMM, int textPosition) throws EscPosBarcodeException { 10 | super(printerSize, EscPosPrinterCommands.BARCODE_TYPE_EAN13, code, widthMM, heightMM, textPosition); 11 | } 12 | 13 | @Override 14 | public int getCodeLength() { 15 | return 13; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /escposprinter/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/barcode/Barcode128.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.barcode; 2 | 3 | import com.dantsu.escposprinter.EscPosPrinterSize; 4 | import com.dantsu.escposprinter.EscPosPrinterCommands; 5 | import com.dantsu.escposprinter.exceptions.EscPosBarcodeException; 6 | 7 | public class Barcode128 extends Barcode { 8 | public Barcode128(EscPosPrinterSize printerSize, String code, float widthMM, float heightMM, int textPosition) throws EscPosBarcodeException { 9 | super(printerSize, EscPosPrinterCommands.BARCODE_TYPE_128, code, widthMM, heightMM, textPosition); 10 | } 11 | 12 | @Override 13 | public int getCodeLength() { 14 | return this.code.length(); 15 | } 16 | 17 | @Override 18 | public int getColsCount() { 19 | return (this.getCodeLength() + 5) * 11; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/barcode/Barcode39.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.barcode; 2 | 3 | import com.dantsu.escposprinter.EscPosPrinterSize; 4 | import com.dantsu.escposprinter.EscPosPrinterCommands; 5 | import com.dantsu.escposprinter.exceptions.EscPosBarcodeException; 6 | 7 | public class Barcode39 extends Barcode { 8 | public Barcode39(EscPosPrinterSize printerSize, String code, float widthMM, float heightMM, int textPosition) throws EscPosBarcodeException { 9 | super(printerSize, EscPosPrinterCommands.BARCODE_TYPE_39, code, widthMM, heightMM, textPosition); 10 | } 11 | 12 | @Override 13 | public int getCodeLength() { 14 | return this.code.length(); 15 | } 16 | 17 | @Override 18 | public int getColsCount() { 19 | return (this.getCodeLength() + 4) * 16; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/EscPosCharsetEncoding.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter; 2 | 3 | public class EscPosCharsetEncoding { 4 | private String charsetName; 5 | private byte[] charsetCommand; 6 | 7 | /** 8 | * Create new instance of EscPosCharsetEncoding. 9 | * 10 | * @param charsetName Name of charset encoding (Ex: windows-1252) 11 | * @param escPosCharsetId Id of charset encoding for your printer (Ex: 16) 12 | */ 13 | public EscPosCharsetEncoding(String charsetName, int escPosCharsetId) { 14 | this.charsetName = charsetName; 15 | this.charsetCommand = new byte[]{0x1B, 0x74, (byte) escPosCharsetId}; 16 | } 17 | 18 | public byte[] getCommand() { 19 | return this.charsetCommand; 20 | } 21 | 22 | public String getName() { 23 | return this.charsetName; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/dantsu/thermalprinter/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.thermalprinter; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android usbDevice. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | 25 | assertEquals("com.dantsu.thermalprinter", appContext.getPackageName()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /escposprinter/src/androidTest/java/com/dantsu/escposprinter/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android usbDevice. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | 25 | assertEquals("com.dantsu.thermalprinter_escpos.test", appContext.getPackageName()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Franck ALARY 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 33 5 | defaultConfig { 6 | applicationId "com.dantsu.thermalprinter" 7 | minSdkVersion 16 8 | targetSdkVersion 33 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 12 | } 13 | compileOptions { 14 | sourceCompatibility JavaVersion.VERSION_1_8 15 | targetCompatibility JavaVersion.VERSION_1_8 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | } 24 | 25 | dependencies { 26 | implementation fileTree(dir: 'libs', include: ['*.jar']) 27 | implementation 'androidx.appcompat:appcompat:1.6.1' 28 | testImplementation 'junit:junit:4.12' 29 | androidTestImplementation 'androidx.test.ext:junit:1.1.5' 30 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' 31 | implementation project(path: ':escposprinter') 32 | } 33 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | 21 | -------------------------------------------------------------------------------- /escposprinter/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Franck ALARY 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/dantsu/thermalprinter/async/AsyncEscPosPrinter.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.thermalprinter.async; 2 | 3 | import com.dantsu.escposprinter.EscPosPrinterSize; 4 | import com.dantsu.escposprinter.connection.DeviceConnection; 5 | 6 | public class AsyncEscPosPrinter extends EscPosPrinterSize { 7 | private DeviceConnection printerConnection; 8 | private String[] textsToPrint = new String[0]; 9 | 10 | public AsyncEscPosPrinter(DeviceConnection printerConnection, int printerDpi, float printerWidthMM, int printerNbrCharactersPerLine) { 11 | super(printerDpi, printerWidthMM, printerNbrCharactersPerLine); 12 | this.printerConnection = printerConnection; 13 | } 14 | 15 | public DeviceConnection getPrinterConnection() { 16 | return this.printerConnection; 17 | } 18 | 19 | public AsyncEscPosPrinter setTextsToPrint(String[] textsToPrint) { 20 | this.textsToPrint = textsToPrint; 21 | return this; 22 | } 23 | 24 | public AsyncEscPosPrinter addTextToPrint(String textToPrint) { 25 | String[] tmp = new String[this.textsToPrint.length + 1]; 26 | System.arraycopy(this.textsToPrint, 0, tmp, 0, this.textsToPrint.length); 27 | tmp[this.textsToPrint.length] = textToPrint; 28 | this.textsToPrint = tmp; 29 | return this; 30 | } 31 | 32 | public String[] getTextsToPrint() { 33 | return this.textsToPrint; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/connection/usb/UsbConnections.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.connection.usb; 2 | 3 | import android.content.Context; 4 | import android.hardware.usb.UsbDevice; 5 | import android.hardware.usb.UsbManager; 6 | 7 | import androidx.annotation.Nullable; 8 | 9 | import java.util.Collection; 10 | 11 | public class UsbConnections { 12 | protected UsbManager usbManager; 13 | 14 | /** 15 | * Create a new instance of UsbConnections 16 | * 17 | * @param context Application context 18 | */ 19 | public UsbConnections(Context context) { 20 | this.usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE); 21 | } 22 | 23 | /** 24 | * Get a list of USB devices available. 25 | * @return Return an array of UsbConnection instance 26 | */ 27 | @Nullable 28 | public UsbConnection[] getList() { 29 | if (this.usbManager == null) { 30 | return null; 31 | } 32 | 33 | Collection devicesList = this.usbManager.getDeviceList().values(); 34 | UsbConnection[] usbDevices = new UsbConnection[devicesList.size()]; 35 | 36 | if (devicesList.size() > 0) { 37 | int i = 0; 38 | for (UsbDevice device : devicesList) { 39 | usbDevices[i++] = new UsbConnection(this.usbManager, device); 40 | } 41 | } 42 | 43 | return usbDevices; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/barcode/BarcodeUPCE.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.barcode; 2 | 3 | import com.dantsu.escposprinter.EscPosPrinterCommands; 4 | import com.dantsu.escposprinter.EscPosPrinterSize; 5 | import com.dantsu.escposprinter.exceptions.EscPosBarcodeException; 6 | 7 | public class BarcodeUPCE extends Barcode { 8 | 9 | public BarcodeUPCE(EscPosPrinterSize printerSize, String code, float widthMM, float heightMM, int textPosition) throws EscPosBarcodeException { 10 | super(printerSize, EscPosPrinterCommands.BARCODE_TYPE_UPCE, code, widthMM, heightMM, textPosition); 11 | this.checkCode(); 12 | } 13 | 14 | public int getCodeLength() { 15 | return 6; 16 | } 17 | 18 | @Override 19 | public int getColsCount() { 20 | return this.getCodeLength() * 7 + 16; 21 | } 22 | 23 | private void checkCode() throws EscPosBarcodeException { 24 | int codeLength = this.getCodeLength(); 25 | 26 | if (this.code.length() < codeLength) { 27 | throw new EscPosBarcodeException("Code is too short for the barcode type."); 28 | } 29 | 30 | try { 31 | this.code = this.code.substring(0, codeLength); 32 | for (int i = 0; i < codeLength; i++) { 33 | Integer.parseInt(this.code.substring(i, i + 1), 10); 34 | } 35 | } catch (NumberFormatException e) { 36 | e.printStackTrace(); 37 | throw new EscPosBarcodeException("Invalid barcode number"); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/connection/bluetooth/BluetoothConnections.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.connection.bluetooth; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.bluetooth.BluetoothAdapter; 5 | import android.bluetooth.BluetoothDevice; 6 | 7 | import androidx.annotation.Nullable; 8 | 9 | import java.util.Set; 10 | 11 | public class BluetoothConnections { 12 | protected BluetoothAdapter bluetoothAdapter; 13 | 14 | /** 15 | * Create a new instance of BluetoothConnections 16 | */ 17 | public BluetoothConnections() { 18 | this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 19 | } 20 | 21 | /** 22 | * Get a list of bluetooth devices available. 23 | * @return Return an array of BluetoothConnection instance 24 | */ 25 | @SuppressLint("MissingPermission") 26 | @Nullable 27 | public BluetoothConnection[] getList() { 28 | if (this.bluetoothAdapter == null) { 29 | return null; 30 | } 31 | 32 | if(!this.bluetoothAdapter.isEnabled()) { 33 | return null; 34 | } 35 | 36 | Set bluetoothDevicesList = this.bluetoothAdapter.getBondedDevices(); 37 | BluetoothConnection[] bluetoothDevices = new BluetoothConnection[bluetoothDevicesList.size()]; 38 | 39 | if (bluetoothDevicesList.size() > 0) { 40 | int i = 0; 41 | for (BluetoothDevice device : bluetoothDevicesList) { 42 | bluetoothDevices[i++] = new BluetoothConnection(device); 43 | } 44 | } 45 | 46 | return bluetoothDevices; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /escposprinter/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.library' 3 | id 'maven-publish' 4 | } 5 | 6 | def libraryVersionCode = 3003000 7 | def libraryVersionName = "3.3.0" 8 | 9 | android { 10 | compileSdkVersion 33 11 | 12 | defaultConfig { 13 | minSdkVersion 16 14 | targetSdkVersion 33 15 | versionCode libraryVersionCode 16 | versionName libraryVersionName 17 | 18 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 19 | consumerProguardFiles 'consumer-rules.pro' 20 | } 21 | 22 | buildTypes { 23 | release { 24 | minifyEnabled false 25 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 26 | } 27 | } 28 | 29 | } 30 | 31 | dependencies { 32 | implementation fileTree(dir: 'libs', include: ['*.jar']) 33 | 34 | implementation 'androidx.appcompat:appcompat:1.6.1' 35 | implementation 'com.google.zxing:core:3.4.0' 36 | testImplementation 'junit:junit:4.13.2' 37 | androidTestImplementation 'androidx.test.ext:junit:1.1.5' 38 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' 39 | } 40 | 41 | 42 | afterEvaluate { 43 | publishing { 44 | publications { 45 | release(MavenPublication) { 46 | groupId = 'com.github.DantSu' 47 | artifactId = 'ESCPOS-ThermalPrinter-Android' 48 | version = libraryVersionName 49 | pom { 50 | name = 'Android library for ESC/POS Thermal Printer' 51 | description = 'Useful library to help Android developers to print with (Bluetooth, TCP, USB) ESC/POS thermal printers.' 52 | } 53 | afterEvaluate { 54 | from components.release 55 | } 56 | } 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /app/src/main/java/com/dantsu/thermalprinter/async/AsyncBluetoothEscPosPrint.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.thermalprinter.async; 2 | 3 | import android.content.Context; 4 | 5 | import com.dantsu.escposprinter.connection.DeviceConnection; 6 | import com.dantsu.escposprinter.connection.bluetooth.BluetoothPrintersConnections; 7 | import com.dantsu.escposprinter.exceptions.EscPosConnectionException; 8 | 9 | public class AsyncBluetoothEscPosPrint extends AsyncEscPosPrint { 10 | public AsyncBluetoothEscPosPrint(Context context) { 11 | super(context); 12 | } 13 | 14 | public AsyncBluetoothEscPosPrint(Context context, OnPrintFinished onPrintFinished) { 15 | super(context, onPrintFinished); 16 | } 17 | 18 | protected PrinterStatus doInBackground(AsyncEscPosPrinter... printersData) { 19 | if (printersData.length == 0) { 20 | return new PrinterStatus(null, AsyncEscPosPrint.FINISH_NO_PRINTER); 21 | } 22 | 23 | AsyncEscPosPrinter printerData = printersData[0]; 24 | DeviceConnection deviceConnection = printerData.getPrinterConnection(); 25 | 26 | this.publishProgress(AsyncEscPosPrint.PROGRESS_CONNECTING); 27 | 28 | if (deviceConnection == null) { 29 | printersData[0] = new AsyncEscPosPrinter( 30 | BluetoothPrintersConnections.selectFirstPaired(), 31 | printerData.getPrinterDpi(), 32 | printerData.getPrinterWidthMM(), 33 | printerData.getPrinterNbrCharactersPerLine() 34 | ); 35 | printersData[0].setTextsToPrint(printerData.getTextsToPrint()); 36 | } else { 37 | try { 38 | deviceConnection.connect(); 39 | } catch (EscPosConnectionException e) { 40 | e.printStackTrace(); 41 | } 42 | } 43 | 44 | return super.doInBackground(printersData); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/connection/usb/UsbDeviceHelper.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.connection.usb; 2 | 3 | import android.hardware.usb.UsbConstants; 4 | import android.hardware.usb.UsbDevice; 5 | import android.hardware.usb.UsbEndpoint; 6 | import android.hardware.usb.UsbInterface; 7 | 8 | import androidx.annotation.Nullable; 9 | 10 | public class UsbDeviceHelper { 11 | /** 12 | * Find the correct USB interface for printing 13 | * 14 | * @param usbDevice USB device 15 | * @return correct USB interface for printing, null if not found 16 | */ 17 | @Nullable 18 | static public UsbInterface findPrinterInterface(UsbDevice usbDevice) { 19 | if (usbDevice == null) { 20 | return null; 21 | } 22 | int interfacesCount = usbDevice.getInterfaceCount(); 23 | for (int i = 0; i < interfacesCount; i++) { 24 | UsbInterface usbInterface = usbDevice.getInterface(i); 25 | if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_PRINTER) { 26 | return usbInterface; 27 | } 28 | } 29 | return null; 30 | } 31 | 32 | /** 33 | * Find the USB endpoint for device input 34 | * 35 | * @param usbInterface USB interface 36 | * @return Input endpoint or null if not found 37 | */ 38 | @Nullable 39 | static public UsbEndpoint findEndpointIn(UsbInterface usbInterface) { 40 | if (usbInterface != null) { 41 | int endpointsCount = usbInterface.getEndpointCount(); 42 | for (int i = 0; i < endpointsCount; i++) { 43 | UsbEndpoint endpoint = usbInterface.getEndpoint(i); 44 | if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK && endpoint.getDirection() == UsbConstants.USB_DIR_OUT) { 45 | return endpoint; 46 | } 47 | } 48 | } 49 | return null; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/barcode/BarcodeNumber.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.barcode; 2 | 3 | import com.dantsu.escposprinter.EscPosPrinterSize; 4 | import com.dantsu.escposprinter.exceptions.EscPosBarcodeException; 5 | 6 | public abstract class BarcodeNumber extends Barcode { 7 | 8 | public BarcodeNumber(EscPosPrinterSize printerSize, int barcodeType, String code, float widthMM, float heightMM, int textPosition) throws EscPosBarcodeException { 9 | super(printerSize, barcodeType, code, widthMM, heightMM, textPosition); 10 | this.checkCode(); 11 | } 12 | 13 | @Override 14 | public int getColsCount() { 15 | return this.getCodeLength() * 7 + 11; 16 | } 17 | 18 | private void checkCode() throws EscPosBarcodeException { 19 | int codeLength = this.getCodeLength() - 1; 20 | 21 | if (this.code.length() < codeLength) { 22 | throw new EscPosBarcodeException("Code is too short for the barcode type."); 23 | } 24 | 25 | try { 26 | 27 | String code = this.code.substring(0, codeLength); 28 | int totalBarcodeKey = 0; 29 | for (int i = 0; i < codeLength; i++) { 30 | int 31 | pos = codeLength - 1 - i, 32 | intCode = Integer.parseInt(code.substring(pos, pos + 1), 10); 33 | if (i % 2 == 0) { 34 | intCode = 3 * intCode; 35 | } 36 | totalBarcodeKey += intCode; 37 | } 38 | 39 | String barcodeKey = String.valueOf(10 - (totalBarcodeKey % 10)); 40 | if (barcodeKey.length() == 2) { 41 | barcodeKey = "0"; 42 | } 43 | this.code = code + barcodeKey; 44 | 45 | } catch (NumberFormatException e) { 46 | e.printStackTrace(); 47 | throw new EscPosBarcodeException("Invalid barcode number"); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/barcode/Barcode.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.barcode; 2 | 3 | import com.dantsu.escposprinter.EscPosPrinterSize; 4 | import com.dantsu.escposprinter.exceptions.EscPosBarcodeException; 5 | 6 | public abstract class Barcode { 7 | 8 | protected int barcodeType; 9 | protected String code; 10 | protected int colWidth; 11 | protected int height; 12 | protected int textPosition; 13 | 14 | Barcode(EscPosPrinterSize printerSize, int barcodeType, String code, float widthMM, float heightMM, int textPosition) throws EscPosBarcodeException { 15 | this.barcodeType = barcodeType; 16 | this.code = code; 17 | this.height = printerSize.mmToPx(heightMM); 18 | this.textPosition = textPosition; 19 | 20 | if(widthMM == 0f) { 21 | widthMM = printerSize.getPrinterWidthMM() * 0.7f; 22 | } 23 | 24 | int 25 | wantedPxWidth = widthMM > printerSize.getPrinterWidthMM() ? printerSize.getPrinterWidthPx() : printerSize.mmToPx(widthMM), 26 | colWidth = (int)Math.round((double) wantedPxWidth / (double) this.getColsCount()); 27 | 28 | if((colWidth * this.getColsCount()) > printerSize.getPrinterWidthPx()) { 29 | --colWidth; 30 | } 31 | 32 | if(colWidth == 0) { 33 | throw new EscPosBarcodeException("Barcode is too long for the paper size."); 34 | } 35 | 36 | this.colWidth = colWidth; 37 | } 38 | 39 | public abstract int getCodeLength(); 40 | 41 | public abstract int getColsCount(); 42 | 43 | public int getBarcodeType() { 44 | return this.barcodeType; 45 | } 46 | 47 | public String getCode() { 48 | return this.code; 49 | } 50 | 51 | public int getHeight() { 52 | return this.height; 53 | } 54 | 55 | public int getTextPosition() { 56 | return this.textPosition; 57 | } 58 | 59 | public int getColWidth() { 60 | return this.colWidth; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/connection/DeviceConnection.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.connection; 2 | 3 | import com.dantsu.escposprinter.exceptions.EscPosConnectionException; 4 | 5 | import java.io.IOException; 6 | import java.io.OutputStream; 7 | 8 | public abstract class DeviceConnection { 9 | protected OutputStream outputStream; 10 | protected byte[] data; 11 | 12 | public DeviceConnection() { 13 | this.outputStream = null; 14 | this.data = new byte[0]; 15 | } 16 | 17 | public abstract DeviceConnection connect() throws EscPosConnectionException; 18 | public abstract DeviceConnection disconnect(); 19 | 20 | /** 21 | * Check if OutputStream is open. 22 | * 23 | * @return true if is connected 24 | */ 25 | public boolean isConnected() { 26 | return this.outputStream != null; 27 | } 28 | 29 | /** 30 | * Add data to send. 31 | */ 32 | public void write(byte[] bytes) { 33 | byte[] data = new byte[bytes.length + this.data.length]; 34 | System.arraycopy(this.data, 0, data, 0, this.data.length); 35 | System.arraycopy(bytes, 0, data, this.data.length, bytes.length); 36 | this.data = data; 37 | } 38 | 39 | 40 | /** 41 | * Send data to the device. 42 | */ 43 | public void send() throws EscPosConnectionException { 44 | this.send(0); 45 | } 46 | /** 47 | * Send data to the device. 48 | */ 49 | public void send(int addWaitingTime) throws EscPosConnectionException { 50 | if(!this.isConnected()) { 51 | throw new EscPosConnectionException("Unable to send data to device."); 52 | } 53 | try { 54 | this.outputStream.write(this.data); 55 | this.outputStream.flush(); 56 | int waitingTime = addWaitingTime + this.data.length / 16; 57 | this.data = new byte[0]; 58 | if(waitingTime > 0) { 59 | Thread.sleep(waitingTime); 60 | } 61 | } catch (IOException | InterruptedException e) { 62 | e.printStackTrace(); 63 | throw new EscPosConnectionException(e.getMessage()); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/textparser/PrinterTextParserQRCode.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.textparser; 2 | 3 | import com.dantsu.escposprinter.EscPosPrinter; 4 | import com.dantsu.escposprinter.EscPosPrinterCommands; 5 | import com.dantsu.escposprinter.exceptions.EscPosBarcodeException; 6 | import com.dantsu.escposprinter.exceptions.EscPosEncodingException; 7 | import com.dantsu.escposprinter.exceptions.EscPosParserException; 8 | 9 | import java.util.Hashtable; 10 | 11 | public class PrinterTextParserQRCode extends PrinterTextParserImg { 12 | 13 | private static byte[] initConstructor(PrinterTextParserColumn printerTextParserColumn, 14 | Hashtable qrCodeAttributes, String data) throws EscPosParserException, EscPosBarcodeException { 15 | EscPosPrinter printer = printerTextParserColumn.getLine().getTextParser().getPrinter(); 16 | data = data.trim(); 17 | 18 | int size = printer.mmToPx(20f); 19 | 20 | if (qrCodeAttributes.containsKey(PrinterTextParser.ATTR_QRCODE_SIZE)) { 21 | String qrCodeAttribute = qrCodeAttributes.get(PrinterTextParser.ATTR_QRCODE_SIZE); 22 | if (qrCodeAttribute == null) { 23 | throw new EscPosParserException("Invalid QR code attribute : " + PrinterTextParser.ATTR_QRCODE_SIZE); 24 | } 25 | try { 26 | size = printer.mmToPx(Float.parseFloat(qrCodeAttribute)); 27 | } catch(NumberFormatException nfe) { 28 | throw new EscPosParserException("Invalid QR code " + PrinterTextParser.ATTR_QRCODE_SIZE + " value"); 29 | } 30 | } 31 | 32 | return EscPosPrinterCommands.QRCodeDataToBytes(data, size); 33 | } 34 | 35 | public PrinterTextParserQRCode(PrinterTextParserColumn printerTextParserColumn, String textAlign, 36 | Hashtable qrCodeAttributes, String data) throws EscPosParserException, EscPosBarcodeException { 37 | super( 38 | printerTextParserColumn, 39 | textAlign, 40 | PrinterTextParserQRCode.initConstructor(printerTextParserColumn, qrCodeAttributes, data) 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/connection/usb/UsbPrintersConnections.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.connection.usb; 2 | 3 | import android.content.Context; 4 | import android.hardware.usb.UsbConstants; 5 | import android.hardware.usb.UsbDevice; 6 | 7 | import androidx.annotation.Nullable; 8 | 9 | import com.dantsu.escposprinter.exceptions.EscPosConnectionException; 10 | 11 | public class UsbPrintersConnections extends UsbConnections { 12 | 13 | /** 14 | * Create a new instance of UsbPrintersConnections 15 | * 16 | * @param context Application context 17 | */ 18 | public UsbPrintersConnections(Context context) { 19 | super(context); 20 | } 21 | 22 | /** 23 | * Easy way to get the first USB printer paired / connected. 24 | * 25 | * @return a UsbConnection instance 26 | */ 27 | @Nullable 28 | public static UsbConnection selectFirstConnected(Context context) { 29 | UsbPrintersConnections printers = new UsbPrintersConnections(context); 30 | UsbConnection[] bluetoothPrinters = printers.getList(); 31 | 32 | if (bluetoothPrinters == null || bluetoothPrinters.length == 0) { 33 | return null; 34 | } 35 | 36 | return bluetoothPrinters[0]; 37 | } 38 | 39 | 40 | /** 41 | * Get a list of USB printers. 42 | * 43 | * @return an array of UsbConnection 44 | */ 45 | @Nullable 46 | public UsbConnection[] getList() { 47 | UsbConnection[] usbConnections = super.getList(); 48 | 49 | if(usbConnections == null) { 50 | return null; 51 | } 52 | 53 | int i = 0; 54 | UsbConnection[] printersTmp = new UsbConnection[usbConnections.length]; 55 | for (UsbConnection usbConnection : usbConnections) { 56 | UsbDevice device = usbConnection.getDevice(); 57 | int usbClass = device.getDeviceClass(); 58 | if((usbClass == UsbConstants.USB_CLASS_PER_INTERFACE || usbClass == UsbConstants.USB_CLASS_MISC ) && UsbDeviceHelper.findPrinterInterface(device) != null) { 59 | usbClass = UsbConstants.USB_CLASS_PRINTER; 60 | } 61 | if (usbClass == UsbConstants.USB_CLASS_PRINTER) { 62 | printersTmp[i++] = new UsbConnection(this.usbManager, device); 63 | } 64 | } 65 | 66 | UsbConnection[] usbPrinters = new UsbConnection[i]; 67 | System.arraycopy(printersTmp, 0, usbPrinters, 0, i); 68 | return usbPrinters; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/connection/bluetooth/BluetoothPrintersConnections.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.connection.bluetooth; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.bluetooth.BluetoothClass; 5 | import android.bluetooth.BluetoothDevice; 6 | 7 | import androidx.annotation.Nullable; 8 | 9 | import com.dantsu.escposprinter.exceptions.EscPosConnectionException; 10 | 11 | public class BluetoothPrintersConnections extends BluetoothConnections { 12 | 13 | /** 14 | * Easy way to get the first bluetooth printer paired / connected. 15 | * 16 | * @return a EscPosPrinterCommands instance 17 | */ 18 | @Nullable 19 | public static BluetoothConnection selectFirstPaired() { 20 | BluetoothPrintersConnections printers = new BluetoothPrintersConnections(); 21 | BluetoothConnection[] bluetoothPrinters = printers.getList(); 22 | 23 | if (bluetoothPrinters != null && bluetoothPrinters.length > 0) { 24 | for (BluetoothConnection printer : bluetoothPrinters) { 25 | try { 26 | return printer.connect(); 27 | } catch (EscPosConnectionException e) { 28 | e.printStackTrace(); 29 | } 30 | } 31 | } 32 | return null; 33 | } 34 | 35 | /** 36 | * Get a list of bluetooth printers. 37 | * 38 | * @return an array of EscPosPrinterCommands 39 | */ 40 | @SuppressLint("MissingPermission") 41 | @Nullable 42 | public BluetoothConnection[] getList() { 43 | BluetoothConnection[] bluetoothDevicesList = super.getList(); 44 | 45 | if (bluetoothDevicesList == null) { 46 | return null; 47 | } 48 | 49 | int i = 0; 50 | BluetoothConnection[] printersTmp = new BluetoothConnection[bluetoothDevicesList.length]; 51 | for (BluetoothConnection bluetoothConnection : bluetoothDevicesList) { 52 | BluetoothDevice device = bluetoothConnection.getDevice(); 53 | 54 | int majDeviceCl = device.getBluetoothClass().getMajorDeviceClass(), 55 | deviceCl = device.getBluetoothClass().getDeviceClass(); 56 | 57 | if (majDeviceCl == BluetoothClass.Device.Major.IMAGING && (deviceCl == 1664 || deviceCl == BluetoothClass.Device.Major.IMAGING)) { 58 | printersTmp[i++] = new BluetoothConnection(device); 59 | } 60 | } 61 | BluetoothConnection[] bluetoothPrinters = new BluetoothConnection[i]; 62 | System.arraycopy(printersTmp, 0, bluetoothPrinters, 0, i); 63 | return bluetoothPrinters; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/textparser/PrinterTextParserTag.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.textparser; 2 | 3 | import java.util.Hashtable; 4 | 5 | public class PrinterTextParserTag { 6 | 7 | private String tagName = ""; 8 | private Hashtable attributes = new Hashtable(); 9 | private int length = 0; 10 | private boolean isCloseTag = false; 11 | 12 | public PrinterTextParserTag(String tag) { 13 | tag = tag.trim(); 14 | 15 | if(!tag.substring(0, 1).equals("<") || !tag.substring(tag.length() - 1).equals(">")) { 16 | return; 17 | } 18 | 19 | this.length = tag.length(); 20 | int openTagIndex = tag.indexOf("<"), 21 | closeTagIndex = tag.indexOf(">"), 22 | nextSpaceIndex = tag.indexOf(" "); 23 | 24 | if(nextSpaceIndex != -1 && nextSpaceIndex < closeTagIndex) { 25 | this.tagName = tag.substring(openTagIndex + 1, nextSpaceIndex).toLowerCase(); 26 | 27 | String attributesString = tag.substring(nextSpaceIndex, closeTagIndex).trim(); 28 | while (attributesString.contains("='")) { 29 | int egalPos = attributesString.indexOf("='"), endPos = attributesString.indexOf("'", egalPos + 2); 30 | 31 | String attributeName = attributesString.substring(0, egalPos); 32 | String attributeValue = attributesString.substring(egalPos + 2, endPos); 33 | 34 | if(!attributeName.equals("")) { 35 | this.attributes.put(attributeName, attributeValue); 36 | } 37 | 38 | attributesString = attributesString.substring(endPos + 1).trim(); 39 | } 40 | } else { 41 | this.tagName = tag.substring(openTagIndex + 1, closeTagIndex).toLowerCase(); 42 | } 43 | 44 | 45 | if(this.tagName.substring(0, 1).equals("/")) { 46 | this.tagName = this.tagName.substring(1); 47 | this.isCloseTag = true; 48 | } 49 | } 50 | 51 | public String getTagName() { 52 | return this.tagName; 53 | } 54 | 55 | public Hashtable getAttributes() { 56 | return this.attributes; 57 | } 58 | 59 | public String getAttribute(String key) { 60 | return this.attributes.get(key); 61 | } 62 | public boolean hasAttribute(String key) { 63 | return this.attributes.containsKey(key); 64 | } 65 | 66 | public int getLength() { 67 | return this.length; 68 | } 69 | 70 | public boolean isCloseTag() { 71 | return this.isCloseTag; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/connection/usb/UsbConnection.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.connection.usb; 2 | 3 | import android.hardware.usb.UsbDevice; 4 | import android.hardware.usb.UsbManager; 5 | 6 | import com.dantsu.escposprinter.connection.DeviceConnection; 7 | import com.dantsu.escposprinter.exceptions.EscPosConnectionException; 8 | 9 | import java.io.IOException; 10 | 11 | public class UsbConnection extends DeviceConnection { 12 | 13 | private UsbManager usbManager; 14 | private UsbDevice usbDevice; 15 | 16 | /** 17 | * Create un instance of UsbConnection. 18 | * 19 | * @param usbManager an instance of UsbManager 20 | * @param usbDevice an instance of UsbDevice 21 | */ 22 | public UsbConnection(UsbManager usbManager, UsbDevice usbDevice) { 23 | super(); 24 | this.usbManager = usbManager; 25 | this.usbDevice = usbDevice; 26 | } 27 | 28 | /** 29 | * Get the instance UsbDevice connected. 30 | * 31 | * @return an instance of UsbDevice 32 | */ 33 | public UsbDevice getDevice() { 34 | return this.usbDevice; 35 | } 36 | 37 | /** 38 | * Start socket connection with the usbDevice. 39 | */ 40 | public UsbConnection connect() throws EscPosConnectionException { 41 | if (this.isConnected()) { 42 | return this; 43 | } 44 | 45 | try { 46 | this.outputStream = new UsbOutputStream(this.usbManager, this.usbDevice); 47 | this.data = new byte[0]; 48 | } catch (IOException e) { 49 | e.printStackTrace(); 50 | this.outputStream = null; 51 | throw new EscPosConnectionException("Unable to connect to USB device."); 52 | } 53 | return this; 54 | } 55 | 56 | /** 57 | * Close the socket connection with the usbDevice. 58 | */ 59 | public UsbConnection disconnect() { 60 | this.data = new byte[0]; 61 | if (this.isConnected()) { 62 | try { 63 | this.outputStream.close(); 64 | } catch (IOException e) { 65 | e.printStackTrace(); 66 | } 67 | this.outputStream = null; 68 | } 69 | return this; 70 | } 71 | 72 | /** 73 | * Send data to the device. 74 | */ 75 | public void send() throws EscPosConnectionException { 76 | this.send(0); 77 | } 78 | /** 79 | * Send data to the device. 80 | */ 81 | public void send(int addWaitingTime) throws EscPosConnectionException { 82 | try { 83 | this.outputStream.write(this.data); 84 | this.data = new byte[0]; 85 | } catch (IOException e) { 86 | e.printStackTrace(); 87 | throw new EscPosConnectionException(e.getMessage()); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/connection/usb/UsbOutputStream.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.connection.usb; 2 | 3 | import android.hardware.usb.UsbDevice; 4 | import android.hardware.usb.UsbDeviceConnection; 5 | import android.hardware.usb.UsbEndpoint; 6 | import android.hardware.usb.UsbInterface; 7 | import android.hardware.usb.UsbManager; 8 | import android.hardware.usb.UsbRequest; 9 | 10 | import androidx.annotation.NonNull; 11 | 12 | import java.io.IOException; 13 | import java.io.OutputStream; 14 | import java.nio.ByteBuffer; 15 | 16 | public class UsbOutputStream extends OutputStream { 17 | private UsbDeviceConnection usbConnection; 18 | private UsbInterface usbInterface; 19 | private UsbEndpoint usbEndpoint; 20 | 21 | public UsbOutputStream(UsbManager usbManager, UsbDevice usbDevice) throws IOException { 22 | 23 | this.usbInterface = UsbDeviceHelper.findPrinterInterface(usbDevice); 24 | if(this.usbInterface == null) { 25 | throw new IOException("Unable to find USB interface."); 26 | } 27 | 28 | this.usbEndpoint = UsbDeviceHelper.findEndpointIn(this.usbInterface); 29 | if(this.usbEndpoint == null) { 30 | throw new IOException("Unable to find USB endpoint."); 31 | } 32 | 33 | this.usbConnection = usbManager.openDevice(usbDevice); 34 | if(this.usbConnection == null) { 35 | throw new IOException("Unable to open USB connection."); 36 | } 37 | } 38 | 39 | @Override 40 | public void write(int i) throws IOException { 41 | this.write(new byte[]{(byte) i}); 42 | } 43 | 44 | @Override 45 | public void write(@NonNull byte[] bytes) throws IOException { 46 | this.write(bytes, 0, bytes.length); 47 | } 48 | 49 | @Override 50 | public void write(final @NonNull byte[] bytes, final int offset, final int length) throws IOException { 51 | if (this.usbInterface == null || this.usbEndpoint == null || this.usbConnection == null) { 52 | throw new IOException("Unable to connect to USB device."); 53 | } 54 | 55 | if (!this.usbConnection.claimInterface(this.usbInterface, true)) { 56 | throw new IOException("Error during claim USB interface."); 57 | } 58 | 59 | ByteBuffer buffer = ByteBuffer.wrap(bytes); 60 | UsbRequest usbRequest = new UsbRequest(); 61 | try { 62 | usbRequest.initialize(this.usbConnection, this.usbEndpoint); 63 | if (!usbRequest.queue(buffer, bytes.length)) { 64 | throw new IOException("Error queueing USB request."); 65 | } 66 | this.usbConnection.requestWait(); 67 | } finally { 68 | usbRequest.close(); 69 | } 70 | } 71 | 72 | @Override 73 | public void flush() throws IOException { 74 | 75 | } 76 | 77 | @Override 78 | public void close() throws IOException { 79 | if (this.usbConnection != null) { 80 | this.usbConnection.close(); 81 | this.usbInterface = null; 82 | this.usbEndpoint = null; 83 | this.usbConnection = null; 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/textparser/PrinterTextParserString.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.textparser; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.util.Arrays; 5 | 6 | import com.dantsu.escposprinter.EscPosCharsetEncoding; 7 | import com.dantsu.escposprinter.EscPosPrinter; 8 | import com.dantsu.escposprinter.EscPosPrinterCommands; 9 | import com.dantsu.escposprinter.exceptions.EscPosEncodingException; 10 | 11 | public class PrinterTextParserString implements IPrinterTextParserElement { 12 | private EscPosPrinter printer; 13 | private String text; 14 | private byte[] textSize; 15 | private byte[] textColor; 16 | private byte[] textReverseColor; 17 | private byte[] textBold; 18 | private byte[] textUnderline; 19 | private byte[] textDoubleStrike; 20 | 21 | public PrinterTextParserString(PrinterTextParserColumn printerTextParserColumn, String text, byte[] textSize, byte[] textColor, byte[] textReverseColor, byte[] textBold, byte[] textUnderline, byte[] textDoubleStrike) { 22 | this.printer = printerTextParserColumn.getLine().getTextParser().getPrinter(); 23 | this.text = text; 24 | this.textSize = textSize; 25 | this.textColor = textColor; 26 | this.textReverseColor = textReverseColor; 27 | this.textBold = textBold; 28 | this.textUnderline = textUnderline; 29 | this.textDoubleStrike = textDoubleStrike; 30 | } 31 | 32 | @Override 33 | public int length() throws EscPosEncodingException { 34 | EscPosCharsetEncoding charsetEncoding = this.printer.getEncoding(); 35 | 36 | int coef = 1; 37 | if(Arrays.equals(this.textSize, EscPosPrinterCommands.TEXT_SIZE_DOUBLE_WIDTH) || Arrays.equals(this.textSize, EscPosPrinterCommands.TEXT_SIZE_BIG)) 38 | coef = 2; 39 | else if(Arrays.equals(this.textSize, EscPosPrinterCommands.TEXT_SIZE_BIG_2)) 40 | coef = 3; 41 | else if(Arrays.equals(this.textSize, EscPosPrinterCommands.TEXT_SIZE_BIG_3)) 42 | coef = 4; 43 | else if(Arrays.equals(this.textSize, EscPosPrinterCommands.TEXT_SIZE_BIG_4)) 44 | coef = 5; 45 | else if(Arrays.equals(this.textSize, EscPosPrinterCommands.TEXT_SIZE_BIG_5)) 46 | coef = 6; 47 | else if(Arrays.equals(this.textSize, EscPosPrinterCommands.TEXT_SIZE_BIG_6)) 48 | coef = 7; 49 | 50 | if (charsetEncoding != null) { 51 | try { 52 | return this.text.getBytes(charsetEncoding.getName()).length * coef; 53 | } catch (UnsupportedEncodingException e) { 54 | throw new EscPosEncodingException(e.getMessage()); 55 | } 56 | } 57 | 58 | return this.text.length() * coef; 59 | } 60 | 61 | /** 62 | * Print text 63 | * 64 | * @param printerSocket Instance of EscPosPrinterCommands 65 | * @return this Fluent method 66 | */ 67 | @Override 68 | public PrinterTextParserString print(EscPosPrinterCommands printerSocket) throws EscPosEncodingException { 69 | printerSocket.printText(this.text, this.textSize, this.textColor, this.textReverseColor, this.textBold, this.textUnderline, this.textDoubleStrike); 70 | return this; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/connection/tcp/TcpConnection.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.connection.tcp; 2 | 3 | import com.dantsu.escposprinter.connection.DeviceConnection; 4 | import com.dantsu.escposprinter.exceptions.EscPosConnectionException; 5 | 6 | import java.io.IOException; 7 | import java.net.InetAddress; 8 | import java.net.InetSocketAddress; 9 | import java.net.Socket; 10 | import java.net.SocketTimeoutException; 11 | 12 | public class TcpConnection extends DeviceConnection { 13 | private Socket socket = null; 14 | private String address; 15 | private int port; 16 | private int timeout; 17 | 18 | /** 19 | * Create un instance of TcpConnection. 20 | * 21 | * @param address IP address of the device 22 | * @param port Port of the device 23 | */ 24 | public TcpConnection(String address, int port) { 25 | this(address, port, 30); 26 | } 27 | 28 | /** 29 | * Create un instance of TcpConnection. 30 | * 31 | * Overload of the above function TcpConnection() 32 | * Include timeout parameter in milliseconds. 33 | * 34 | * @param address IP address of the device 35 | * @param port Port of the device 36 | * @param timeout Timeout in milliseconds to establish a connection 37 | */ 38 | public TcpConnection(String address, int port, int timeout) { 39 | super(); 40 | this.address = address; 41 | this.port = port; 42 | this.timeout = timeout; 43 | } 44 | 45 | /** 46 | * Check if the TCP device is connected by socket. 47 | * 48 | * @return true if is connected 49 | */ 50 | public boolean isConnected() { 51 | return this.socket != null && this.socket.isConnected() && super.isConnected(); 52 | } 53 | 54 | /** 55 | * Start socket connection with the TCP device. 56 | */ 57 | public TcpConnection connect() throws EscPosConnectionException { 58 | if (this.isConnected()) { 59 | return this; 60 | } 61 | try { 62 | this.socket = new Socket(); 63 | this.socket.connect(new InetSocketAddress(InetAddress.getByName(this.address), this.port), this.timeout); 64 | this.outputStream = this.socket.getOutputStream(); 65 | this.data = new byte[0]; 66 | } catch (IOException e) { 67 | e.printStackTrace(); 68 | this.disconnect(); 69 | throw new EscPosConnectionException("Unable to connect to TCP device."); 70 | } 71 | return this; 72 | } 73 | 74 | /** 75 | * Close the socket connection with the TCP device. 76 | */ 77 | public TcpConnection disconnect() { 78 | this.data = new byte[0]; 79 | if (this.outputStream != null) { 80 | try { 81 | this.outputStream.close(); 82 | this.outputStream = null; 83 | } catch (IOException e) { 84 | e.printStackTrace(); 85 | } 86 | } 87 | if (this.socket != null) { 88 | try { 89 | this.socket.close(); 90 | this.socket = null; 91 | } catch (IOException e) { 92 | e.printStackTrace(); 93 | } 94 | } 95 | return this; 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /escposprinter/src/main/java/com/dantsu/escposprinter/textparser/PrinterTextParserLine.java: -------------------------------------------------------------------------------- 1 | package com.dantsu.escposprinter.textparser; 2 | 3 | import com.dantsu.escposprinter.exceptions.EscPosBarcodeException; 4 | import com.dantsu.escposprinter.exceptions.EscPosEncodingException; 5 | import com.dantsu.escposprinter.exceptions.EscPosParserException; 6 | 7 | import java.util.ArrayList; 8 | import java.util.regex.Matcher; 9 | import java.util.regex.Pattern; 10 | 11 | public class PrinterTextParserLine { 12 | private PrinterTextParser textParser; 13 | private int nbrColumns; 14 | private int nbrCharColumn; 15 | private int nbrCharForgetted; 16 | private int nbrCharColumnExceeded; 17 | private PrinterTextParserColumn[] columns; 18 | 19 | public PrinterTextParserLine(PrinterTextParser textParser, String textLine) throws EscPosParserException, EscPosBarcodeException, EscPosEncodingException { 20 | this.textParser = textParser; 21 | int nbrCharactersPerLine = this.getTextParser().getPrinter().getPrinterNbrCharactersPerLine(); 22 | 23 | Pattern pattern = Pattern.compile(PrinterTextParser.getRegexAlignTags()); 24 | Matcher matcher = pattern.matcher(textLine); 25 | 26 | ArrayList columnsList = new ArrayList(); 27 | int lastPosition = 0; 28 | 29 | while (matcher.find()) { 30 | int startPosition = matcher.start(); 31 | if(startPosition > 0) { 32 | columnsList.add(textLine.substring(lastPosition, startPosition)); 33 | } 34 | lastPosition = startPosition; 35 | } 36 | columnsList.add(textLine.substring(lastPosition)); 37 | 38 | this.nbrColumns = columnsList.size(); 39 | this.nbrCharColumn = (int) Math.floor(((float) nbrCharactersPerLine) / ((float) this.nbrColumns)); 40 | this.nbrCharForgetted = nbrCharactersPerLine - (nbrCharColumn * this.nbrColumns); 41 | this.nbrCharColumnExceeded = 0; 42 | this.columns = new PrinterTextParserColumn[this.nbrColumns]; 43 | 44 | int i=0; 45 | for (String column : columnsList) { 46 | this.columns[i++] = new PrinterTextParserColumn(this, column); 47 | } 48 | } 49 | 50 | 51 | public PrinterTextParser getTextParser() { 52 | return this.textParser; 53 | } 54 | 55 | public PrinterTextParserColumn[] getColumns() { 56 | return this.columns; 57 | } 58 | 59 | public int getNbrColumns() { 60 | return this.nbrColumns; 61 | } 62 | 63 | 64 | public PrinterTextParserLine setNbrCharColumn(int newValue) { 65 | this.nbrCharColumn = newValue; 66 | return this; 67 | } 68 | public int getNbrCharColumn() { 69 | return this.nbrCharColumn; 70 | } 71 | 72 | 73 | public PrinterTextParserLine setNbrCharForgetted(int newValue) { 74 | this.nbrCharForgetted = newValue; 75 | return this; 76 | } 77 | public int getNbrCharForgetted() { 78 | return this.nbrCharForgetted; 79 | } 80 | 81 | 82 | public PrinterTextParserLine setNbrCharColumnExceeded(int newValue) { 83 | this.nbrCharColumnExceeded = newValue; 84 | return this; 85 | } 86 | public int getNbrCharColumnExceeded() { 87 | return this.nbrCharColumnExceeded; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 17 | 24 | 25 |