Overview
This guide provides a walk-through of the steps for creating an application that uses RFID3 API 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
Developer machine with latest Android studio
Developer machine with Zebra Android device USB driver installed
Zebra Android device with developer mode turned on
Zebra RFID Manager application installed in case of RFD2000 and MC3300R
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 Android Studio. Call it Hello RFID
to match later references in this guide. For help, see the Android Studio tutorial.
Adding essentials
Modify the application's MainActivity.java
file to use the RFID SDK library.
Declare RFID readers fields:
private static Readers readers;` private static ArrayList
availableRFIDReaderList; private static ReaderDevice readerDevice; private static RFIDReader reader; private static String TAG = "DEMO"; Create SDK
Readers
instance// SDK if (readers == null) { readers = new Readers(this, ENUM_TRANSPORT.SERVICE_SERIAL); }
Note : For RFD40XX USB connectivity create reader instance with
readers = new Readers(this, ENUM_TRANSPORT.SERVICE_USB)
Create
AsyncTask
to retrieve available readers usingGetAvailableRFIDReaderList
new AsyncTask
() { @Override protected Boolean doInBackground(Void... voids) { try { if (readers != null) { if (readers.GetAvailableRFIDReaderList() != null) { availableRFIDReaderList = readers.GetAvailableRFIDReaderList(); if (availableRFIDReaderList.size() != 0) { // get first reader from list readerDevice = availableRFIDReaderList.get(0); reader = readerDevice.getRFIDReader(); if (!reader.isConnected()) { // Establish connection to the RFID Reader reader.connect(); ConfigureReader(); return true; } } } } } catch (InvalidUsageException e) { e.printStackTrace(); } catch (OperationFailureException e) { e.printStackTrace(); Log.d(TAG, "OperationFailureException " + e.getVendorMessage()); } return false; } @Override protected void onPostExecute(Boolean aBoolean) { super.onPostExecute(aBoolean); if (aBoolean) { Toast.makeText(getApplicationContext(), "Reader Connected", Toast.LENGTH_LONG).show(); //textView.setText("Reader connected"); } } }.execute(); Add
ConfigureReader
method to configure the reader for trigger type and adding event handler / listeneraddEventsListener
private void ConfigureReader() { if (reader.isConnected()) { TriggerInfo triggerInfo = new TriggerInfo(); triggerInfo.StartTrigger.setTriggerType(START_TRIGGER_TYPE.START_TRIGGER_TYPE_IMMEDIATE); triggerInfo.StopTrigger.setTriggerType(STOP_TRIGGER_TYPE.STOP_TRIGGER_TYPE_IMMEDIATE); try { // receive events from reader if (eventHandler == null) eventHandler = new EventHandler(); reader.Events.addEventsListener(eventHandler); // HH event reader.Events.setHandheldEvent(true); // tag event with tag data reader.Events.setTagReadEvent(true); // application will collect tag using getReadTags API reader.Events.setAttachTagDataWithReadEvent(false); // set trigger mode as rfid so scanner beam will not come reader.Config.setTriggerMode(ENUM_TRIGGER_MODE.RFID_MODE, true); // set start and stop triggers reader.Config.setStartTrigger(triggerInfo.StartTrigger); reader.Config.setStopTrigger(triggerInfo.StopTrigger); } catch (InvalidUsageException e) { e.printStackTrace(); } catch (OperationFailureException e) { e.printStackTrace(); } } }
Add
EventHandler
class to handle Reader operation events -eventReadNotify
and Reader status events -eventStatusNotify
// Read/Status Notify handler // Implement the RfidEventsListener class to receive event notifications public class EventHandler implements RfidEventsListener { // 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++) { Log.d(TAG, "Tag ID " + myTags[index].getTagID()); } } } // Status Event Notification public void eventStatusNotify(RfidStatusEvents rfidStatusEvents) { Log.d(TAG, "Status Notification: " + rfidStatusEvents.StatusEventData.getStatusEventType()); if (rfidStatusEvents.StatusEventData.getStatusEventType() == STATUS_EVENT_TYPE.HANDHELD_TRIGGER_EVENT) { if (rfidStatusEvents.StatusEventData.HandheldTriggerEventData.getHandheldEvent() == HANDHELD_TRIGGER_EVENT_TYPE.HANDHELD_TRIGGER_PRESSED) { } if (rfidStatusEvents.StatusEventData.HandheldTriggerEventData.getHandheldEvent() == HANDHELD_TRIGGER_EVENT_TYPE.HANDHELD_TRIGGER_RELEASED) { } } } }
Assign
android:id
to -TextView
to print some useful information on screen
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/TagText"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Running the application
Connection with device
Connect MC3300R or TC20+RFD2000 or any android terminal with PC over USB
Make sure project is already built successfully
Click on
Run app (shift+F10)
from top right cornerNow Application should be launched on Zebra Android device fine
Application should be showing
Reader connected
on screen
Programming tips
GetAvailableRFIDReaderList
must be called from background thread, in current example usesAsyncTask
for same purpiseAt time of exit, application shound disconnect with reader using
Disconnect
API and free up SDK instance. Refer MainActivityOnDestroy
methodIn case of failures or exceptions refer messages returned by API call to get more details
What's Next
Add code to show the tag reporting unique count and total tag count
Add code to configure various reader parameters e.g. Antenna power level and Singulation control to change opertional behavior as per need
Refer various guides Guides and RFID demo application source for various features
Application MainActivity full source
package com.zebra.demorfid.hellorfid;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
import com.zebra.rfid.api3.*;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private static Readers readers;
private static ArrayList availableRFIDReaderList;
private static ReaderDevice readerDevice;
private static RFIDReader reader;
private static String TAG = "DEMO";
TextView textView;
private EventHandler eventHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
//
// UI
textView = (TextView) findViewById(R.id.TagText);
// SDK
if (readers == null) {
readers = new Readers(this, ENUM_TRANSPORT.SERVICE_SERIAL);
}
new AsyncTask() {
@Override
protected Boolean doInBackground(Void... voids) {
try {
if (readers != null) {
if (readers.GetAvailableRFIDReaderList() != null) {
availableRFIDReaderList = readers.GetAvailableRFIDReaderList();
if (availableRFIDReaderList.size() != 0) {
// get first reader from list
readerDevice = availableRFIDReaderList.get(0);
reader = readerDevice.getRFIDReader();
if (!reader.isConnected()) {
// Establish connection to the RFID Reader
reader.connect();
ConfigureReader();
return true;
}
}
}
}
} catch (InvalidUsageException e) {
e.printStackTrace();
} catch (OperationFailureException e) {
e.printStackTrace();
Log.d(TAG, "OperationFailureException " + e.getVendorMessage());
}
return false;
}
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
if (aBoolean) {
Toast.makeText(getApplicationContext(), "Reader Connected", Toast.LENGTH_LONG).show();
textView.setText("Reader connected");
}
}
}.execute();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void ConfigureReader() {
if (reader.isConnected()) {
TriggerInfo triggerInfo = new TriggerInfo();
triggerInfo.StartTrigger.setTriggerType(START_TRIGGER_TYPE.START_TRIGGER_TYPE_IMMEDIATE);
triggerInfo.StopTrigger.setTriggerType(STOP_TRIGGER_TYPE.STOP_TRIGGER_TYPE_IMMEDIATE);
try {
// receive events from reader
if (eventHandler == null)
eventHandler = new EventHandler();
reader.Events.addEventsListener(eventHandler);
// HH event
reader.Events.setHandheldEvent(true);
// tag event with tag data
reader.Events.setTagReadEvent(true);
// application will collect tag using getReadTags API
reader.Events.setAttachTagDataWithReadEvent(false);
// set trigger mode as rfid so scanner beam will not come
reader.Config.setTriggerMode(ENUM_TRIGGER_MODE.RFID_MODE, true);
// set start and stop triggers
reader.Config.setStartTrigger(triggerInfo.StartTrigger);
reader.Config.setStopTrigger(triggerInfo.StopTrigger);
} catch (InvalidUsageException e) {
e.printStackTrace();
} catch (OperationFailureException e) {
e.printStackTrace();
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
try {
if (reader != null) {
reader.Events.removeEventsListener(eventHandler);
reader.disconnect();
Toast.makeText(getApplicationContext(), "Disconnecting reader", Toast.LENGTH_LONG).show();
reader = null;
readers.Dispose();
readers = null;
}
} catch (InvalidUsageException e) {
e.printStackTrace();
} catch (OperationFailureException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
// Read/Status Notify handler
// Implement the RfidEventsLister class to receive event notifications
public class EventHandler implements RfidEventsListener {
// Read Event Notification
public void eventReadNotify(RfidReadEvents e) {
// Recommended to use new method getReadTagsEx for better performance in case of large tag population
TagData[] myTags = reader.Actions.getReadTags(100);
if (myTags != null) {
for (int index = 0; index < myTags.length; index++) {
Log.d(TAG, "Tag ID " + myTags[index].getTagID());
if (myTags[index].getOpCode() == ACCESS_OPERATION_CODE.ACCESS_OPERATION_READ &&
myTags[index].getOpStatus() == ACCESS_OPERATION_STATUS.ACCESS_SUCCESS) {
if (myTags[index].getMemoryBankData().length() > 0) {
Log.d(TAG, " Mem Bank Data " + myTags[index].getMemoryBankData());
}
}
}
}
}
// Status Event Notification
public void eventStatusNotify(RfidStatusEvents rfidStatusEvents) {
Log.d(TAG, "Status Notification: " + rfidStatusEvents.StatusEventData.getStatusEventType());
if (rfidStatusEvents.StatusEventData.getStatusEventType() == STATUS_EVENT_TYPE.HANDHELD_TRIGGER_EVENT) {
if (rfidStatusEvents.StatusEventData.HandheldTriggerEventData.getHandheldEvent() == HANDHELD_TRIGGER_EVENT_TYPE.HANDHELD_TRIGGER_PRESSED) {
new AsyncTask() {
@Override
protected Void doInBackground(Void... voids) {
try {
reader.Actions.Inventory.perform();
} catch (InvalidUsageException e) {
e.printStackTrace();
} catch (OperationFailureException e) {
e.printStackTrace();
}
return null;
}
}.execute();
}
if (rfidStatusEvents.StatusEventData.HandheldTriggerEventData.getHandheldEvent() == HANDHELD_TRIGGER_EVENT_TYPE.HANDHELD_TRIGGER_RELEASED) {
new AsyncTask() {
@Override
protected Void doInBackground(Void... voids) {
try {
reader.Actions.Inventory.stop();
} catch (InvalidUsageException e) {
e.printStackTrace();
} catch (OperationFailureException e) {
e.printStackTrace();
}
return null;
}
}.execute();
}
}
}
}
}