Zebra EMDK for Xamarin and Android Virtual Device

I have a Xamarin Forms app that is deployed to a Zebra TC51 device. It works very well. TC51 is a very interesting rugged device. I use EMDK to work with integrated barcode reader. You can find a lot of information and code samples here.

Now I would like to use my app without a TC51 device. For example, I would like to test it with an Android Virtual Device. So, I open “AVD Manager” in Visual Studio for MAC and run Android Accelerated x86 AVD. It starts, everything is fine. I start a debug session and APK is deployed to AVD and… now start problems!

/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/Android/Xamarin.Android.Common.Debugging.targets(516,2): error : Failure [INSTALL_FAILED_MISSING_SHARED_LIBRARY]

This is the first error. It seems that I should have a device with EMDK installed to deploy my app. How can I solve this problem?

Modify AndroidManifest.xml

I have to modify AndoridManifest.xml and add the code in “bold

 <application android:label="fev_ventilazione_smartwatch" android:icon="@drawable/icon">
     <uses-library android:name="com.symbol.emdk"  android:required="false"/>
 </application>

What does it mean? Here all explanations you need.

android:required

Boolean value that indicates whether the application requires the feature specified in android:name.

  • When you declare android:required="true" for a feature, you are specifying that the application cannot function, or is not designed to function, when the specified feature is not present on the device.
  • When you declare android:required="false" for a feature, it means that the application prefers to use the feature if present on the device, but that it is designed to function without the specified feature, if necessary.

The default value for android:required if not declared is "true".

Ok. A first problem is solved. I am very happy. Now I try to deploy again the app to my AVD. All seems to work fine and…

Another big problem. An exception appears:

Screenshot 2017-10-31 20.48.45

Yes, my code needs EMDK! How can I solve this problem?

Remove EMDK code with preprocessor directives

Preprocessor directive are very powerful. To use these directives we have to create a new configuration for our solution. I add some pictures to explain better all the steps. I have VS4Mac in Italian… maybe a little different from English version.

Add a new configuration.

Double click to “(master)” solution and select “Configurations”, you should see something like this (I hope MFractor developer do not be angry for popup…;)):

Screenshot 2017-10-31 21.02.51

Select “Release” configuration, press “Copy” and create a new “ReleaseNoEMDK” configuration. Obviously, you can do the same with “Debug” configuration if you need to debug your app without EMDK installed.

Now, when you try to change your configuration, you should have a situation like this:

Screenshot 2017-10-31 21.07.54

Select “ReleaseNoEMDK” and double click PCL Solution. In “Project Option” popup, select “Compiler” and add “NO_EMDK” symbol.

Screenshot 2017-10-31 21.09.56

Double click to Android Solution and add NO_EMDK symbol.

Screenshot 2017-10-31 21.13.20

Now your projects have the right configuration to use preprocessor directives. You can add these directives to your Android project, when you use EMDK (all EMDK code is under Android project!). For example in MainActivity.cs:

 #if !NO_EMDK
     public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, EMDKManager.IEMDKListener
 #else
     public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
 #endif 

or ScanReceiver.cs

 #if !NO_EMDK
     [BroadcastReceiver]
     public class ScanReceiver : BroadcastReceiver
     {
         public static DateTime UltimaLetturaBarcode = DateTime.MinValue;
 
         // 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
         public static string IntentAction = "barcodescanner.RECVR";
         public static string IntentCategory = "android.intent.category.DEFAULT";
 
         public event EventHandler<string> scanDataReceived;
 
         public override void OnReceive (Context context, Intent i)
         {
             // check the intent action is for us  
             if (i.Action.Equals (IntentAction)) {
                 // 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;
                 string sLabelType = "";
                 // 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  
                         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 = "Scanner  " + "Symbology: " + sLabelType + ", Length: " + data_len.ToString () + ", Data: " + data.ToString () + "\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: " + data.ToString () + "\r\n";
                 }
                     
 
                 if (scanDataReceived != null) {
 
                     // Prendo la data precedente
                     if ((DateTime.Now - UltimaLetturaBarcode).TotalMilliseconds < 1000)
                         return;
                     UltimaLetturaBarcode = DateTime.Now;
 
                     System.Diagnostics.Debug.WriteLine("scanDataReceived '" + data + "'");
 
                     //scanDataReceived (this, Out);
                     scanDataReceived(this, data);
                 }
             }
         }
     }
 #endif


Using these directives you can add or remove EMDK specific code from your source only selecting the correct project configuration.

Hope this can be useful. Let me know. Comments are well accepted! And happy Halloween…

 

4 pensieri su “Zebra EMDK for Xamarin and Android Virtual Device

  1. Hello
    I have something misunderstand, you said you need EMDK , but why you remove EMDK code with preprocessor directives?
    I have NoClassDefFoundError too, i think it should be deploy some DLL or EMDK file to mobile computer.

    "Mi piace"

Lascia un commento