1. Documentation
  2. Printing Service
  3. API

API Overview

These documents describe how to use the AEVI Printing API. This API allows developers to quickly and easily integrate printing into your Android application. The API allows you to print using any AEVI enabled device and selected printer drivers. Specifically this API is designed for use with receipt/line printer type devices.

The print API itself makes extensive use of reactive (Rx) based principles. Therefore in the case of the Java API it makes heavy use of the RxJava library. To read more about Rx principles and the RxJava library itself see the documentation here. For the remainder of this documentation it is assumed that the reader is familiar with asynchronous and event-based programming using observable streams.

There is a PrintingExample that is part of this open source project, please see android-pos-print-api.

The javadocs are available here.

Getting started

repositories {
    maven {
        url "http://dl.bintray.com/aevi/aevi-uk"
    }
}

In your main gradle.build you'll need to include our public bintray in your main repositories section.

compile 'com.aevi.print:print-api:1.1.0'

And then add to your dependencies section

PrinterManager printerManager = PrinterApi.getPrinterManager(this);

The main entry point to the SDK is to first obtain an instance of the PrintManager. This object can then be used to send print jobs, actions and listen to printer events.

<uses-permission android:name="com.aevi.permission.NGS_PRINT_SERVICE"/>

In order to bind to the printer service your application must add the permission com.aevi.permission.NGS_PRINT_SERVICE to your manifest file.

if(printerManager.isPrinterServiceAvailable()) {

  PrintPayload payload = new PrintPayload();

  // fill out payload here. Described below

  printerManager.print(payload)
          .subscribe(new Consumer<PrintJob>() {
              @Override
              public void accept(@NonNull PrintJob printResult) throws Exception {
                  // Do something with results here
                  Log.d(TAG, "Got printing result:: " + printResult.getPrintJobState());
              }
          }, new Consumer<Throwable>() {
              @Override
              public void accept(@NonNull Throwable throwable) throws Exception {
                  Log.e(TAG, "Error while printing", throwable);
              }
          });
}

The PrinterManager can then be used as shown below to send a print job to a printer. If no printer is specified then the print will be sent to the default printer. You can specify a printer by setting the printerId in the PrintPayload object. PrinterIds are obtained via the PrinterManager using the getPrinterSettings() method.

Printing

if(printerManager.isPrinterServiceAvailable()) {

  PrintPayload payload = new PrintPayload();

  // fill out payload here. Described below

  printerManager.print(payload)
          .subscribe(new Consumer<PrintJob>() {
              @Override
              public void accept(@NonNull PrintJob printResult) throws Exception {
                  // Do something with results here
                  Log.d(TAG, "Got printing result: " + printResult.getPrintJobState());
              }
          }, new Consumer<Throwable>() {
              @Override
              public void accept(@NonNull Throwable throwable) throws Exception {
                  Log.e(TAG, "Error while printing", throwable);
              }
          });
}

Before calling any print methods you should check that the printing service is installed and available as can be seen opposite using the isPrinterServiceAvailable() method.

All printing requests require a PrintPayload object to be built, which is described below. Once this object is constructed it is sent to the PrintManager using the print() method. This method must be subscribed to before the payload is sent.

The subscriber should also ensure they are subscribed to any errors that may be thrown during printing. Exceptions are only thrown if an unexpected error is returned by the AEVI print service. The stream of PrintJob objects returned by the print service will indicate success or failure of the print itself.

By default print jobs will be sent to the default printer. However, prints can also be sent to a specific printer. This is accomplished by setting a printerId in the PrintPayload using the setPrinterId() method. The printerIds for available printers can be obtained via the PrintManager.getPrintersSettings() method. Usage of this method is shown below.

Building print payloads

PrintPayload printPayload = new PrintPayload();
printPayload.append("Align Left");
printPayload.append("Align Right").align(Alignment.RIGHT);
printPayload.append("Align Center").align(Alignment.CENTER);
printPayload.append("Emphasized").fontStyle(FontStyle.EMPHASIZED);
printPayload.append("Inverted").fontStyle(FontStyle.INVERTED);
printPayload.appendEmptyLine();
printPayload.append("InvertedEmphasized").fontStyle(FontStyle.INVERTED_EMPHASIZED);
printPayload.append("Single Underlined").underline(Underline.SINGLE);
printPayload.append("Double Underlined").underline(Underline.DOUBLE);
printPayload.appendEmptyLine();
// append a basket 20 columns wide
printPayload.appendLeftRight(20, "Name", "Price");
printPayload.appendLeftRight(20, "Doughnut", " $1.02");
printPayload.appendLeftRight(20, "Beer", "$6.00");
printPayload.appendEmptyLine();

PrintPayload objects can be used to configure most textual print layouts you would expect a receipt printer to handle. This includes standard styles such as EMPHASIZED, INVERTED etc and alignment e.g. LEFT, RIGHT. See the javadocs for a full list of styles.

Adding images

Bitmap logo = BitmapFactory.decodeResource(context.getResources(),
                          R.drawable.yourlogo, bitmapFactoryOptions);
printPayload.appendEmptyLine();
printPayload.append(logo).align(Alignment.CENTER);

Images can also be added to the PrintPayload as shown in the example. By default images added that are larger than the width of the printer paper will be scaled down to fit. However, you can also choose that the image added is clipped to the width of the paper and not scaled by setting the scaleToFit parameter to false when calling PrintPayload.append(Bitmap bitmap, boolean scaleToFit).

Printer Settings

printerManager.getPrintersSettings()
                   .subscribe(new Consumer<PrinterSettings>() {
                       @Override
                       public void accept(@NonNull PrinterSettings printerSettings) throws Exception {
                          // store or cache printer settings here
                       }
                   });

The settings of each printer available to your device can be obtained using the getPrintersSettings() method. This method will return an observable stream of PrinterSettings objects. The PrinterSettings object contains various details about the aspects of the printer and the functionality it provides. Each PrinterSettings object also contains the unique value of the printerId that can be used to refer to a specific printer device.

The PrinterSettings object contains information about: * paperwidth - The paper width supported by this printer in mm * printableWidth - The maximum width this printer can print on the paper size given above in mm * dotsPerMm - The number of dots this printer can support per mm (to convert to dpi multiply by 25.4) * paperkind - The type of paper supported by this printer e.g. THERMAL, NORMAL * codepages - The character codepages a printer will accept * actions - The actions that can be sent to this printer to perform a task e.g. "cutPaper" * options - A Map of String key value pairs that describe any printer specific options this printer exposes * fonts - A list of fixed width fonts that the printer supports * languages - A list of language code supported by the printer. This allows text characters to be sent in different languages if the printer supports it.

The PrinterSettings object is a graph of data that contains information about the printer at a given point in time. This data may be updated by the printer driver at any time. In particular this data change could occur in response to a user settings change or perhaps the printer configuration is changed (e.g. different sized paper inserted). Therefore, the PrinterSettings object(s) should not be stored permanently or cached. Instead you should subscribe to the settings stream as shown in the example and ensure that if the data is updated you use the latest values.

Printer fonts

PrinterFont[] fonts = printerSettings.getPrinterFonts();
if(fonts != null && fonts.length > 0) {
    int cols = fonts[0].getNumColumns();
    // In this font you can now print `cols` columns of text per line
}

A list of fonts available can (optionally) be returned along with the PrinterSettings object above. These fonts provide details of the various sizes of fixed width text a printer can print at. In particular the PrinterFont object contains the number of columns (per line) that can be printed. This is useful in determining table or columnar layouts as well as maximum number of characters per line. If this number of characters is exceeded then each printer driver may choose to truncate or wrap the text sent in the PrintPayload.

Using fonts

String tstStr = "Hello World!";
PrinterFont font = fonts[0];
printPayload.append(tstStr, font);

To use a font in your PrintPayload simply call the overloaded append method passing in your text and the font you wish to use. If a font is not passed into the append method then the printer default font will be used.

Printer Statuses

String printerId = "" // PrinterId obtained previously in getPrintersSettings call

printerManager.status(printerId).subscribe(new Consumer<PrinterStatus>() {
    @Override
    public void accept(@NonNull PrinterStatus printerStatus) throws Exception {
        // do something with the status if required
        String status = printerStatus.getStatus();
    }
});

Your application can optionally subscribe to printer events. These events can be used to notify the user that something has happened on the printer if required. It is not mandatory that the statuses are observed but they may be useful for the user in diagnosing print issues.

Status Code Meaning
printerReady The printer driver is connected to this printer and is ready to print
printerOffline The printer driver has just disconnected from this printer and is no-longer ready to print
coverOpened The cover has been opened on the printer
outOfPaper The printer has just run out of paper
lowBattery The printers battery is low
mechanicalError The printer has mechanically failed in some way
unrecoverableError The printer driver has failed to connect to the printer and cannot recover
printerOverheated The printer has overheated
wrongPaper Wrong paper detected in the printer
drawerOpened The action command to open the cash drawer has completed successfully.
drawerNotAvailable The action command to open the cash drawer failed because it is either not connected or the printer is offline
drawerHigh The cash drawer status pin is high, which may indicate that the cash drawer is closed
drawerLow The cash drawer status pin is low, which may indicate that the drawer is either open or the drawer is not plugged in
timeout The printer driver timed out while attempting to print

Actions

String action = "cutPaper"; // String value obtained from PrinterSettings
printerManager.sendAction(printerId, action);

Actions can be sent to a printer. This method is used to send any custom actions a printer can perform, common examples of action would be "cutPaper" and "openCashDrawer". Each printer is free to define its own list of available actions. These can be obtained by reading the actions from the PrinterSettings object. Different printer drivers may choose to implement their own set of action commands but default/common actions are defined in the PrinterMessages interface.

Errors

Errors returned by printing service are thrown as MessageException objects.

The following common errors are defined as Strings in the PrinterMessages interface but printer drivers are free to define there own specific errors if required.

Error Code Meaning
printFailed Printer failed to print unexpectedly
printerNotFound Printer with the given printerId is not found
serviceNotAvailable Printer service not available or not installed
getSettingsFailed Failed while getting printer settings objects
getStatusFailed Failed while getting printer status events
coverOpen Print job failed because the cover is open
outOfPaper Print job failed because the device is out of paper
busy Print job failed because the printer can only handle one print job and it is in progress