In this new post of the blog series, we will be moving to different topic of new development tools. We will learn how to work with XML templates in our new Print Station Card app developed in Android (source code available) for ZC100/300 card printers.

 

The blog series will be covering the following use cases:

 

  1. ) Android App to print one sided card through TCP/USB
  2. ) Android App to print double sided card with 3 layers through TCP/USB
  3. ) XML Templates for ZC1/300 Card Printers

 

 

This blog will cover the third use case, XML Templates for ZC1/300 Card Printers.

 

Let's start with examining the image above. The image illustrates the basic skeleton of the XML template that is utilized for working with our ZC1/300 card printer. One of the advantages of using templates in an app is that defines a common pattern easy to use for multiple use cases with minimum effort for code development maintenance (few variations in source code is needed for app updates).  Without using templates, developers normally write code for each use case, so it adds complexity for development and testing stages in the life cycle of a software project, or for the updates of posterior versions of the app.

 

The main sections that are defined to be used in a ZC1/300 XML template are:

 

  • Header template: In this area is defined the attributes of the schema basically the template's name, and the attributes of the card such as type of card, card’s thickness, source and destination of the card. 
  • Fonts: The name is self-explanatory to define the type of font to use if text is used in any of the layers.
  • Sides: This area is used to declare if one(front) or two sides(front and back) would be needed for printing. Each sub-section is called side. For each side is needed to define how many layers would be printed. It is defined through print type:
    1. Print_type: define each printing layer that matches the type of panel(s) of the ribbon used. It can be a combination of panels (YMC) or unique panel (MonoK). Into this sub-section there are some basic elements needed to print a layer:
      • graphic: Image to be printed in this layer.
      • Text: Text to print in this layer
      • Barcode: Barcode to print in this layer
      • Line/Eclipse/Rectangle: Shapes to be printed in this layer
  • Magdata: The last section is used for magnetic encoding. This section defines the tracks to be encoded. If magnetic encoding is not needed, this section does not need to go into the template.

 

The source code of Print Station Card app can be downloaded from LINK-OS Multiplatform SDK product page. Once you have downloaded and installed the SDKs, you should be able now to see the folder by clicking on the apps menu on your Start Windows like the picture shows below. Otherwise, you may prefer to go directly to the Program Files folder and search for Zebra Technologies/link-os/ where you will find the SDKs for each environment.

The folder where you will find the version that we will be working in this blog is called Android_Card like the image bellow indicates.

 

The exercise proposed in this blog will work with the following three XML templates (attached to the blog), the first one will be a template for printing with three layers, two on the front, and one on the back following the use case proposed in the second blog of this series post.

 

  • XML template with 3 layers without variable text fields
<?xml version="1.0" encoding="utf-8"?>
<template name="Template" card_type="2" card_thickness="30" delete="no">
<fonts>
    <font id="1" name="arial" size="12" bold="no" italic="no" underline="no" />
    <font id="2" name="arial" size="14" bold="yes" italic="no" underline="no" />
</fonts>
<sides>
    <side name="front" orientation="landscape" rotation="0">
        <print_types>
            <print_type type="color">
                <graphic format="bmp" width="1024" height="640" x="0" y="0" delete="false">Sample_Loyal_ID_Card-Front</graphic>
            </print_type>
            <print_type type="overlay">
                <graphic format="bmp" width="1024" height="648">TEST_OVERLAY_SECURITY</graphic>
            </print_type>
        </print_types>
    </side>
    <side name="back" orientation="landscape">
        <print_types>
            <print_type type="mono">
                <graphic format="bmp" width="1024" height="640" x="0" y="0" delete="false">Sample_ID_Back_barcodes</graphic>
            </print_type>
        </print_types>
    </side>
</sides>
</template>

 

  • XML template with 3 layers with 5 variable text fields
<?xml version="1.0" encoding="utf-8"?>
<template name="Template" card_type="2" card_thickness="30" delete="no">
<fonts>
    <font id="1" name="arial" size="12" bold="no" italic="no" underline="no" />
    <font id="2" name="arial" size="14" bold="yes" italic="no" underline="no" />
</fonts>
<sides>
    <side name="front" orientation="landscape" rotation="0">
        <print_types>
            <print_type type="color">
                <graphic format="bmp" width="1024" height="640" x="0" y="0" delete="false">Sample_Loyal_ID_Card-Front</graphic>
            </print_type>
            <print_type type="mono">
                <graphic field="imageLogo" format="bmp" width="280" height="100" x="710" y="40" delete="false"/>
                <text field="firstName" font_id="1" width="0" height="0" x="50" y="400" angle="0" color="0x000000" alignment="left"/>
                <text field="lastName" font_id="1" width="0" height="0" x="50" y="450" angle="0" color="0x000000" alignment="left"/>
                <text field="email" font_id="2" width="0" height="0" x="50" y="500" angle="0" color="0x000000" alignment="left"/>
                <barcode field="qrCode" x="720" y="380" width="250" height="250" rotation="0" code="qrcode" multiplier="8"/>
            </print_type>
            <print_type type="overlay">
                <graphic format="bmp" width="1024" height="648">TEST_OVERLAY_SECURITY</graphic>
            </print_type>
        </print_types>
    </side>
    <side name="back" orientation="landscape">
        <print_types>
            <print_type type="mono">
                <graphic format="bmp" width="1024" height="640" x="0" y="0" delete="false">Sample_ID_Back_barcodes</graphic>
            </print_type>
        </print_types>
    </side>
</sides>
</template>

 

  • XML template with 3 layers, and with the whole data integrated in the template.
<?xml version="1.0" encoding="utf-8"?>
<template name="Template" card_type="2" card_thickness="30" delete="no">
<fonts>
    <font id="1" name="arial" size="12" bold="no" italic="no" underline="no" />
    <font id="2" name="arial" size="14" bold="yes" italic="no" underline="no" />
</fonts>
<sides>
    <side name="front" orientation="landscape" rotation="0">
        <print_types>
            <print_type type="color">
                <graphic format="bmp" width="1024" height="640" x="0" y="0" delete="false">Sample_Loyal_ID_Card-Front</graphic>
            </print_type>
            <print_type type="mono">
                <graphic field="" format="bmp" width="280" height="100" x="710" y="40" delete="false">zebralogo</graphic>
                <text field="" font_id="1" width="0" height="0" x="50" y="400" angle="0" color="0x000000" alignment="left">Manuel</text>
                <text field="" font_id="1" width="0" height="0" x="50" y="450" angle="0" color="0x000000" alignment="left">Caicedo-Rivera</text>
                <text field="" font_id="2" width="0" height="0" x="50" y="500" angle="0" color="0x000000" alignment="left">test@email.com</text>
                <barcode field="" x="720" y="380" rotation="0" width="250" height="250" code="qrcode" multiplier="8">www.zebra.com</barcode>
            </print_type>
            <print_type type="overlay">
                <graphic format="bmp" width="1024" height="648">TEST_OVERLAY_SECURITY</graphic>
            </print_type>
        </print_types>
    </side>
    <side name="back" orientation="landscape">
        <print_types>
            <print_type type="color">
                <graphic format="bmp" width="1024" height="640" x="0" y="0" delete="false">Sample_ID_Back_barcodes</graphic>
            </print_type>
        </print_types>
    </side>
</sides>
</template>

 

 

We recommend the following the high-level workflow to the developers to code a basic app with templates.

 

  1. ) Routine to save the xml files on the device
  2. ) Routine to find/select the xml files on the device
  3. ) Routine to find/select the Zebra Card printer, and verify the actual configuration of the printer, so this information can be saved and compared later for each template to verify if that template can be printed with the printer connected
  4. ) Routine to analyze the xml file and provide the right UX to user to introduce the variables fields of the template
  5. ) Merge the xml template skeleton with the variables (if needed) and send the print job template to the printer
  6. ) Monitor the print job template until the connection is closed

 

The image below shows the second XML example (3 layers with 5 variable text fields), so you can appreciate on the right side how the app allows to the user fill out each field of the template variables with data.

Once you run the application in your android app, you will need to save the files (images and XML templates) in two different directories as it is shown below. If the application does not create the two folders for TemplateFiles and TemplateImages, you will need to create them manually on your android device.

 

The template functionality does not cover all panels of the ribbons as the SDK does, so the list complete of the panels supported are: color, monochrome, overlay, inhibit, helper, uv, silver, pearl, color is assumed by default.

 

Let’s review the components of the app that are exclusive of the template implementation in Android. If you want to work directly with templates in your app, you will need to use the ZebraCardTemplate interface which is the interface used to define functions in template related operations.

In addition to the previous interface, the developer will need to work with the TemplateJob class that is for holding the data used during card template printing. Once the TemplateJob instance has been loaded with the XML template to be printed, and with the data, then it is sent to the printer with the command ZebraCardPrinter.printTemplate including the number of copies and job Data.

 

Print Station will understand the templates in two different ways. The first style is when you provide the XML skeleton with the name of the variables to be called, and the second style is when you provide the XML without names of the variables, but the data already uploaded on the XML template. The cool thing about the Print Station card app is that dynamically creates the variables to fill it out on the screen based on the XML template that is saved in the device (see code/image below).

 

printButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (!isApplicationBusy) {
            isApplicationBusy = true;

            printButton.setEnabled(false);
            UIHelper.hideSoftKeyboard(SelectedTemplateJobActivity.this);

            Map<String, String> varsData = new HashMap<>();
            for (String variable : variablesData.keySet()) {
                varsData.put(variable, variablesData.get(variable).getText());
            }

            int quantity = Integer.parseInt(quantitySpinner.getSelectedItem().toString());

            if (sendTemplateJobTask != null) {
                sendTemplateJobTask.cancel(true);
            }

            sendTemplateJobTask = new SendTemplateJobTask(zebraCardTemplate, SelectedPrinterManager.getSelectedPrinter(), templateName, varsData, quantity);
            sendTemplateJobTask.setOnSendTemplateJobListener(SelectedTemplateJobActivity.this);
            sendTemplateJobTask.execute();
        }
    }
});

The last step is to send the information to the printer for printing, it is done with the code shown below.

 

protected Void doInBackground(Void... params) {
    Connection connection = null;
    ZebraCardPrinter zebraCardPrinter = null;

    try {
        connection = printer.getConnection();
        connection.open();

        zebraCardPrinter = ZebraCardPrinterFactory.getInstance(connection);

        TemplateJob templateJob = zebraCardTemplate.generateTemplateJob(templateName, variablesData);
        jobId = zebraCardPrinter.printTemplate(quantity, templateJob);
    } catch (Exception e) {
        exception = e;
    } finally {
        ConnectionHelper.cleanUpQuietly(zebraCardPrinter, connection);
    }

    return null;
}

 

With the blog, I have attached the three XML examples and the images which you can use and play with the application. If you plan to use the XML samples, be aware that the name of the images on the layer sections of the format must match with the real names of files saved on your android device, and the folder defined to be used with the Card Print Station app.

 

The intention of this new post was to provide another alternative of how to get the same output achieved through blog #2 of the blog series but this time by using templates in Android. Zebra wanted to share the source code with the developers, so the concepts explained here can be easily implemented in their apps. The app also provides an easy way for end-users to work with XML templates and Zebra card printers.

 

If you have questions or comments, please feel free to post them, and see you soon in my last post of this blog series.