Warning Older Docs! - You are viewing documentation for a previous released version of RhoMobile Suite.

Printing

Overview

In RhoMobile Suite 4.1, we introduced a simplified method for printing. In this release we are currently supporting printing to Zebra printers only (via WiFi and BlueTooth), but in subsequent releases we will be adding different printer types.

Enabling the APIs

In the API reference, you will see two new APIs: Printing and PrintingZebra. The Printing API is a parent class that is defined to easily define common class attributes that specific printer type APIs like PrintingZebra will inherit. To enable this functionality in your application, your must include both of these extensions in you build.yml

extensions: ["printing","printing_zebra"]

Finding Printers

In order to print you must first find and connect to a printer. There are a few different ways to do this, but they all use the searchPrinters Method.

For example, in the following code snippet, we are looking for any Zebra printers over BlueTooth only, by specifying connectionType and printerType in the options parameter:

var printers = [];

Rho.Printer.searchPrinters({ 
    connectionType:Rho.Printer.CONNECTION_TYPE_BLUETOOTH,  
    printerType: Rho.Printer.PRINTER_TYPE_ZEBRA
     }, function (cb){
        if(cb.status == 'PRINTER_STATUS_SUCCESS')
        {
            if (typeof cb.printerID != "undefined")
            {
                console.log('Found: ' + cb.printerID)
                // > Found ZEBRA_PRINTER_1

                printers.push(cb.printerID);
            }
            else
            {
                console.log('Done Searching');
            }
        }
        else
        {
            console.log(cb.status);
        }
    });
It is recommended to provide as many parameters as possible to reduce the search time.

If we knew the printer’s BlueTooth address we could have specified the deviceAddress in the options parameter. When you are connecting for the first time to your device, you may be prompted for the devices Bluetooth secure pairing PIN. usually by default manufacturers use 0000, 1111 or 1234.

Rho.PrinterZebra.searchPrinters({ 
    connectionType:Rho.Printer.CONNECTION_TYPE_BLUETOOTH,  
    deviceAddress: '00:03:7A:4C:F2:DB'
    ...
The deviceAddress for a BlueTooth device must include the ':' like ##:##:##:##:##:##. The discovery process may take several seconds to complete.

Likewise, if we were searching for a printer over WiFi, we could have also used the deviceAddress & devicePort parameters.

Rho.Printer.searchPrinters({ 
    connectionType:Rho.Printer.CONNECTION_TYPE_TCP,  
    deviceAddress: '192.168.1.121',
    devicePort: 8080
    ...
Be sure that your BlueTooth or WiFi radios are turned on in your device. Your printer should also be in BlueTooth discover mode

The searchPrinters callback function will be executed for each printer found. The callback will include a printerID property, which will be used to establish a connection with the printer. When the search is complete, it will issue one more callback with a success status, but will not contain a printerID. You would use this as an indication that the search process is complete and it is safe to connect to the printer.

This ID is a unique ID that the RhoMobile framework keeps track of. It is not an ID that the printer manufacturer may be using.

Connecting to the Printer

Now that we found the printers using the searchPrinters method, we should have a printerID in our printers array variable. We create an instance of Printer class by calling the getPrinterByID method and pass in a string that is the printerID that was returned in the searchPrinters call

// Ex: printers[0] = 'ZEBRA_PRINTER_1'
var myPrinter = Rho.Printer.getPrinterByID(printers[0]);

// myPrinter is now an instance class of Printer
// and can use the Instance Methods and properties associated 
// with that class

Once we have an instance to a specific printer we now must make a connection, using the connect method, before executing any additional commands:

myPrinter.connect(function (cb){

    console.log(cb);
    // > PRINTER_STATUS_SUCCESS
    //cb = PRINTER_STATUS... constant

    console.log(myPrinter.deviceName);
    // > 'XXXX09-10-5799'
    // deviceName will be Zebra's 'Friendly Name'

    console.log(myPrinter.deviceAddress);
    // > '00:03:7A:4C:F2:DB'
    // deviceAddress will equal the Bluetooth Address

});

The callback object in the connect method will be a string containing one of the PRINTER_STATUS… constants.

Getting Printer State

You can also check some information about the printer using the requestState method. This method sends a message to the printer to retrieve the current status and returns the information in a callback. The first parameter of this method is an array that lists the items to find. These are Printer Constants that start with PRINTER_STATE. Each state you specify will be returned as a property of the callback object.

// Assumes you have created an instance 'myPrinter'
// from previous methods described
myPrinter.requestState(['PRINTER_STATE_IS_READY_TO_PRINT',
    'PRINTER_STATE_IS_PAPER_OUT'],function (cb){
        console.log(cb.status);
        console.log(cb.PRINTER_STATE_IS_PAPER_OUT);
        console.log(cb.PRINTER_STATE_IS_READY_TO_PRINT);

    });

Getting Supported Printer Languages

Before you should send any commands to the printer, you should know what languages the printer supports. In the case of Zebra these may be ZPL, CPCL, EPS, etc. You can do this by using the enumerateSupportedControlLanguages method. The callback will be an array of PRINTER_LANGUAGE… Constants:

//assumes you created a printer instance from previous instructions
myPrinter.enumerateSupportedControlLanguages(function(cb){
    // cb = Array of strings 
    // PRINTER_LANGUAGE_ZPL
    // PRINTER_LANGUAGE_CPCL
    // PRINTER_LANGUAGE_EPS
});

Sending Printer Commands

Now that we found and connected to the printer, we can send commands to the printer. Depending on your printer model and the current state it is in, you may see different behavior. Commands for each printer will not be discussed here, you should consult the manufacturers' technical documentation. There are two fundamental ways for sending commands

  • Sending a string that includes raw printer commands
  • Sending a series of commands that are stored in a file ex: ZPL,CPCL

Sending a Raw String

To send a string to the printer, you use the printRawString method

// If my printer was in line mode I would see this text printed
myPrinter.printRawString('This is a test print');

// Example of sending a Zebra CPCL Command
// changing from linemode to ZPL mode
myPrinter.printRawString('! U1 setvar "device.languages" "ZPL"\r\n');

Sending a Series of Commands

Typically, there will be a series of commands that need to be executed. These command files(ex; ZPL, CPCL) can be generated by hand or from a tool provided by Zebra. You can include these files in your application, so that they can be used.

Assuming we have a file address.cpcl stored in the application’s public folder, which has CPCL commands to print an address:

! U1 SETLP 5 2 46
AURORA'S FABRIC SHOP
! U1 SETLP 7 0 24
123 Castle Drive, Kingston, RI 02881
(401) 555-4CUT

You can use the RhoFile.join helper function and Application.publicFolder property to create a fully qualified path to the address.cpcl file. This file path is passed to the sendFileContents method:

var addressFile = Rho.RhoFile.join(Rho.Application.publicFolder, 'address.cpcl');

//assuming you made an instance and connected per the previous instructions
myPrinter.sendFileContents(addressFile,function(e){
    console.log(e);
    // Will return a PRINTER_STATUS... CONSTANT String
    });

Using Files Already Stored On The Printer

You may have already stored files on the printer or have been included through some other means. You can retrieve a list of files that exists on the printer by using the retrieveFileNames method

myPrinter.retrieveFileNames(function (e){
    // e.status : PRINTER_STATUS_SUCCESS, PRINTER_STATUS_ERROR
    // e.fileNames : ARRAY of file names
    //
});

Now that we have the names of the files stored on the printer, we can print to them and pass in variables that the file is expecting (specified in the ZPL or CPCL file). We do this either using the printStoredFormatWithArray method or the printStoredFormatWithHash method. Both of these include three parameters:

*formatPathOnPrinter – this will be ‘E:filename’ where ‘filename’ is the name of the file that we sent in the previous step, or one that existed on the device (assuming the file is on the printers ‘E’ partition)

*vars – This represents the data we want to pass to the label.

printStoredFormatWithArray – An array of strings representing the data to fill into the format. For ZPL formats, index 0 of the array corresponds to field number 2 (FN2). For CPCL, the variables are passed in the order that they are found in the format

printStoredFormatWithHash (Only ZPL Support) – An hash which contains the key/value pairs for the stored format. For ZPL formats, the key number should correspond directly to the number of the field in the format. Number keys should be passed as string ex: ‘1’:‘field1’, ‘2’:‘field2’ etc.

*callback – Will return a PRINTER_STATUS… CONSTANT String

Example using printStoredFormatWithArray

myPrinter.printStoredFormatWithArray('E:LABEL.ZPL',['John Doe','123 East Main St','Smalltown, NY 11766'],function (e){
        // Will return a PRINTER_STATUS... CONSTANT String
    });

Example using printStoredFormatWithHash

myPrinter.printStoredFormatWithHash('E:LABEL.ZPL',{ '1':'John Doe','2': '123 East Main St','3': Smalltown, NY 11766'},function (e){

    // e = PRINTER_STATUS... CONSTANT String
    if(e == 'PRINTER_STATUS_SUCCESS')
        {

        }
    });

Printing Images

You can also print images using the printImageFromFile method (as long as your printer supports images). Say for example, you had included an image called myImage.jpg in the public folder of your application. You can use the RhoFile.join helper function and Application.publicFolder property to create a fully qualified path to the myImage.jpg file. This file path is passed to the printImageFromFile method:

var imagefile = Rho.RhoFile.join(Rho.Application.publicFolder, 'myImage.jpg');

//assuming you made an instance and connected per the previous instructions
myPrinter.printImageFromFile(imagefile,0,0,{},function(e){

    // e = PRINTER_STATUS... CONSTANT String
    if(e == 'PRINTER_STATUS_SUCCESS')
        {

        }
    });

The callback will be a PRINTER_STATUS constant string indicating if the operation was successful or not.

If the image resolution is large (e.g. 1024x768) this method may take a long time to execute. It is not guaranteed that files larger than 1024x1024 could be printed correctly. You should also consult the manufacturers' documentation on image support for your printer. The image may need to be of a certain size and color depth before sending to the printer.

Storing Images

Some Zebra printers support storing images. You can accomplish this by creating your own ZPL or CPL command set, or use the storeImage method

//location of image on device
var imagefile = Rho.RhoFile.join(Rho.Application.publicFolder, 'myImage.jpg');

//destination of image on the printer. Must have partion specified
var destination = "E:LOGO.GRF"

//assuming you made an instance and connected per the previous instructions
myPrinter.storeImageFromFile(destination,imagefile,0,0,{},function(e){

    // e = PRINTER_STATUS... CONSTANT String
    if(e == 'PRINTER_STATUS_SUCCESS')
        {

        }
    });

Disconnecting

Be sure to disconnect from the printer when not in use. This is especially true for BoueTooth connections. To do this you will use the disconnect method

//assumes you already created an instance object from previous instructions
myPrinter.disconnect();

Platform Notes

Windows Mobile / Windows CE

Requirements

Windows Mobile/CE require that a provided printing-service application is installed and always running in order to use the Printing API or PrintingZebra API.

  • Before installing the printing service on Windows Mobile devices, you first need to install the .NET compact framework on your device. You may find the device installation package on your build machine at C:\Program Files (x86)\Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE\NETCFv35.wm.armv4i.cab
  • Windows CE only – You’ll need to also install the messaging framework found on your build machine at C:\Program Files (x86)\Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE\Diagnostics\NETCFv35.Messages.EN.cab on Windows 7.

Printing-Service Installation

  • The .cab file for the printing service is held inside the printing-service folder inside your RhoMobile Suite installation directory located at C:\<path to your rhomobile suite installation>\printing-service\PrintingService.cab

Limitations

  • Currently, the printing service only works with one client at a time but, this will be changed in RE 5.0 to include a multi-client mode.
  • The method Printer.requestState() does not work with bluetooth printers.
  • The method Printer.stopSearch() currently does not work.
Back to Top