DataWedge Background Scanning on Zebra Android Devices

Tags: 

DataWedge Background Scanning

The sample application to accompany this post is available on Github

Although not common, some customers targeting Zebra Android mobile computers need to be able to scan barcodes when the application is in the background or the mobile computer is in the standby state. Following a question posted on the developer forum we came up with an architecture that appeared to work reliably.

The sample application has been tested with the internal imager but the principle also applies to Bluetooth scanner. Be aware the BT scanners have other considerations such as maintaining the connection when the device goes into standby. See here for more information.

Set Wake-up Sources

In order to wake up the device from a standby mode when the trigger button is pressed, you need to set the wake-up sources. The wake-up sources can be configured using StageNow and the MX PowerManager but be aware that, at the time of writing, this capability requires the relative recent MX version 9.2+ which is not available on all devices.

If your device is in standby, you can also (of course) press the power key to wake it up, after which the scan can be captured even when the keyguard (password screen) is shown.

Approach overview

  1. Use DataWedge to start an Android service whenever a barcode is scanned. Unlike a broadcast message the receiving application does not need to be in the foreground.
  2. Listen for the scan intent in a service exported from the recipient application
  3. Process the scan in the recipient service, accounting for Oreo background restrictions.

1. Use DataWedge to start an Android service whenever a barcode is scanned.

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 start a service 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)

Modify both the default and launcher DataWedge profiles as follows: - Barcode Input Enabled - Intent Output Enabled - Intent Output action: com.zebra.backgroundscan.ACTION (this action needs to match the action we define in the application manifest for the service) - Intent delivery: Send via startService - Intent Output 'Use startForegroundService on failure' set to true. (This gives the maximum compatibility for both Oreo+ and pre-Oreo Android versions.)

Input settings:

Default Input Launcher Input

Output settings:

Default Output Launcher Output

2. Listen for the scan intent in a service exported from the application

Create an Android service in your application and modify the AndroidManifest.xml to listen for the Intent sent by DataWedge:

<service
    android:name=".ListeningService"
    android:exported="true">
    <intent-filter>
        <action android:name="com.zebra.backgroundscan.ACTION" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</service>

From the Android service, extract the received scan data. In the case of an IntentService:

@Override
protected void onHandleIntent(Intent intent) {
    if (intent.getAction().equals("com.zebra.backgroundscan.ACTION")) {
        String scanData = intent.getStringExtra("com.symbol.datawedge.data_string");
        //  process scanData
        ...
    }
}

3. Process the scan in the recipient serivce, accounting for Oreo background restrictions

On Android Oreo and above, the amount of work you can do in a background service is very limited, therefore it makes sense to promote this service to a foreground service, at least whilst the scan is being processed.

You need to declare that you are using a foregound service in the AndroidManifest.xml

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

And then promote the service to a foreground service with an accompanying notification

createNotificationChannel();
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
    0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("DataWedge Background Scanning")
.setContentText("barcode processing")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);

The sample application processes the barcode so quickly that you will not see the noticiation but doing the above will make it work reliably on Android Oreo+

Finally, actually do work to process the scan. This might be communicating with a backend or updating a database but the sample application shows a toast and does some text-to-speech.

showToast("Scanned: " + scanData);

Run the application

Install the application on a Zebra mobile device, configure DataWedge as described above and scan a barcode from any activity. You should see a toast appear and text-to-speech should read the first 3 digits of the barcode

Running 1 Running 2

Follow-on topic:

DataWedge 8.0+ introduces the ability to specify the Intent component which opens up the possibility of using an explicit broadcast Intent to invoke a background application. Look out for an additional forum post on this topic soon

Resources

Vince Hunt

I have an Android TC70x Zebra scanner using DataWedge. Using Blue Tooth I can scan bar-codes to an excel spread sheet. For inventory tracking I need to send a second value for the quantity on hand. Is it possible to enter the quantity manually and then have that value sent to the excel spread sheet followed by a line feed. Is there a way to do this by setting up a profile or will code be needed?


Darryn Campbell

It sounds like you would need to write some code.  What parts of that solution do you have today?  DataWedge does not natively support Bluetooth output so at minimum you would need code to capture the scan and send it to your PC.  You would also need some UI to capture the quantity and then send that quantity to your backend alongside the scan so it sounds like you need to write an Android app.