RhoMobile Suite 5.3 permits printing via Bluetooth and Wi-Fi from mobile devices running Android, iOS and Windows Mobile/CE. New in version 5.3 is the ability to print via USB to Windows Mobile/CE devices, building on similar support for Android devices introduced in 5.1.
To facilite USB printing, the RhoMobile printing API now includes the CONNECTION_TYPE_USB
parameter. The API is otherwise unchanged, and operates in the same way as in prior editions. To print via USB, the Zebra device must be connected with a USB “On-The-Go” (OTG) cable or adapter to one of Zebra’s supported printers. Android and Windows Mobile/CE printing is supported via direct USB OTG connection or through a cradle with OTG adapter. Windows Mobile/CE devices also must be in ‘Host Mode,’ which is found under USB Config in the Settings panel.
This guide is designed to provide an overview of the steps necessary to enable printing in a RhoMobile application. Where appropriate, it contains links to details for the calls, methods, parameters, constants and other specifics necessary to build your application using the Zebra printing APIs.
The RhoMobile APIs provide two APIs for printing. The Printing API is a parent class that defines common class attributes that specific printer-type APIs will inherit. The PrintingZebra API is the printer-type API for Zebra printers.
To enable printing in your application, your build.yml
must include both of these extensions.
Example build.yml
command:
... extensions: ["printing","printing_zebra",...] ...
Before your app can print, it must first discover and connect to a printer. There are a few ways to discover printers, but all use the searchPrinters method.
Printing via Bluetooth is supported for Android, iOS and Windows Mobile apps. During Bluetooth discovery, the printer must be set to “discoverable.” The following JavaScript code looks for any Zebra printers discoverable via Bluetooth by specifying the connectionType
and printerType
in the options
parameter:
Sample JavaScript code:
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); } });
TIP: To minimize search time, code should provide as many search parameters as possible. |
The Bluetooth MAC address consists of six groups of two hexadecimal digits separated by colons. If a printer’s Bluetooth MAC address is known, it can be specified as a deviceAddress
using the options
parameter:
Sample JavaScript code:
:::javascript
Rho.PrinterZebra.searchPrinters({
connectionType:Rho.Printer.CONNECTION_TYPE_BLUETOOTH,
deviceAddress: ‘00:03:7A:4C:F2:DB’
…
When pairing with a Bluetooth device for the first time, a prompt might appear for a pairing PIN. Commonly used PINs: 0000, 1111 and 1234. Check the printer manufacturer's specifications. |
Printing via Wi-Fi is supported for Android, iOS and Windows Mobile apps. For Wi-Fi printer searching, the deviceAddress
and devicePort
parameters can be used to quickly identify known devices:
Sample JavaScript code:
:::javascript
Rho.Printer.searchPrinters({
connectionType:Rho.Printer.CONNECTION_TYPE_TCP,
deviceAddress: ‘192.168.1.121’,
devicePort: 6101
…
When attepting to connect via Bluetooth or Wi-Fi, be sure the device's corresponding radio is turned on. If using Bluetooth, the printer should be set to "discoverable." |
Printing via USB is supported on Android and Windows Mobile/CE devices. To print from a Zebra enterprise mobile computer, it must be connected to one of Zebra’s supported printers using an OTG cable or adapter. Windows Mobile/CE devices also must be in ‘Host Mode,’ which is found under USB Config in the Settings panel.
Sample JavaScript code:
var printers = []; Rho.Printer.searchPrinters({ connectionType:Rho.Printer.CONNECTION_TYPE_USB, 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); } });
Use the search.Printers
method and the connecionType as CONNECTION_TYPE_USB
parameter to search for printer(s) connected to the mobile device via USB. This parameter is new in RMS 5.1.
A USB On-the-Go (OTG) cable or adapter permits a mobile device to act as ‘host’ to client peripherals such as flash drives, keyboards and printers.
Some Zebra TC7X single/dual slot cradles present a USB micro “AB” receptacle that allows the TC7X to act as host or client depending on the cable.
The Zebra OTG implementation lacks Session Request Protocol (SRP) and Host Negotiation Protocol (HNP), portions of the spec that allow connected devices to control power consumption and switch dynamically between host and client modes.
Printing via USB from a cradled device is possible by inserting an OTG micro A connector to the cradle and connecting the USB-B (or mini-B) end to the printer.
OTG supports direct USB connections only; the use of USB hubs is not supported by the OTG spec.
The script in STEP 2 executes the callback function of the searchPrinters method, which returns a unique printerID property for each printer found. This ID will be used to establish a connection with the desired printer. After the last printer is found, an additional callback will be triggered and will contain no printerID, signaling the end of search and that it’s safe to connect to a printer.
This `printerID` is a unique identifier that is tracked by the RhoMobile framework. It has no relation to ID numbers that a printer manufacturer might be using. |
At this time there should be one or more printerID
values in the printers
array variable. To access one, create an instance of the Printer class by calling the getPrinterByID method and passing a printerID
as a string to the vairable myPrinter
:
Sample JavaScript code: :::javascript // 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 you’ve instantiated a specific printer, your app can connect to it using the connect method:
Sample JavaScript code: :::javascript 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. For example:
You can also check information about the printer using the requestState method, which returns the information in a callback object. The first parameter of this method is an array that lists the items to find. These are PRINTER_STATE… constants. For example:
Sample JavaScript code:
// Assumes you have created the instance 'myPrinter' // from previous methods described above 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); });
Before sending commands to the printer, you must be aware of which printer languages are supported. For Zebra printers these might include ZPL, CPCL and EPS. To retrieve a list of supported languages, use the enumerateSupportedControlLanguages method.
The callback will be an array of PRINTER_LANGUAGE… constants. For example:
Sample JavaScript code: :::javascript //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 });
WARNING: Ruby is NOT supported with the CPCL printer language. |
Once your app finds and connects to a printer, it can begin sending commands. Printer behavior will vary depending on printer make, model and its current state. Consult your printer’s technical documentation for printer-specific commands and syntax.
In general, there are two fundamental ways to send commands:
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 line mode to ZPL mode myPrinter.printRawString('! U1 setvar "device.languages" "ZPL"\r\n');
When a series of commands is used repeatedly by an app, they can be stored in a file (i.e. ZPL, CPCL) and modified programatically to perform a task, for example to print an address label. Command files can be generated manually or made using a tool provided by Zebra. They can be created in advance and delivered with the application.
For example, let’s say we created a file called address.cpcl
that’s stored in the application’s public
folder. This file will contain CPCL commands that will be used to print an address, and might look something like the one below.
Sample terminal script file with embedded CPCL commands: :::term ! 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 the Application.publicFolder property to create a fully qualified path to the address.cpcl
file. This file path would then be passed to the sendFileContents method:
Sample JavaScript code: :::javascript 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 });
Whenever your app is finished printing, it’s important to disconnect from the printer. This is especially important for Bluetooth connections. To disconnect, use the disconnect method:
//assumes you already created an instance object from previous instructions myPrinter.disconnect();
Some printers have the ability to store command-file templates or other files useful for performaing print operations. To retrieve a list of files that exist on the printer, use the retrieveFileNames method:
Sample JavaScript code: :::javascript myPrinter.retrieveFileNames(function (e){ // e.status : PRINTER_STATUS_SUCCESS, PRINTER_STATUS_ERROR // e.fileNames : ARRAY of file names // });
Once the file names are known, your app can print to them, passing variables as specified within the ZPL or CPCL files themselves. This is done using either the printStoredFormatWithArray method or the printStoredFormatWithHash method. Both include three parameters:
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 printer’s ‘E’ partition)
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
Sample JavaScript code: :::javascript myPrinter.printStoredFormatWithArray(‘E:LABEL.ZPL’,[‘John Doe’,‘123 East Main St’,‘Smalltown, NY 11766’],function (e){ // Will return a PRINTER_STATUS… CONSTANT String });
printStoredFormatWithHash
(supported by ZPL only) - A 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.
Sample JavaScript code: :::javascript 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') { } });
This will return a PRINTER_STATUS… constant as a string.
For printers with graphics support, images are printed using the printImageFromFile method. For example, an image called myImage.jpg
in your application’s public
folder could use the same RhoFile.join helper function and Application.publicFolder property described above to create a fully qualified path to the myImage.jpg
file. The file could then be passed to the printImageFromFile method:
Sample JavaScript code: :::javascript 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') { } });
A callback for the PRINTER_STATUS constant would return a string indicating whether the operation was successful.
Images larger than 1024x768 might take a long time or print incorrectly. Consult the printer manufacturer's documentation for image printing parameters. |
Some Zebra printers support the storage of images. You can accomplish this by creating your own ZPL or CPL command set, or use the storeImage method:
Sample JavaScript code: :::javascript //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') { } });
Windows Mobile/CE require that a provided printing-service
application is installed and always running in order to use the Printing and PrintingZebra APIs.
C:\Program Files (x86)\Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE\NETCFv35.wm.armv4i.cab
C:\Program Files (x86)\Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE\Diagnostics\NETCFv35.Messages.EN.cab
on Windows 7.printing-service
folder inside your RhoMobile Suite installation directory located at C:\<path to your rhomobile suite installation>\printing-service\PrintingService.cab
Printer.requestState()
does not work with Bluetooth printers.Printer.stopSearch()
currently does not work.
Device | Device model(s) | Operating System(s) | |
---|---|---|---|
MZ | MZ 220, MZ 320 | Android, Mac OS X, Windows Mobile, CE, x86 | |
iMZ | iMZ 220, iMZ 320 | Android, Mac OS X, Windows Mobile, CE, x86 | |
RW | RW 220, RW 420, RW 420 Print Station | Android, Mac OS X, Windows Mobile, CE, x86 | |
P4T | P4T, RP4T Passive RFID Printer | Android, Mac OS X, Windows Mobile, CE, x86 | |
ZD500R | ZD500R RFID Printer | Android, Mac OS X, Windows Mobile, CE, x86 |
|
|