Scan barcodes using DataWedge Intents in Xamarin Android

Overview

This guide will walk you through creating a Xamarin Android Application that will scan barcodes on a Symbol Android device using DataWedge Intents. Basically, the tutorial will use a DataWedge profile that we need to create, through which it will send the scanned barcode data to our Xamarin Android application using Intents. The user can scan barcodes using a hard scan trigger on the device, where the app would receive barcode data through DataWedge. The tutorial also allows you to scan barcodes by toggling from hard to soft scan by pressing a button specified in the app itself. Since Xamarin uses C#, we will code using C# in our Xamarin Android application.

Note: You can go through this quick start to get familiar with Xamarin Android.

Prerequisites

  • Java Development Kit (JDK)
  • Android SDK
  • Install Xamarin Android on your Mac/Windows machine using guidelines mentioned here
  • Symbol Android Device (MC40, TC70, TC55)

Note: This tutorial uses Xamarin studio for app development. You can use either Visual Studio or Xamarin Studio.

Creating The Project

  1. Launch the Xamarin Studio

    img

  2. Create a new Solution

    img

    img

  3. Select “Android” section under “C#” on the left hand side and you will see different options of creating Android Project.

    img

  4. Select “Android Application” and provide application name in the “Name” field (Ex. barcodescanner).

    img

    Note: You can set different location for the project based on your workspace.

  5. Click “OK” and the project will be created.

    img

Updating Manifest

  1. Modify the Application’s AndroidManifest.xml to receive Intents from a Profile of DataWedge application that we will be creating later.

    Initially the AndroidManifest.xml file looks like:

    img

    Remove all the existing code and add following code:

     <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="barcodescanner.barcodescanner">    <uses-sdk android:targetSdkVersion="19" android:minSdkVersion="16" />    <application android:icon="@drawable/icon" android:label="barcodescanner">     <activity android:name=".MainActivity" android:label="barcodescanner" android:launchMode="singleTask">      <intent-filter>        <action android:name="barcodescanner.RECVR" />        <category android:name="android.intent.category.DEFAULT" />      </intent-filter>     </activity>    </application> </manifest> 

    we have added the MainActivity in application tag. This MainActivity has has the Intent Filters that specifies a Receiver through which the app would receive Intent from DataWedge application for its MainActivity.

    You can also see that activity tag has an attribute android:launchMode="singleTask" that provides only one instance of the Activity, which handles all new incoming Intents.

    When done, your manifest.xml should look like:

    img

Adding Some Code

  1. Now we will start to add some code.

    First, Lets add a simple User Interface that contains a Text View as a label and  an Edit Text that will display Barcode data to the user.

    So go to Resources -> layout -> Main.axml and remove all the existing code. Add the following code to Main.axml:

     <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:minWidth="25px"    android:minHeight="25px">      <TextView        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_margin="10dip"        android:text="Barcode Data:"        android:textSize="18sp"        android:textStyle="bold" />      <EditText        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:inputType="textMultiLine"        android:id="@+id/editbox" />      <Button        android:id="@+id/btn_scan"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center_horizontal"        android:layout_margin="20dip"        android:gravity="center"        android:text="Scan" /> </LinearLayout> 

    Now, your Main.axml file should look like:

    img

  2. Once done with User Interface, we will now add some C# code in MainActivity.cs to get the scanned barcode data through DataWedge application profile using Intent and display it in the User Interface.

    So open the MainActivity.cs file that looks like:

    img

    Remove the existing code from OnCreate method including variables and Activity information just above MainActivity class. The MainActivity.cs should now look like:

    img

  3. Remove all the existing using imports in MainActivity.cs add add the following imports that let you use required components in the application.

     using System;
    
     using Android.App;
     using Android.Content;
     using Android.Runtime;
     using Android.Views;
     using Android.Widget;
     using Android.OS;
     using Android.Text;
     using Android.Text.Style;
     using Android.Graphics;
    

    We need to add manifest attributes such as Activities and Intent Filters to our MainActivity.cs in order to make our code work. So add the following code just above MainActivity class in MainActivity.cs.

    Note: For more Information please go through Working with AndroidManifest.xml

     [Activity (Name="barcodescanner.barcodescanner.MainActivity", Label = "barcodescanner", 
     LaunchMode = Android.Content.PM.LaunchMode.SingleTask , MainLauncher = true, Icon = "@drawable/icon")]
    
     [IntentFilter(new string[] { "barcodescanner.RECVR" }, Categories = new[] { Intent.CategoryDefault })]
    

    Your code with the imports and manifest attributes should look like:

    img

  4. Lets declare some global variables in MainActivity class that we would be using in our application. Some of these variables hold the Intent information such as source-tag, label-type and data-string of the scanned barcode data coming through DataWedge application. The variable ourIntentAction holds the Intent Action for our operation and editText holds the UI information, which in this tutorial is barcode data. ACTION_SOFTSCANTRIGGER is the Intent Action that is sent to DataWedge application whenever the user presses scan button in application. This action is supported with extra data (DWAPI_TOGGLE_SCANNING) that lets data wedge application Toggle from hard to soft scan whenever the scan button in the app is pressed.

     // This intent string contains the source of the data as a string  
     private static string SOURCE_TAG = "com.motorolasolutions.emdk.datawedge.source";
     // This intent string contains the barcode symbology as a string  
     private static string LABEL_TYPE_TAG = "com.motorolasolutions.emdk.datawedge.label_type";
     // This intent string contains the captured data as a string  
     // (in the case of MSR this data string contains a concatenation of the track data)  
     private static string DATA_STRING_TAG = "com.motorolasolutions.emdk.datawedge.data_string";
     // Intent Action for our operation
     private static string ourIntentAction = "barcodescanner.RECVR";
    
     // Let's define the API intent strings for the soft scan trigger
     private static String ACTION_SOFTSCANTRIGGER = "com.motorolasolutions.emdk.datawedge.api.ACTION_SOFTSCANTRIGGER";
     private static String EXTRA_PARAM = "com.motorolasolutions.emdk.datawedge.api.EXTRA_PARAMETER";
     private static String DWAPI_TOGGLE_SCANNING = "TOGGLE_SCANNING";
    
     // EditText to hold Barcode data
     private EditText editText;
    
  5. We will now configure OnCreate method by adding following code below the base.OnCreate (bundle);:

     // Set our view from the "main" layout resource
     SetContentView(Resource.Layout.Main);
    
     // Get our button from the layout resource,
     // and attach an event to it
     editText = FindViewById<EditText>(Resource.Id.editbox);
     editText.SetSelection(editText.Text.Length);
    
     // Get our button from the layout resource,
     // and attach an event to toggle scanning option
     Button scanButton = FindViewById<Button> (Resource.Id.btn_scan);
    
     scanButton.Click += delegate {
         var intent = new Intent();    
         intent.SetAction(ACTION_SOFTSCANTRIGGER);    
         intent.PutExtra(EXTRA_PARAM, DWAPI_TOGGLE_SCANNING);
         SendBroadcast(intent);    
     } ;
    

    This code block refers to Main.axml to get the User Interface for Main Activity. It refers to the UI elements declared in the Main.axml layout. After that it has an on click listener for “Scan” button that broadcasts the Intent to DataWedge application with specified Intent Action and Extra Data in order to change modes from hard to soft scan once the “Scan” button is pressed.

    So the code with global variables and OnCreate method should look like:

    img

  6. In this step, we would specify handleDecodeData method that accepts Intent with scanned barcode information. We will extract this barcode information and display to the user in this method.

     // Receives the Intent that has barcode info and displays to the user
     private void handleDecodeData(Android.Content.Intent i)
     {
           // check the intent action is for us  
           if (i.Action.Equals(ourIntentAction))
           {
               // define a string that will hold our output  
               String Out = "";
               // get the source of the data  
               String source = i.GetStringExtra(SOURCE_TAG);
               // save it to use later  
               if (source == null) source = "scanner";
               // get the data from the intent  
               String data = i.GetStringExtra(DATA_STRING_TAG);
               // let's define a variable for the data length  
               int data_len = 0;
               // and set it to the length of the data  
               if (data != null) data_len = data.Length;
               // check if the data has come from the barcode scanner  
               if (source.Equals("scanner"))
               {
                   // check if there is anything in the data  
                   if (data != null && data.Length > 0)
                   {
                       // we have some data, so let's get it's symbology  
                       String sLabelType = i.GetStringExtra(LABEL_TYPE_TAG);
                       // check if the string is empty  
                       if (sLabelType != null && sLabelType.Length > 0)
                       {                        
                           // format of the label type string is LABEL-TYPE-SYMBOLOGY  
                           // so let's skip the LABEL-TYPE- portion to get just the symbology  
                           sLabelType = sLabelType.Substring(11);
                       }
                       else
                       {
                           // the string was empty so let's set it to "Unknown"  
                           sLabelType = "Unknown";
                       }
    
                       // let's construct the beginning of our output string  
                       Out = "Source: Scanner, " + "Symbology: " + sLabelType + ", Length: " + data_len.ToString() + ", Data: ...\r\n";
                   }
               }
               // check if the data has come from the MSR  
               if (source.Equals("msr"))
               {
                   // construct the beginning of our output string  
                   Out = "Source: MSR, Length: " + data_len.ToString() + ", Data: ...\r\n";
               }
    
               // we need to put the edit box text into a spannable string builder  
               SpannableStringBuilder stringbuilder = new SpannableStringBuilder(editText.Text);
               // add the output string we constructed earlier  
               stringbuilder.Append(Out);
               // now let's highlight our output string in bold type  
               //stringbuilder.SetSpan(new StyleSpan(Typeface.DefaultBold), et.Text.Length, stringbuilder.Length, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);  
               // then add the barcode or msr data, plus a new line, and add it to the string builder  
               stringbuilder.Append(data + "\r\n");
               // now let's update the text in the edit box  
               editText.SetText(stringbuilder.ToString(), null);
               // we want the text cursor to be at the end of the edit box  
               // so let's get the edit box text again  
    
               // and set the cursor position at the end of the text  
               editText.SetSelection(editText.Text.Length);
               // and we are done!  
           }
     }
    

    As you can see the method receives an Intent object. It then fetches source data of the Intent along with data string that are passed from DataWedge as EXTRA strings in the Intent. The method then checks for scanner device types such as Scanner and MSR, which is going to be Scanner in this tutorial. Based on the scanner device (Scanner), the method would form the output data string that contains barcode data and display it in the Edit Text that we specified in layout.

    So the handleDecodeData method should look like:

    Note: Since the handleDecodeData method is too long, it’s been divided into multiple screen captures.

    img

    img

    img

  7. Finally, we would override OnNewIntent method that primarily receives the Intent sent by our DataWedge profile whenever a barcode is scanned. This method would in turn call handleDecodeData method to get the barcode data, format it and display it to the user.

    Add following code for OnNewIntent method:

     // Receives Intent from DataWedge application that has barcode data 
     protected override void OnNewIntent(Intent i)
     {
         handleDecodeData(i);
     }
    

    The method OnNewIntent looks like:

    img

That’s it!!! We are done with all the coding part that will let us capture the Intent sent by DataWedge Profile whenever a barcode is scanned. This Intent has the barcode data that would be extracted and displayed in our Xamarin Android application.

Note: We have not yet created the DataWedge Profile for our Xamarin Android application. We will create it after we run the application so that the profile can see our “barcodescanner” application in the list of available applications.

Running the Application

  1. Connect the device to USB port.

    Note:
    Make sure the device is in USB debug.

    In order to run the application on device, select your connected Symbol device under “Physical Devices” in the drop-down.

    img

    img

  2. Run the application by pressing img  button on the top left corner of Xamarin Studio.

    img

    As we have not created the “DataWedge Profile” yet, we will not get the formatted barcode data in the EditText after scanning barcodes. So lets create one.

  3. Creating a DataWedge Profile:

    img

    img

    img

    img

    img

    img

    img

    img

    img

    img

    img

    img

    img

    • Open DataWedge application.
    • You can see different DataWedge Profiles associated with their different respective applications. Now we need to create a DataWedge Profile specific to our Android application that we have created and installed on Symbol device. So click the Menu button and select “New Profile” option.
    • Enter some Profile Name (Ex. Xamarin-Profile) and press “OK”.
    • The profile is now created. We need to configure the profile to output a barcode Intent to our Xamarin Android application when a barcode is scanned. So tap on the profile we created.
    • Now associate our application to this profile by clicking “Associated apps” option. This will let the profile know to pass Intent having barcode data to our application every time a barcode is scanned.
    • Press menu and select “New app/activity” option.
    • Select our Xamarin Android application from the list (barcodescanner.barcodescanner).
    • Select the Activity where you want your app to receive Intent. In our case, it would be barcodescanner.barcodescanner.MainActivity. So select that option and you should see following.
    • Hit the Back button and scroll down a bit and disable the “Keystroke Output” option.
    • Scroll down and Enable the “Intent Output” option, which allows your application to receive information via Intents.
    • Just below that, click the “Intent Action” option and specify the Intent action name that we mentioned in our Xamarin  AndroidManifest.xml file (barcodescanner.RECVR) and press “OK”

      Note: The Intent Action Name in the Xamarin manifest and DataWedge Profile should be identical.

    • Just below that, click the “Intent Category” option and specify the Intent category name that we mentioned in our apps manifest file (android.intent.category.DEFAULT) and Press “OK”
    • So now we have successfully created a DataWedge Profile (Xamarin-Profile) that transfers the Intents having barcode data to our Xamarin Android application (barcodescanner).
  4. So open the Xamarin Android application named “barcodescanner” that we created.

    img

  5. Now scan barcodes using hard scan trigger as well as the soft scan key in the application and you should see the formatted barcode data successfully received through our DataWedge Profile and displayed on the Edit Text of our Xamarin Android application.

    img

Important Programming Tips

  1. It is required to add the manifest configurations in MainActivity.cs file to make them work properly.

    Example:

     [Activity (Name="barcodescanner.barcodescanner.MainActivity", Label = "barcodescanner", 
     LaunchMode = Android.Content.PM.LaunchMode.SingleTask , MainLauncher = true, Icon = "@drawable/icon")]
    
     [IntentFilter(new string[] { "barcodescanner.RECVR" }, Categories = new[] { Intent.CategoryDefault })]
    
  2. Make sure you check the compatibility of the Xamarin and Xa