Integrating DataWedge into your Cordova application

Update - March 2018

This blog received an overhaul in March 2018 to update the APIs being used and rework the demo application to provide more up to date functionality.

DataWedge Intent Interface

DataWedge is a value-add of all Zebra Technologies devices (formally Symbol and Motorola Solutions) that allows barcode capture and configuration without the need to write any code.  This application will demonstrate how to use Android intents to add DataWedge scanning functionality to your application

Quick Start - Getting the demo running

This application will demonstrate how to scan barcodes and control Datawedge from a Cordova based application. 

>git clone https://github.com/darryncampbell/DataWedgeCordova.git

>cd DataWedgeCordova

>cordova platform add android

Plug in Zebra device Follow instructions under "Configuring Datawedge" (below)

>cordova run android --device

Scan a barcode

If your device supports Datawedge 6.3 or below you will need to complete additional setup, see the Configuring Datawedge section.

Bootstrapping

This section walks through the steps to create a new Cordova based application that utilises DataWedge for scanning.

Create a cordova application that will run on Android

cordova create DataWedgeCordova com.mycompany.datawedgecordova DataWedgeCordova

cordova platform add android

We will use a 3rd party plugin to handle sending and receiving Intents to the DataWedge service.  Any plugin capable of sending or receiving generic intents and interpreting the extra bundle into JSON will work:

cordova plugin add https://github.com/darryncampbell/darryncampbell-cordova-plugin-intent.git

Note that a previous version of this blog used different 3rd party plugins which have since been deprecated.  I wrote my own generic plugin to handle intents and released it under MIT to aid customers who wish to integrate DataWedge and Cordova but this should not be considered supported software by Zebra Technologies.

Configuring Datawedge

If your device is running Datawedge 6.4 or higher and you just want to run the demo application you can safely skip this section as the demo app will configure the Datawedge profile automatically.

DataWedge can be configured to send intents whenever it scans barcodes, there are more sophisticated ways to configure DataWedge but this section will cover the basics.  More detailed help is available at the official documentation​ .

  • Create a new DataWedge profile (Applications --> DataWedge --> Menu --> New Profile).  This will be the profile that will be active when our Cordova application is in the foreground.  Give it a name e.g. DataWedgeCordova and click into it to configure.
  • The next step requires our Cordova application to have previously run on the device so if you have not already done so:
  • cordova run android
  • Back in DataWedge configuration associate the Cordova application with our DW profile

associate_app.png

  • Scroll down to the Intent Output section of DW configuration and enable intents:
    • Intent Action: com.zebra.cordovademo.ACTION (Note: This action changed with the update to this blog in March 2018)
    • Intent Category: leave blank
    • Intent delivery: Broadcast intent

intent_output_settings.png

Adding code to the Cordova application

Some example code from the demo application

Listening for intents

Since in the previous section DataWedge was configured to send barcode data to our application via an implicit broadcast intent we can use the 3rd party plugin to register a broadcast receiver:

window.plugins.intentShim.registerBroadcastReceiver({

  filterActions: [

    'com.zebra.cordovademo.ACTION', //  Scans

    'com.symbol.datawedge.api.RESULT_ACTION' //  Messages from service

  ],

  filterCategories: [

    'com.android.intent.category.DEFAULT'

  ]

},

function(intent) {

  //  Broadcast received

  console.log('Received Intent: ' + JSON.stringify(intent.extras));

  if (intent.extras["com.symbol.datawedge.data_string"] != null)

  {

    console.log("Scan: " + intent.extras["com.symbol.datawedge.data_string"]);

  }

});

Sending intents

DataWedge supports an intent based API documented here. The API supports many functions, code is shown here to initiate a scan without pressing the hardware key but the full demo also shows modifying the enabled decoders and retrieving Datawedge state:

To simulate a trigger press:

window.plugins.intentShim.sendBroadcast(

    {

       action: 'com.symbol.datawedge.api.ACTION',

       extras: {  

         'com.symbol.datawedge.api.SOFT_SCAN_TRIGGER': 'TOGGLE_SCANNING'   }

    },

    function() {},    

    function() {}

);

Now deploy & launch your app.  You are able to scan barcodes and exercise the functionality:

The demo application is available from github: GitHub - darryncampbell/DataWedgeCordova: Cordova application using DataWedge solely through Intents

application01.png

Feedback

This technique for adding scanning capabilities to a Cordova application represents the most generic possible solution.  We appreciate your developer feedback:

  • Would you prefer a dedicated Cordova plugin for Javascript?
  • Would you like to access EMDK profile functionality through Cordova?
  • Would you rather a dedicated Javascript interface as opposed to relying on third party plugins?
  • Are you interested in JavaScript development outside of Cordova e.g. ReactNative or NativeScript for your Enterprise application

Please feel free to raise github issues on the repository or post comments to this blog.

Sven Kueter
  • Would you prefer a dedicated Cordova plugin for Javascript?

          Yes

  • Would you like to access EMDK profile functionality through Cordova?

          ​Yes


Adonis Nahuel

I've been trying to solve this problem for 2 days but I still can not, I have version 6.2.23 of DataWedge on a Zebra TC 70x device, I do not achieve the expected result, I'm doing everything possible


Aaron Berk

Darryn, thank you for your reply!  I am following the readme, but I still don't see data on the UI.  A couple of questions, though.  One obvious, one not so obvious...

Where it says:

Associate the profile with com.zebra.zebracordovademo with * Activities (Note: You need to have previously run the application on the device to complete this step).

Should that be:

com.zebra.datawedgecordova (which is the only com.zebra* in the list so I'm assuming the latter is correct)

Simarlarly where it says:

Configure the intent output plugin to send broadcast intents to com.zebra.cordovademo.ACTION (Note: the action changed with the update made in March 2018).

Should that be:

com.zebra.datawedgecordova.ACTION (not so obvious, but I don't see a com.zebra.cordovademo in the code).

I have done both, but still no data in the UI.  I'm messing around with a couple other plug-ins that I've found around.  I'll post any successes I may have with those.

Thank you!


Adonis Nahuel

Although it seems logical, I was doing several tests in my application with the bar reader, make the profile settings and the steps mentioned above, until I got to the point of obtaining data through the reader, I realized that by selecting the input ( give a touch) then I used the reader and automatically filled the selected input, for my part I am all "Ok" thank you very much Darryn Campbell


Aaron Berk

I am trying this on a TC70. I am following but it is not working for me.  It has DataWedge 6.2.24.  I've added the profile, but the app keep telling me to set up a profile on 6.3 and prior.  I'm trying to get scanning working from a reactjs build into Cordova and figured this would be a good start.  I'm kind of a newbie to Android / ReactJS / Cordova...a triple whammy, so any suggestions are welcome! 


Anonymous (not verified)

Hi Aaron, If the device only has DataWedge 6.2 then the application has no way of knowing which version of DataWedge is present because the GetVersion API was only introduced in DW 6.3 (I guess I could have done something to make that more intuitive, such as removing the warning when a scan is received).  If you are following the steps in the ReadMe file to configure the profile then you should see scanned data on your UI when you scan a barcode - if you see scanned data then the app is working, if not then there is probably some setup issue with DataWedge and please ensure you are following all the steps in the ReadMe.


Anonymous (not verified)

I will fix that the application package and action over the next few days (the screenshots are accurate). You should be able to import the following profile which is known to work in the mean time: https://github.com/darryncampbell/DataWedgeCordova/releases/download/v0.0/dwprofile_ZebraCordovaDemo.zip


Aaron Berk

Unfortunately, I tried importing the profile and now I am getting "Unfortunately, DataWedge has stopped." and I can't get it to go away.  I'm not sure how to fix that aside from restoring the phone.  Any suggestions? Otherwise, I'll go that route.


Ian Simpson

Hello Mr. Campbell,

I've been able to use the approach you describe above to successfully receive scan intents from the wedge and also trigger a soft scan from my Ionic-Cordova app. However, I am not able to receive an intents from the core DataWedge API. Some of the one-way calls appear to work (I was able to send an 'ENABLE_DATAWEDGE' command to turn on the DW after I manually turned it off) but I'm receiving no intents from the API. This is what I'm trying to run:

     //Communication from DataWedge
     window.plugins.intentShim.registerBroadcastReceiver(
       { 
           filterActions: [
               'com.symbol.datawedge.api.RESULT_ACTION',
               'com.zebrascan.ACTION'
           ],
           filterCategories: [ 
               'com.android.intent.category.DEFAULT' 
           ]
       }, 
      
       function(intent) {
           alert(JSON.stringify(intent));

          //Scan result
           if (intent.extras['com.symbol.datawedge.data_string'] != null) { 
               $rootScope.$broadcast('zebraScan', {code: intent.extras['com.symbol.datawedge.data_string']});
           }

          //API version
           else if(intent.extras['com.symbol.datawedge.api.RESULT_GET_VERSION_INFO'] != null) {
               $rootScope.$broadcast('dwVersion', intent.extras['com.symbol.datawedge.api.RESULT_GET_VERSION_INFO']);
           }
       }
     );

    //Get DW version
     window.plugins.intentShim.sendBroadcast(
       {
         action: 'com.symbol.datawedge.api.ACTION', 
         extras: { 'com.symbol.datawedge.api.GET_VERSION_INFO': '' }
       },
       function() { console.log('Getting Version Info!'); },
       function() { alert ('Failed to get version info!'); }
     );

This works fine if I'm receiving the scan intents (from a real button press or soft trigger), but I can't get anything else from the API. My end goal is to programmatically load a profile into the DataWedge based on the DataWedge version number (in case profiles become incompatible over DataWedge versions). The profile will simply enable outputs via intent by broadcast with a simple intent name. Aside from this command, I was also trying the IMPORT_PROFILE intent, but I didn't get anything back from that either, even though the file was where it needed to be and I could import it manually from the location specified in the intent.

This is DataWedge version 6.8.50 running on an MC3300. I'm running Cordova 8.1.2 and it is an Ionic v1 app with v4.12.0 of the CLI installed.


Anonymous (not verified)

Hi Ian,

There are two types of returns and I'm not sure which one(s) you are referring to, it may be both...

- Returns from calls like GET_VERSION_INFO where you expect to receive version info back.  This is actually used in the demo app to populate the "DataWedge version" field so you should see that field populated without having to make any changes to the demo app.

- Return values from calls that support returns (like IMPORT_CONFIG) as detailed at Intent Result Codes - Zebra Technologies TechDocs .  In this case you need to specify SEND_RESULT as part of the intent extras which is missing from your code sample, above.

For your use case, rather than trying to import profiles it may be easier to create the profile from within the app (as the sample does)?  Just a thought.


Ian Simpson

Thanks for the pointers. After reading some of the API documentation more carefully I noticed that the category filter for core API stuff is

android.intent.category.DEFAULT

So it lacks the com. prefix. After adding this to the filterCategories array I can now receive responses from the API:

window.plugins.intentShim.registerBroadcastReceiver(

  {

    filterActions: [

      'com.symbol.datawedge.api.RESULT_ACTION',

      'com.zebrascan.ACTION'

    ],

    filterCategories: [

      'com.android.intent.category.DEFAULT',

      'android.intent.category.DEFAULT'

    ]

  },

  function(intent) {

    console.log(JSON.stringify(intent));

  }

);

I was also missing the SEND_RESULT and COMMAND_IDENTIFIER extras, which are both required for responses. So sending an intent with optional output correctly looks like this:

window.plugins.intentShim.sendBroadcast(

  { action: 'com.symbol.datawedge.api.ACTION'

    extras: { 'com.symbol.datawedge.api.IMPORT_CONFIG': { 'FOLDER_PATH': 'path'},

             'SEND_RESULT': 'true',

             'COMMAND_IDENTIFIER': 'CfgImport' }

  },

  function() { console.log('Importing Config!'); },

  function() { alert ('Failed to import DataWedge Configuration!'); }

);

For our application, it might be more desirable to load profiles from files instead of specifying them with the API, because this would make it possible to handle API profile/config format changes without


Ian Simpson

I meant to finish that last sentence by saying "without code changes", but I'm thinking now SET_CONFIG is the way to go, because we can just use JSON files on our dev server without dealing with the details of the Android file system.


Rafael Domingues

Hey Darryn,

Can you help me?

It is possible to create a PWA and access the datawedge of the TC 51 / TC 56 using the side buttons to scan without the need to install an APK.

Just only via browser in Chrome of android?

I am trying to access via android chrome and it does not detect the datawedge

Tks


Anonymous (not verified)

Hi Rafael, you would need to use DataWedge keystroke output and capture the input in a form within your PWA.  You would not be able to use Android Intents.


Brendan Farthing

Hi Darryn,

We're new to Zebra at our company and I have one general question related to Cordova which I think may be more closely related to your feedback questions.

Is it possible to have a Cordova app call an API to use the built-in device scanner (e.g. on a TC56) but without having to use the DataWedge? Kind of like how Enterprise Browser can call the Barcode API directly without DataWedge?

Assume that may need a dedicated JavaScript Plugin for Cordova? If so, I second a vote for you guys to create a Cordova JS plug-in (for in-built hardware scanning without DataWedge in this case).

A bit of background, I'm coming from a SAP Cloud Fiori Client Developer perspective as we will be rolling out Fiori apps to our TC65's globally and want to use the native laser scanning as tightly and efficiently as possible. We would build custom SAP Fiori Client (Cordova) APK's and like to include a Cordova plug-in to get access to the scanner hardware within our apps. It would be really nice to have an officially supported Cordova plug-in for this (you know how it is in large Enterprise, we want supported stuff due to this probably running on hundreds and potentially thousands of TC65's within our company). We don't really want to use Enterprise Browser as Android Fiori Client (Cordova) is much nicer under the SAP Fiori apps scenario and includes some SAP specific optimisations.

Thanks for a great blog.

Brendan...


Anonymous (not verified)

Hi Brendan,

It would be possible to use the built-in device scanner without DataWedge but it does need a dedicated Cordova Plugin to achieve that.  Nearly 4 years ago I did do a proof of concept for such a plugin but this was abandoned for several reasons including issues running on M+ - it was released under MIT so you are welcome to use any of the code: GitHub - darryncampbell/EnterpriseBarcodePoC: Enterprise Browser Proof of Concept .  It was however never supported.

Thank you for the feedback that you would like an officially supported Cordova plug-in & we'll take it on board however I'll be honest that the company has made a strategic investment in improving Enterprise Browser to be the platform of choice for SAP Fiori apps.  I strongly suspect the team would rather improve Enterprise Browser to make it more appealing to SAP Fiori users and I'll pass your feedback along to that team.

Probably not the answer(s) you were looking for but I hope that helps.

Darryn.


Brendan Farthing

Hi Darryn,

Thanks for the detailed reply. Yes, not the answer I was hoping for but I do understand Zebra's reasons and focus on Enterprise Browser. Being supported is of course of high importance to us. I am already trialing Enterprise Browser with our Fiori apps and will discuss this further internally within our organization to decide our path forward.

Regards,

Brendan