Zebra has an active developer community that frequently gets questions about how to develop Ionic applications for our devices. About 10 years ago, it was perfectly acceptable for mobile apps aimed at industry to be utilitarian. But with the proliferation of smartphones, user expectations are now much greater, regardless of whether the app will be used by a handful of employees in a retail store or exist solely in the warehouse, the application needs to function well and look great. It is therefore no surprise that the Ionic Framework’s ability to rapidly develop beautiful-looking and robust applications with existing tooling is a great fit for Zebra devices.

 

Of course, Zebra offers a native SDK for Android, but unless you need extremely tight integration, I would not recommend developing a native Ionic plugin. Upwards of 95 percent of applications on Zebra devices are built to scan barcodes with the device’s dedicated scanning hardware. For these use cases there is a simpler solution for Ionic integration – DataWedge, a service resident on every Zebra device that supports an intent-based interface to control and interact with the device scanner without worrying about threads, timing or pending reads.

 

In this blog, I'll take you through how to create an Ionic application for a Zebra Android device capable of scanning barcodes and controlling the scanner configuration.  The finished sample is available on the Zebra GitHub page at https://github.com/Zebra/ZebraIonicDemo.

 

The Android Intent Plugin

To interact with the DataWedge service to control the scanner we need to add an Ionic plugin capable of handling Android Intents. Ionic’s recommended web intent plugin will give us what we need, it is based on a Cordova plugin released under MIT license, so there are no issues including it in a commercial application:

 

Ionic Cordova plugin add com-darryncampbell-cordova-plugin-intent

 

The Code

With the Ionic application capable of sending and receiving Android intents, we can set up a broadcast receiver to handle both barcode scans and notifications from the DataWedge service.

 

(<any>window).plugins.intentShim.registerBroadcastReceiver({
  filterActions: [
    'com.zebra.ionicdemo.ACTION',
    'com.symbol.datawedge.api.RESULT_ACTION'
  ],
  filterCategories: [
    'android.intent.category.DEFAULT'
  ]},
  function (intent) {
    //  Broadcast received
    console.log('Received Intent: ' + JSON.stringify(intent.extras));
});

 

DataWedge needs to be configured to send intents to our broadcast receiver.  DataWedge configuration is profile-based; profiles are associated with an application or activity, and when the specified app or activity comes to the foreground the associated profile configuration is applied. There are three steps to configure DataWedge:

  1. Create a DataWedge profile
  2. Associate the created profile with the Ionic application
  3. Configure the profile to send broadcast intents when a barcode is scanned

These three steps can be done manually or, if you are running a recent version of DataWedge on your device, can be done entirely in code.

 

The manual steps (with screenshots) are detailed in the sample project’s setup instructions, but it is far more convenient for both yourself and device administrators to configure the device in code:

 

    1. Create a DataWedge profile

This is achieved with the CREATE_PROFILE API (requires DW 6.3+):
(<any>window).plugins.intentShim.sendBroadcast({
    action: 'com.symbol.datawedge.api.ACTION',
    extras: {
      "com.symbol.datawedge.api.CREATE_PROFILE": "ZebraIonicDemo"
    }
  },
  function () { },  // Success in sending the intent, not success of DW to process the intent.
  function () { }  // Failure in sending the intent, not failure of DW to process the intent.
);

   

     2. Associate the created profile with our Ionic application

This is achieved with the SET_CONFIG API (requires DW 6.4+):

 

let profileConfig = {
    "PROFILE_NAME": "ZebraIonicDemo",
    "PROFILE_ENABLED": "true",
    "CONFIG_MODE": "UPDATE",
    "PLUGIN_CONFIG": {
      "PLUGIN_NAME": "BARCODE",
      "RESET_CONFIG": "true",
      "PARAM_LIST": {}
    },
    "APP_LIST": [{
      "PACKAGE_NAME": "com.zebra.zebraionicdemo",
      "ACTIVITY_LIST": ["*"]
    }]
  };
(<any>window).plugins.intentShim.sendBroadcast({
  action: 'com.symbol.datawedge.api.ACTION',
  extras: {
    "com.symbol.datawedge.api.SET_CONFIG": profileConfig,
    "SEND_RESULT": this.requestResultCodes
  }
},
  function () { },  // Success in sending the intent, not success of DW to process the intent.
  function () { }  // Failure in sending the intent, not failure of DW to process the intent.
);

 

    3. Configure the profile to send broadcast intents when a barcode is scanned.

Again, this is achieved with the SET_CONFIG API (requires DW6.4+):

 

let profileConfig2 = {
  "PROFILE_NAME": "ZebraIonicDemo",
  "PROFILE_ENABLED": "true",
  "CONFIG_MODE": "UPDATE",
  "PLUGIN_CONFIG": {
    "PLUGIN_NAME": "INTENT",
    "RESET_CONFIG": "true",
    "PARAM_LIST": {
      "intent_output_enabled": "true",
      "intent_action": "com.zebra.ionicdemo.ACTION",
      "intent_delivery": "2" // Broadcast
    }
  }
};
(<any>window).plugins.intentShim.sendBroadcast({
  action: 'com.symbol.datawedge.api.ACTION',
  extras: {
    "com.symbol.datawedge.api.SET_CONFIG": profileConfig2,
    "SEND_RESULT": this.requestResultCodes
  }
},
  function () { },  //  Success in sending the intent, not success of DW to process the intent.
  function () { }  //  Failure in sending the intent, not failure of DW to process the intent.
);

 

Putting this all together, you now have an application that will receive barcodes from the default device scanner without having to perform any special scanner control logic or write any native code.

 

So far, we have shown the DataWedge API being used to create a profile and configure the scanner. There are far more APIs available. For example, if you wanted to switch from the default imager scanner to a connected Bluetooth scanner, you could use the SWITCH_SCANNER API (DW 6.5+)

 

(<any>window).plugins.intentShim.sendBroadcast({
  action: 'com.symbol.datawedge.api.ACTION',
  extras: {
    "com.symbol.datawedge.api.SWITCH_SCANNER": "" + 3 // Assume 3 is the index of the BT scanner returned from a call to ENUMERATE
  }
},
  function () { },  //  Success in sending the intent, not success of DW to process the intent.
  function () { }  //  Failure in sending the intent, not failure of DW to process the intent.
);

 

Demo Application

I have put together a basic demo application at https://github.com/Zebra/ZebraIonicDemo that enables you to scan barcodes, change the scanner, and configure the decoders in use.

 

The application will work on any Zebra mobile computer running Android that supports the DataWedge service. Depending on the version of DataWedge running on your device, some features might not be available to you, but all devices support scanning and capturing barcode data at a minimum. Please see the demo readme file for more information and setup.

 

Building and Running the Demo Application

  • cd ZebraIonicDemo
  • npm install
  • Connect Zebra device to adb
  • ionic cordova run android --device

Please raise any issues with the demo app in GitHub