Hello RFID Xamarin Application

RFID SDK For Xamarin 2.0.1.15

Overview

This guide provides a walk-through of the steps for creating an application that uses Xamarin RFID SDK to perform RFID operations

Note: The demo app in this guide is intended for tutorial purposes only and should not be used in production environments.


Prerequisites

  1. Developer machine with latest Visual studio and Xamarin

  2. Developer machine with Zebra Android device USB driver installed

  3. Zebra Android device with developer mode turned on

  4. Zebra RFID Manager application installed in case of RFD2000 and MC3300R

  5. Reader regulatory is configured as per norms using RFID Manager or Zebra RFID Demo application

Create the Project

Start by creating a new project in Visual Studio. Call it HelloRFID to match later references in this guide. For help, see the Create the Project tutorial

This project has been created with Shared Projectcode sharing strategy

Adding essentials

Modify the application's MainPage.xaml.cs file to use the Xamarin RFID SDK library.

  1. Declare RFID readers fields:

    
    private static Readers readers;
    private static IList availableRFIDReaderList;
    private static ReaderDevice readerDevice;
    private static RFIDReader Reader;
    private EventHandler eventHandler;
    
  2. Create SDK Readers instance

    
    // SDK
    if (readers == null)
    {
        readers = new Readers(Android.App.Application.Context, ENUM_TRANSPORT.ServiceSerial);
    }
    GetAvailableReaders();
    
  3. Create ThreadPool.QueueUserWorkItem to retrieve available readers using AvailableRFIDReaderList

    
    private void GetAvailableReaders()
    {
        ThreadPool.QueueUserWorkItem(o =>
        {
            try
            {
                if (readers != null && readers.AvailableRFIDReaderList != null)
                {
                    availableRFIDReaderList =
                        readers.AvailableRFIDReaderList;
                    if (availableRFIDReaderList.Count > 0)
                    {
                        if (Reader == null)
                        {
                            // get first reader from list
                            readerDevice = availableRFIDReaderList[0];
                            Reader = readerDevice.RFIDReader;
                            // Establish connection to the RFID Reader
                            Reader.Connect();
                            if (Reader.IsConnected)
                            {
                                Console.Out.WriteLine("Reader connected");
                                Status = "Reader connected";
                                ConfigureReader();
                            }
    
                        }
                    }
                }
            }
            catch (InvalidUsageException e)
            {
                e.PrintStackTrace();
            }
            catch (OperationFailureException e)
            {
                e.PrintStackTrace();
                Console.Out.WriteLine("OperationFailureException " + e.VendorMessage);
                Status = "OperationFailureException " + e.VendorMessage;
            }
        });
    }
    
  4. Add ConfigureReader method to configure the reader for trigger type and adding event handler / listener AddEventsListener

    
    private void ConfigureReader()
    {
        if (Reader.IsConnected)
        {
            TriggerInfo triggerInfo = new TriggerInfo();
            triggerInfo.StartTrigger.TriggerType = START_TRIGGER_TYPE.StartTriggerTypeImmediate;
            triggerInfo.StopTrigger.TriggerType = STOP_TRIGGER_TYPE.StopTriggerTypeImmediate;
            try
            {
                // receive events from reader
                if (eventHandler == null)
                {
                    eventHandler = new EventHandler(Reader);
                }
    
                Reader.Events.AddEventsListener(eventHandler);
                // HH event
                Reader.Events.SetHandheldEvent(true);
                // tag event with tag data
                Reader.Events.SetTagReadEvent(true);
                Reader.Events.SetAttachTagDataWithReadEvent(false);
                // set trigger mode as rfid so scanner beam will not come
                Reader.Config.SetTriggerMode(ENUM_TRIGGER_MODE.RfidMode, true);
                // set start and stop triggers
                Reader.Config.StartTrigger = triggerInfo.StartTrigger;
                Reader.Config.StopTrigger = triggerInfo.StopTrigger;
            }
            catch (InvalidUsageException e)
            {
                e.PrintStackTrace();
            }
            catch (OperationFailureException e)
            {
                e.PrintStackTrace();
            }
        }
    }
    
  5. Add EventHandler class to handle Reader operation events - EventReadNotify and Reader status events - EventStatusNotify

    
    // Read/Status Notify handler
    // Implement the RfidEventsLister class to receive event notifications
    public class EventHandler : Java.Lang.Object, IRfidEventsListener
    {
        public EventHandler(RFIDReader Reader)
        {
    
        }
        // Read Event Notification
        public void EventReadNotify(RfidReadEvents e)
        {
            TagData[] myTags = Reader.Actions.GetReadTags(100);
        }
    
        // Status Event Notification
        public void EventStatusNotify(RfidStatusEvents rfidStatusEvents)
        {
    
        }
    }
    
  6. Assign Label Text="{Binding Status}" to - Status to print some useful information on screen

  7. 
    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:local="clr-namespace:HelloRFID"
                 x:Class="HelloRFID.MainPage">
    
        <StackLayout>
            <!-- Place new controls here -->
            <Label Text="Welcome to Xamarin.Forms Hello RFID!" 
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />
    		<Label Text="{Binding Status}"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />
    	</StackLayout>
    
    </ContentPage>
    

Running the application

Connection with device

  1. Connect MC3300R or TC20+RFD2000 with PC over USB

  2. Make sure project is already built successfully

  3. Click on Run app (F5) to run the applicationr

  4. Now Application should be launched on Zebra Android device fine

  5. Application should be showing Reader connected on screen

  6. img

Programming tips

  1. GetAvailableRFIDReaderList must be called from background thread, in current example uses ThreadPool.QueueUserWorkItem for same purpise

  2. At time of exit, application shound disconnect with reader using Disconnect API and free up SDK instance.

  3. In case of failures or exceptions refer messages returned by API call to get more details

What's Next

  1. Add code to show the tag reporting unique count and total tag count

  2. Add code to configure various reader parameters e.g. Antenna power level and Singulation control to change opertional behavior as per need

  3. Refer various guides Guides and RFID demo application source for various features

Application full source


using Com.Zebra.Rfid.Api3;
using System;
using System.Collections.Generic;
using System.Threading;
using Xamarin.Forms;

namespace HelloRFID
{
	public partial class MainPage : ContentPage
	{
		private static Readers readers;
		private static IList availableRFIDReaderList;
		private static ReaderDevice readerDevice;
		private static RFIDReader Reader;
		private EventHandler eventHandler;
		private string _status;
		public string Status { get => _status; set { _status = value; OnPropertyChanged(); } }

		public MainPage()
		{
			InitializeComponent();
			BindingContext = this;
			// SDK
			if (readers == null)
			{
				readers = new Readers(Android.App.Application.Context, ENUM_TRANSPORT.ServiceSerial);
			}

			GetAvailableReaders();
		}

		private void GetAvailableReaders()
		{
			ThreadPool.QueueUserWorkItem(o =>
			{
				try
				{
					if (readers != null && readers.AvailableRFIDReaderList != null)
					{
						availableRFIDReaderList =
							readers.AvailableRFIDReaderList;
						if (availableRFIDReaderList.Count > 0)
						{
							if (Reader == null)
							{
								// get first reader from list
								readerDevice = availableRFIDReaderList[0];
								Reader = readerDevice.RFIDReader;
								// Establish connection to the RFID Reader
								Reader.Connect();
								if (Reader.IsConnected)
								{
									Console.Out.WriteLine("Reader connected");
									Status = "Reader connected";
									ConfigureReader();
								}

							}
						}
					}
				}
				catch (InvalidUsageException e)
				{
					e.PrintStackTrace();
				}
				catch (OperationFailureException e)
				{
					e.PrintStackTrace();
					Console.Out.WriteLine("OperationFailureException " + e.VendorMessage);
					Status = "OperationFailureException " + e.VendorMessage;
				}
			});
		}

		private void ConfigureReader()
		{
			if (Reader.IsConnected)
			{
				TriggerInfo triggerInfo = new TriggerInfo();
				triggerInfo.StartTrigger.TriggerType = START_TRIGGER_TYPE.StartTriggerTypeImmediate;
				triggerInfo.StopTrigger.TriggerType = STOP_TRIGGER_TYPE.StopTriggerTypeImmediate;
				try
				{
					// receive events from reader
					if (eventHandler == null)
					{
						eventHandler = new EventHandler(Reader);
					}

					Reader.Events.AddEventsListener(eventHandler);
					// HH event
					Reader.Events.SetHandheldEvent(true);
					// tag event with tag data
					Reader.Events.SetTagReadEvent(true);
					Reader.Events.SetAttachTagDataWithReadEvent(false);
					// set trigger mode as rfid so scanner beam will not come
					Reader.Config.SetTriggerMode(ENUM_TRIGGER_MODE.RfidMode, true);
					// set start and stop triggers
					Reader.Config.StartTrigger = triggerInfo.StartTrigger;
					Reader.Config.StopTrigger = triggerInfo.StopTrigger;
				}
				catch (InvalidUsageException e)
				{
					e.PrintStackTrace();
				}
				catch (OperationFailureException e)
				{
					e.PrintStackTrace();
				}
			}
		}

		// Read/Status Notify handler
		// Implement the RfidEventsLister class to receive event notifications
		public class EventHandler : Java.Lang.Object, IRfidEventsListener
		{
			public EventHandler(RFIDReader Reader)
			{

			}
			// Read Event Notification
			public void EventReadNotify(RfidReadEvents e)
			{
				TagData[] myTags = Reader.Actions.GetReadTags(100);
				if (myTags != null)
				{
					for (int index = 0; index < myTags.Length; index++)
					{
						Console.Out.WriteLine("Tag ID " + myTags[index].TagID);
						if (myTags[index].OpCode ==
								ACCESS_OPERATION_CODE.AccessOperationRead &&
								myTags[index].OpStatus ==
										ACCESS_OPERATION_STATUS.AccessSuccess)
						{
							if (myTags[index].MemoryBankData.Length > 0)
							{
								Console.Out.WriteLine(" Mem Bank Data " + myTags[index].MemoryBankData);
							}
						}
					}
				}
			}

			// Status Event Notification
			public void EventStatusNotify(RfidStatusEvents rfidStatusEvents)
			{
				Console.Out.WriteLine("Status Notification: " + rfidStatusEvents.StatusEventData.StatusEventType);
				if (rfidStatusEvents.StatusEventData.StatusEventType == STATUS_EVENT_TYPE.HandheldTriggerEvent)
				{
					if (rfidStatusEvents.StatusEventData.HandheldTriggerEventData.HandheldEvent ==
							HANDHELD_TRIGGER_EVENT_TYPE.HandheldTriggerPressed)
					{
						ThreadPool.QueueUserWorkItem(o =>
						{
							try
							{
								Reader.Actions.Inventory.Perform();
							}
							catch (InvalidUsageException e)
							{
								e.PrintStackTrace();
							}
							catch (OperationFailureException e)
							{
								e.PrintStackTrace();
							}
						});

					}
					if (rfidStatusEvents.StatusEventData.HandheldTriggerEventData.HandheldEvent ==
							HANDHELD_TRIGGER_EVENT_TYPE.HandheldTriggerReleased)
					{
						ThreadPool.QueueUserWorkItem(o =>
						{
							try
							{
								Reader.Actions.Inventory.Stop();
							}
							catch (InvalidUsageException e)
							{
								e.PrintStackTrace();
							}
							catch (OperationFailureException e)
							{
								e.PrintStackTrace();
							}
						});
					}
				}
			}
		}

	}

}