This tutorial will take you through scanning barcode data via Android Intents using DataWedge on Zebra devices with a Xamarin application.

Be aware that there is a dedicated Xamarin component for Zebra mobile devices providing API access through an SDK but the DataWedge service is sufficient for most applications and is simpler to use to get barcode data into your app.  This tutorial describes using DataWedge, not the Nuget package.

DataWedge configuration

The first step is to configure the DataWedge service with an INPUT (the barcode scanner) and an OUTPUT (send an Intent)

Launch the DataWedge application on the device, there is no need to install anything as it comes pre-installed on all Zebra Android mobile devices.

Select the profile which will be associated with your application, unless you configure a separate profile then DataWedge will use “Profile0 (default)”

Ensure:

  • The profile is enabled
  • Barcode input is enabled
  • Intent output is enabled
  • All other inputs and outputs can be disabled.

 

Configure the Intent Output as follows (as shown in the screenshot below):

  • Intent action: This is an implicit intent that will be sent by DataWedge, it is up to your application to ensure it is configured to receive this intent.  For the purposes of this tutorial, specify com.dwexample.ACTION.
  • Intent category: The category that is associated with the intent sent by DataWedge following each scan.  Leave this blank for this tutorial.
  • Intent delivery, One of

For the tutorial, your Intent output should match the screenshot below.

datawedge_settings.png

The application

Moving over to the application now, there are several key parts to ensure we are able to receive the intent data that DataWedge is sending.

First, we can pre-define some of the strings to make it easier to receive and extract the scanned data.  The intent’s action is defined as “com.dwexample.ACTION” and once we receive an intent it will contain extras representing the scanned data for source, type and data as listed in the official docs.

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="app_name">Datawedge Intent Example 3</string>
  <string name="activity_intent_filter_action">
        com.dwexample.ACTION</string>
  <string name="datawedge_intent_key_source">
        com.symbol.datawedge.source</string>
  <string name="datawedge_intent_key_label_type">
        com.symbol.datawedge.label_type</string>
  <string name="datawedge_intent_key_data">
        com.symbol.datawedge.data_string</string>
</resources>

 

Because we configured DataWedge to send a broadcast intent our application must now register a broadcast receiver.

 

Obviously if we had configured DW to start an activity we could register for that in our manifest and call getIntent() in onCreate() or if we had configured it as start service we could create a service to receive the intent.

 

For this example we will register a dynamic broadcast receiver in the onCreate() call of our application.  If you were doing this in a production application you would more likely register / unregister in the onResume() / onPause() methods.

 

Note that the action we are filtering on matches the action that we configured the DataWedge service to send, com.dwexample.ACTION.

 

protected override void OnResume()
{
    base.OnResume();
    //  Register the broadcast receiver dynamically
    RegisterReceiver(receiver, 
        new IntentFilter(Resources.GetString(
        Resource.String.activity_intent_filter_action)));
}

 

Having registered a broadcast receiver we had better define one.  You could do this in a separate class but for this tutorial I will just define a receiver within the MainActivity.cs

 

//  Broadcast receiver to receive our scanned data from Datawedge
[BroadcastReceiver(Enabled = true)]
public class myBroadcastReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        String action = intent.Action;
        if (action.Equals(MainActivity.Instance.Resources.GetString(
            Resource.String.activity_intent_filter_action)))
        {
            //  A barcode has been scanned
            MainActivity.Instance.RunOnUiThread(() => 
                MainActivity.Instance.DisplayResult(intent));
        }
    }
}

 

Plumb together the broadcast receiver and the main activity in the onCreate() method using an instance variable

 

//  Instance used to communicate from broadcast receiver back to main activity
public static MainActivity Instance;
myBroadcastReceiver receiver;
protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    MainActivity.Instance = this;
    receiver = new myBroadcastReceiver();
    // Set our view from the "main" layout resource
    SetContentView(Resource.Layout.Main);
}

 

The logic of extracting the scanned data and displaying it on the screen is handled by its own method.  Note that the extra keys were defined earlier in the strings.xml file.  The below code assumes a UI exists in which to place the data but a production application will be driving a lot of its business logic following a scan.

 

public void DisplayResult(Intent intent)
{
    //  Output the scanned barcode on the screen.  Bear in mind older JB devices will use the legacy DW parameters on unbranded devices.
    String decodedSource = intent.GetStringExtra(Resources.GetString(
        Resource.String.datawedge_intent_key_source));
    String decodedData = intent.GetStringExtra(Resources.GetString(
        Resource.String.datawedge_intent_key_data));
    String decodedLabelType = intent.GetStringExtra(Resources.GetString(
        Resource.String.datawedge_intent_key_label_type));
    TextView scanSourceTxt = FindViewById<TextView>
        (Resource.Id.txtScanScource);
    TextView scanDataTxt = FindViewById<TextView>
        (Resource.Id.txtScanData);
    TextView scanLabelTypeTxt = FindViewById<TextView>
        (Resource.Id.txtScanDecoder);
    scanSourceTxt.Text = "Scan Source: " + decodedSource;
    scanDataTxt.Text = "Scan Data: " + decodedData;
    scanLabelTypeTxt.Text = "Scan Decoder: " + decodedLabelType;
}

 

Those are all of the key points to receive scanned data via intent, the flexibility of both Android and DataWedge allow for many other possible configurations for receiving data but the above should be a good jumping off point.

There is a sample application that accompanies this tutorial and shows all the code, available on github

2.png