Read a barcode with Zebra terminals, using DataWedge and .NET MAUI

[删除(380066935@qq.com或微信通知)]

更好的阅读体验请查看原文:https://acaliaro.wordpress.com/2023/06/08/read-a-barcode-with-zebra-terminals-using-datawedge-and-dotnetmaui/

Hi everyone. It’s been a long time since my last article on Xamarin Forms. Many things have happened in these years. Surely, for us developers, one of the most interesting things is the arrival of #dotnetmaui, the new framework for developing applications on iOS, Android, Windows.

As you know many of my articles are related to how to use industrial android devices and their hardware. This first article would like to resume an article already written for Xamarin Forms (Xamarin Android and DataWedge scanning process), on how to integrate barcode reading in a MAUI application on Zebra android terminals.

You will find that much of the material in the Xamarin Forms article is still valid. That’s because the platform-specific parts haven’t changed much between Xamarin Forms and MAUI. Instead, we will see what are the differences relating in particular to the fact that with MAUI you have a single project, while with Xamarin Forms there was a PCL project and a project for each platform.

To integrate the barcode reader into an Android application on Zebra terminals, the best method is to create a DataWedge profile https://techdocs.zebra.com/datawedge/11-4/guide/about/. Zebra DataWedge is an application service that provides the capability to control and manage data capture hardware with little effort to integrate acquired data into new or existing apps with DataWedge. It enables any application on the device to capture data from multiple input sources (such as barcode scanner, MSR, RFID, voice, and serial port) and format the data as needed using simple options or custom complex rules. DataWedge functionality is based on profiles – the foreground activity determines the set of configurations to apply from the profile. Profiles are configured manually or programmatically using Android intent APIs, with the capability for mass deployment. DataWedge is available out-of-the-box with every Zebra Android device.

Another possibility is to use the EMDK https://techdocs.zebra.com/emdk-for-xamarin/8-0/guide/about/, but it is not recommended by Zebra:

Zebra strongly recommends the use of DataWedge for all applications that require barcode scanning. While Zebra will continue to support EMDK Barcode APIs, the efficiency and feature richness of intent-based interfaces make it a simpler alternative to app development using EMDK Barcode APIs.

DataWedge facts:

  • DataWedge APIs have the same capabilities currently available in EMDK Barcode APIs.
  • DataWedge intent-based APIs are easier and faster to implement than EMDK Barcode APIs.
  • New features are added to DataWedge before being considered for EMDK Barcode APIs.

Below are the various steps to be able to integrate a barcode reader using a DataWedge profile and android intents in a MAUI application.

Define the package name of the application

The first step is to define the packagename of the application. This is because the MAUI application associates itself with the DataWedge profile via its packagename: for this reason, it is better to define it now. In MAUI, to define the application packagename, open the application properties and select “shared MAUI” (I suppose… I have Visual Studio in Italian…). The packagename is “Application ID”. In my example, I leave the one proposed by Visual Studio when creating the project: “com.companyname.mauiappdatawedgesample”.

In our MAUI application we will need some libraries. It’s good to add them now!

  • CommunityToolkit.Mvvm

Now, let’s connect the Zebra device (I’m using a Zebra TC52 Android 11) to the PC and run the application. In this way, once the application is loaded on the device, DataWedge will be able to detect it and associate it with the profile, once we are going to create it.

Once we’ve run the application and verified that it works, let’s move on to creating the DataWedge profile.

Create a DataWedge profile

To create a DataWedge profile, you can follow these simple guidelines:

Open the DataWedge application on the device

Select “New Profile” in the top right menu

Enter the profile name

The new profile should be created, and added to the bottom of the profile list. Open the profile by clicking on the name, so that you can edit the necessary properties.

There are not many properties to change. The first is to associate the MAUI application with the profile. Open “Associated applications” and, in the menu at the top right, select the item “New application / activity” (the translation could be different as I have DataWedge in Italian)

DataWedge presents a list containing all the applications installed on the device. We need to scroll through the list until we reach the packagename of our application. Once selected, a list of the activities associated with the application appears (by default, a MAUI application has three activities). To avoid problems, we select the asterisk, so that all activities can use DataWedge.

In this way we have associated our MAUI application with the DataWedge profile. This means that the DataWedge profile will only be used by our application and will not interfere with other applications.

Now let’s go back to the DataWedge profile main form, where there is the list of properties. Going down, you’ll find an “Output keystroke” property (I think…damn translation), which is enabled. It must be disabled as our application will use the “Output Intent”, which is immediately after and must be enabled:

Once the “Output Intent” has been enabled, some of its properties must be modified: the “Action” (put an Action of your choice, for example “barcodescanner.RECVR”) and the “Distribution” (selecting “Broadcast”) must be specified. If desired, you can also specify the “Category” (“android.intent.category.DEFAULT”). With these changes finished, the DataWedge profile for the “Intent” part should look like this:

The DataWedge profile creation part can be considered completed. Now we need to export the profile, so that we can add it to our application’s assets. To export the profile, go back to the DataWedge screen where the list of profiles is displayed, and choose “Settings” from the menu at the top right

Select “export profile”. A list of configured profiles will appear. Select the one from our MAUI application and press “Export”. A file with the “.db” extension will be created in the “sdcard/Android/data/com.symbol.datawedge/files” directory (in our example, the file name is “dwprofile_MauiAppDataWedgeSample.db”) which can be retrieved and copied to the PC or via ADB command, or via Android Studio.

Use the DataWedge profile in the MAUI application

Now that we have created the DataWedge profile and copied the file with the “.db” extension to our PC, we can insert it into our MAUI application. In MAUI applications, the best place to put “external” files to the application is in the “Raw” folder in the “Resources” folder. We can go and create a “DataWedge” subfolder inside “Raw” and copy the “.db” file into it. By copying the file, it should automatically receive the “MauiAsset” build action.

We now need to add some code that will allow us to handle DataWedge intents. This code is very similar to the one already used in the previous Xamarin Forms example. First, add a “Utilities” directory in “Platforms/Android” (remember that this code is exclusive to the Android platform), and insert the “ScanReceiver.cs” file which will allow us to manage the BroadcastReceiver to receive the barcode read by the DataWedge.

Once the file has been added, we need to modify the namespace and add the “using” of the CommunityToolkit.Mvvm.Messaging, which will allow us to use the WeakReferenceMessenger which replaces the MessagingCenter in MAUI. We notice that we have an error on the “DataWedgeMessage” object. This object is used by WeakReferenceMessenger to manage the message containing the read barcode, from the Android code to the MAUI code.

WeakReferenceMessenger.Default.Send(new DataWedgeMessage(data));

To create the “DataWedgeMessage” object, we can create a “Messages” directory in the MAUI part of the solution, and add the class.

namespace MauiAppDataWedgeSample.Messages
{
  public class DataWedgeMessage : ValueChangedMessage
  {
    public DataWedgeMessage(string message) : base(message)
    {
    }
  }
}

Now, adding the correct “using”, the code in the “ScanReceiver.cs” should be complete.

In “ScanReceiver.cs”, in addition to some constants representing the “Extras” of the DataWedge intent, which we will use to retrieve the information sent to us by the DataWedge, there are also the constants relating to the “action” and the “category” that we have defined previously when we configured the DataWedge profile. We verify that “action” and “category” are correct with those defined in the profile.

public static string IntentAction = "barcodescanner.RECVR";
public static string IntentCategory = "android.intent.category.DEFAULT";

Once the BroadcastReceiver has been created, let’s use it in the “MainActivity.cs”, adding the “OnCreate”, “OnResume” and “OnPause” methods. The “MainActivity” should look like this:

public class MainActivity : MauiAppCompatActivity
{
    ScanReceiver _scanReceiver;
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        System.Diagnostics.Debug.WriteLine("OnCreate", "MainActivity");
        _scanReceiver = new ScanReceiver();
    }
    protected override void OnResume()
    {
        base.OnResume();
        // Register the broadcast receiver
        IntentFilter filterScan = new(ScanReceiver.IntentAction);
        filterScan.AddCategory(ScanReceiver.IntentCategory);
        RegisterReceiver(_scanReceiver, filterScan);
    }
    protected override void OnPause()
    {
        base.OnPause();
        UnregisterReceiver(_scanReceiver);
    }
}

In the “OnResume” and “OnPause” methods the BroadcastReceiver is registered or unregisterd, so that when the application is in the foreground, it can receive the barcodes, and when it goes to the background, it no longer receives the barcodes from DataWedge.

Now that the part related to the Android platform has been implemented, we can move on to setting the part relating to the UI. Let’s start adding some controls to the MainPage.xaml, so that it looks something like this:

Compared to the original page, we have:

  • a Label to display the read barcode
  • a Button that allows you to copy the DataWedge profile to the PDA
  • a switch that allows you to enable / disable the profile (therefore, enable / disable the barcode reader)

The enabling and disabling of the profile is done through the intents present in the DataWedgeService.cs class:

        public void EnableProfile()
        {

#if ANDROID
            EnableDataWedge(Platform.CurrentActivity.ApplicationContext, true);
            SwitchToProfile(Platform.CurrentActivity.ApplicationContext, PROFILE_NAME_SCANNER);
#endif
        }

        public void DisableProfile()
        {
#if ANDROID
            EnableDataWedge(Platform.CurrentActivity.ApplicationContext, false);
#endif
        }
#if ANDROID
        public static void EnableDataWedge(Context context, bool isEnabled)
        {

            Intent i = new();
            i.SetAction(ACTION_DATAWEDGE_FROM_6_2);
            i.PutExtra(EXTRA_ENABLE_DATAWEDGE, isEnabled);
            context.SendBroadcast(i);
        }
#endif

The DataWedgeService.cs class also contains other methods, not used in this demo, for which you can go to the official Zebra documentation.

I note a couple of things regarding the MainViewModel.cs. In the Appearing and Disappearing commands, the recording of the message sent by the BroadcastReceiver is activated/deactivated each time a barcode is read. Registration upon receipt of the message containing the barcode is performed when the page is displayed (this method is useful when there are applications with multiple pages for which barcode reading is required, so that the barcode is processed only on the current page). This message arrives in the Receive method (defined by the IRecipient interface) and displayed via binding with the Barcode property.

I hope I have been exhaustive enough. At the link you can find the project on GitHub:

https://github.com/acaliaro/MauiAppDataWedgeSample