This library combines various printer implementations into a single, easy-to-use interface.
Step 1. Add the JitPack repository to your settings.gradle
file:
dependencyResolutionManagement {
repositories {
...
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
Step 2. Add the dependency to your app build.gradle
:
dependencies {
implementation 'com.github.tillhub:print-engine:x.x.x'
}
Step 3. Enable JNI legacy packaging
packaging {
jniLibs {
useLegacyPackaging = true
}
}
This SDK offers supports 2 types printing devices:
- PAX devices with a build in printer (A920, A920 pro, etc.)
- Sunmi devices with a build in printer (V2, V2 PRO, V2s, etc.)
- Verifone devices with a build in printer
For devices without printer support the SDK defaults to an EmulatedPrinter
implementation that prints into Logcat, this way it is easy to develop on emulators and unsupported devices.
The SDK will automatically select the correct implementation based on the device its running on.
Singleton Access
: Obtain a singleton reference to thePrinterEngine
instance.Initialization
: Create a per Context Printer instance. SDK will automatically selects the appropriate printer based on the device manufacturer (Sunmi, Pax, or emulated).Initiate print
: Callprinter.startPrintJob(printJob)
to initiate printing. Pass appropriate PrintJob that should be printed. When print is finished it returnsPrinterResult
.Handle printer state
: Subscribe to theprinter.observePrinterState()
flow to receivePrinterState
objects that inform about the state of printer.
override fun onCreate(savedInstanceState: Bundle?) {
// ...
val printEngine = PrintEngine.getInstance(context)
val printer = printEngine.printer
printButton.setOnClickListener {
lifecycleScope.launch {
val result = printer.startPrintJob(printJob)
when (result) {
is PrinterResult.Success -> {
// Handle success
}
is PrinterResult.Error -> {
// Handle failure
}
}
}
}
lifecycleScope.launch {
// Observing printer state of printer
printer.observePrinterState().collect { printerState ->
// Handle printerState result
}
}
}
companion object {
private val printJob = PrintJob(listOf(
PrintCommand.Text("This is a line"),
PrintCommand.Text("This is a another line"),
PrintCommand.Text("-------"),
PrintCommand.Text("Barcode:"),
PrintCommand.Barcode("123ABC"),
PrintCommand.Text("QR code:"),
PrintCommand.QrCode("123ABC"),
PrintCommand.FeedPaper,
))
}
A PrintJob
is defined as a set of PrintCommand
objects, the commands will be executed sequentially, with that a receipt can be build.
The PrintJob
object offers 2 convenience values:
isNotEmpty
gives the information if aPrintJob
is empty or notdescription
gives a string representation of the build receipt
List of commands:
PrintCommand.Text(val text: String)
PrintCommand.Image(val image: Bitmap)
PrintCommand.Barcode(val barcode: String)
PrintCommand.QrCode(val code: String)
PrintCommand.RawData(val data: RawPrinterData)
/**
* 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
*/
PrintCommand.FeedPaper
/**
* Printer cuts paper and throws exception on machines without a cutter
*/
PrintCommand.CutPaper
interface PrintAnalytics {
fun logPrintReceipt(receiptText: String)
fun logErrorPrintReceipt(message: String)
}
The PrinterEngine SDK offers a PrintAnalytics
interface that can be attached to the PrinterEngine
and will call log methods for printed receipts and errors.
This can be used to for analytics and logging purposes.
The interface implementation has to be attached to the engine instance before getting the printer instance for it to work.
PrintAnalytics usage:
override fun onCreate(savedInstanceState: Bundle?) {
// ...
val printEngine = PrintEngine.getInstance(context)
// attaching the interface implementation
printEngine.setAnalytics(object : PrintAnalytics {
override fun logPrintReceipt(receiptText: String) {
// Handle printed receipt text
}
override fun logErrorPrintReceipt(message: String) {
// Handle printing error
}
})
val printer = printEngine.printer
}
Because some printing implementations don't support printing barcodes as is, the BarcodeEncoder
implementation was made that generates a bitmap of a Code 128 barcode or QR code, that is then printed.
The PrinterEngine
offers an instance of this interface that can be used in the host app for convenience.
In case of an error at time of bitmap generation an null
value is returned.
override fun onCreate(savedInstanceState: Bundle?) {
// ...
val printEngine = PrintEngine.getInstance(context)
val barcodeEncoder = printEngine.barcodeEncoder
val qrCode: Bitmap? = barcodeEncoder.encodeAsBitmap(
content = "barcode_content",
type = BarcodeType.QR_CODE,
imgWidth = 500,
imgHeight = 500
)
val code128: Bitmap? = barcodeEncoder.encodeAsBitmap(
content = "barcode_content",
type = BarcodeType.CODE_128,
imgWidth = 500,
imgHeight = 250
)
}
MIT License
Copyright (c) 2024 Tillhub GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.