Scan with DataWedge Using Explicit Broadcast Intents

DataWedge 8.0 introduced a new capability to the DataWedge Intent output plugin, the ability to specify the component of the application which will receive the Intent.

Up until version 8.0, DataWedge only allowed you to specify the action, category and delivery mechanism (Start Activity, Start Service or Send Broadcast)

For StartActivity and StartService, being able to specify the component allows you to be certain which application will receive the Intent. Before DataWedge 8.0 the system would select a single activity whose Intent filter matched the appropriate action. So, if you had two activities which had the same intent-filter action, which activity received the scan would be left to chance (similarly, if you had two services whose intent-filter specified the same action then only one service would receive the scan). For this reason, being able to specify the component makes the delivery more secure and reliable.

When configured to Send Broadcast Intents, the ability to specify the component now allows DataWedge to send explicit Intents, this has long been a customer request as it can help applications receive scans when in the background.

This project presents an alternative approach to scan barcodes in the background compared to https://developer.zebra.com/blog/datawedge-background-scanning-zebra-android-devices; that project uses a service whereas this project uses a broadcast Intent.

Android 8.0 introduced limits on how Broadcast Intents are received, which meant applications could no longer receive implicit Intents that had been declared in their manifest and had to be running in the foreground (or a foreground service) to receive implicit Intents. There are exceptions to this rule but those exceptions do not cover the type of Intents DataWedge will send.

DataWedge was previously only capable of sending implicit Intents which made upgrading to Oreo more complicated. One exception to the Android 8.0 background limits was that it did not apply to explicit Intents, therefore applications who have been written to receive their DataWedge intents via broadcast and declared in the application manifest can upgrade to Oreo without modifying their application, provided they specify a Component for the Intent.

This application has been written to demonstrate how to receive scans via Android Intents on an Android Oreo device (or higher) running DataWedge 8.0+

App

The broadcast receiver is declared in the application manifest as follows:

<receiver
  android:name=".MyReceiver"
  android:enabled="true"
  android:exported="true">
  <intent-filter>
    <action android:name="com.zebra.datawedge.scan" />
  </intent-filter>
</receiver>

And the broadcast receiver looks as follows. The scanned data is presented as a Toast:

public class MyReceiver extends BroadcastReceiver {
  @Override
  public void onReceive(final Context context, final Intent intent) {
    Handler handler = new Handler(Looper.getMainLooper());
    handler.post(new Runnable() {
      @Override
      public void run() {
        String decodedData = 
         intent.getStringExtra("com.symbol.datawedge.data_string");
        String decodedLabelType = 
         intent.getStringExtra("com.symbol.datawedge.label_type");
        Toast.makeText(context.getApplicationContext(), "" +
         decodedData + " [" + decodedLabelType + "]", Toast.LENGTH_SHORT).show();
      }
    });
  }
}

Caveats:

  • If you have previously used the DataWedge API SetDefaultProfile then this application may not appear to work because the "Profile0 (default)" settings are never applied.
  • After boot, you may need to wait a few seconds for the scanning service to fully enable. During this period, the scanner beam will not emit.
  • Do not force close the app which will receive scans in the background. It is best practice to prevent your end users from accessing the application settings, thereby preventing them from manually closing your app.

DataWedge setup

This article assumes familiarity with Zebra's DataWedge tool as well as the DataWedge profile mechanism. For an overview of DataWedge, please refer to the DataWedge Techdocs page

The aim is to have DataWedge send a broadcast intent when the application is in the background, this means we will not know the foreground application. Since we do not know the foreground application then both the default and Launcher profiles need to be modified. Typically the default profile on DataWedge is called Profile0 (default)

If you press the 'Modify Default and Launcher Profiles' button the profiles will be automatically configured for you:

  • Scanner input plugin enabled
  • Intent output plugin enabled
  • Intent output action set to 'com.zebra.datawedge.scan'
  • Intent output delivery method set to 'Broadcast intent'
  • Intent output component set to this app
  • Intent output component signature check disabled

DataWedge 1 DataWedge 2

Signature check

The DataWedge documentation gives a good explanation of why you might want to enable signature check on a production deployment but for the purposes of this demo it is easiest to leave the check disabled. For more information on generating these signatures then I wrote a guide

Running the application

After configuring DataWedge you should be able to scan barcodes regardless of the foreground application, provided that application does not have its own DataWedge profile associated with it.

Note the toast in each of the screenshots below

Scanning Scanning Scanning Scanning Scanning