One very common request I see from our developers is the ability to develop applications for Zebra mobile computers using an Emulator. No emulator images are available for any of our devices but instead developers are advised to code against real hardware - Zebra does have programs for our partners where demo units are available but emulator support remains a common request.
But... Developers using DataWedge for data capture CAN use an emulator for pretty much all of their development and testing cycle. This post will walk through how this can be done.
Note that only applications which depend on DataWedge can be tested on an emulator, applications using EMDK still require to be developed and tested on a real device.
DataWedge works by sending barcode data to the application as either an Intent or by emulating key events, this approach will use adb shell commands to simulate the data that DataWedge will send on a real device when barcodes are scanned.
Simulating DataWedge Keystrokes
The DataWedge Keystroke output plugin is documented on techdocs, please refer to the official documentation for more information on any of the concepts discussed here.
To simulate a barcode string, use the following command:
adb shell input text <barcode data>
adb shell input text 1234567890
Will simulate scanning a barcode with data “1234567890”
Basic Data Formatting
There are some common formatting operations you can perform on the barcode data before it is sent to the application, known as Basic Data Formatting or BDF.
To emulate the BDF for “Send TAB key” or “Send ENTER key” you can send the specific key event using:
adb shell input keyevent <keycode>
For Send TAB key this would be
adb shell input keyevent 61
For Send ENTER key this would be
adb shell input keyevent 66
Simulating DataWedge Intents
The DataWedge Intent output plugin is documented on techdocs, please refer to the official documentation for more information on any of the concepts discussed here.
To test these commands you can use the “DataWedge API Exerciser” sample which will display received, simulated scans at the top of its UI.
The format of the adb command you need to send is, at a minimum:
adb shell am <start mechanism> -a <activity> -e <extra> (-e <extra>)
For the DataWedge API Exerciser you can send the following to simulate scanning a barcode with value 9781846683817:
adb shell am startservice -a com.zebra.dwapiexerciser.ACTION
-e com.symbol.datawedge.data_string 9781846683817
-e com.symbol.datawedge.source scanner
-e com.symbol.datawedge.label_type LABEL_TYPE_EAN13
The full list of parameters is given below (see techdocs for more information on any of these including possible values):
|DataWedge Intent attribute||How to specify using adb|
am followed by:
-a <action> e.g:
-a com.zebra.dwapiexerciser.ACTION but this will depend on your particular application
-c <category> e.g:
String representation of the scanned barcode e.g:-e com.symbol.datawedge_data_string 0123456798
The source of the incoming data e.g:-e com.symbol.datawedge.source scanner
The symbology of the decoded barcode e.g:-e com.symbol.datawedge.label_type LABEL-TYPE-EAN13
|com.symbol.datawedge.decode_data||Not a supported type, see ‘Note on unsupported types', below.|
Whether this was a single or multiple barcode decode e.g:-e com.symbol.datawedge.decoded_mode single_decode
In the case of multiple barcode decodes, how the decode took place e.g:-e com.symbol.datawedge.smart_decode_type udi
The UDI type of the decoded data e.g.-e com.symbol.datawedge.label_id UDI_GS1
|com.symbol.datawedge.barcodes||Not a supported type, see ‘Note on unsupported types', below.|
|com.symbol.datawedge.tokenized_data||Not a supported type, see ‘Note on unsupported types', below.|
|Receiver foreground flag||-f 268435456|
Note on unsupported types
Only those types supported by adb as defined in the IntentSpec are able to be sent. Some of the types sent by DataWedge are not supported by adb and therefore cannot be simulated, for example the Java code to decode the com.symbol.datawedge.decode_data is as follows:
ArrayList<byte> rawData =
(ArrayList <byte>) initiatingIntent.getSerializableExtra("com.symbol.datawedge.decode_data");
if (rawData != null)
byte rawBytes = rawData.get(0);
for (int i = 0; i < rawBytes.length; i++)
Log.d(LOG_TAG, i + ": " + rawBytes[i]);
The data is wrapped in an ArrayList<byte> structure. There is no way for us to define such a structure using adb. The closest the IntentSpec comes is to allow us to define an array of integers, --eia extra_key extra_int_value[,extra_int_value…] but obviously int is not ArrayList<byte>.
A full example of a broadcast intent sent by DataWedge destined for the DataWedge API Exerciser might look as follows:
adb shell am broadcast -a com.zebra.dwapiexerciser.ACTION
-e com.symbol.datawedge.data_string 0123456789
-e com.symbol.datawedge.source scanner
-e com.symbol.datawedge.label_type LABEL-TYPE-EAN13
-e com.symbol.datawedge.decoded_mode single_decode
If you interrogate all the extras present in the received Intent from DataWedge you will notice some which have not been mentioned here, for example com.motorolasolutions.emdk.datawedge.data_string, these are provided for backwards compatibility with older applications on legacy devices and therefore have not been discussed here.