Using Android Studio, we will create a sample project that will interface with the UniMag and will perform the following activities:
- Auto-Connect and display connection status
- Get Device Firmware
- Start/Stop Transaction Request for MSR (tap/swipe)
Listeners:
- Listener to receive card swipes
- Listener to detect device connected
- Listener to detect device disconnected
Step 1: Create New Project
Create a new Android Application project in Android Studio as an Empty Activity
Step 2: Import IDTechSDK for UniMag
Import the necessary libraries
Step 3: Design Interface
Design the User Interface by editing the main layout XML file
Open your layout and add items to so it contains the following buttons/fields (sample code provide at end of section):
- Add a TextView to the top that will signify connection/disconnection status.
- Add two TextViews to communicate data from the UniMag. Remove the Editable behavior if you don't want the keyboard to pop up if you accidentally select it.
- Add buttons to execute the following functions:
- Get Firmware
- Start MSR/ CTLS
- Cancel Transaction
Step 4: Configure Activity File
In the activity file, perform the following:
Layout Source Code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#aaaaaa"
android:orientation="vertical" >
<TextView
android:id="@+id/status_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#000000"
android:gravity="center_vertical|center_horizontal"
android:text="UniMag DISCONNECTED"
android:textColor="#FFFFFF" />
<LinearLayout
android:id="@+id/linearLayoutEditText"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#dddddd"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical" >
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:background="#ffffff" >
<TextView
android:id="@+id/lcdLog"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text=""
android:textColor="#000000"
android:textSize="12sp"
android:typeface="monospace" >
</TextView>
</ScrollView>
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayoutEditText2"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#dddddd"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical" >
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:background="#ffffff" >
<TextView
android:id="@+id/textLog"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text=""
android:textColor="#000000"
android:textSize="12sp"
android:typeface="monospace" >
</TextView>
</ScrollView>
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayoutBottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<Button
android:id="@+id/btn_getFirmware"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.53"
android:gravity="center_vertical|center_horizontal"
android:text="Get Firmware Version" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayoutBottom4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<Button
android:id="@+id/btn_startSwipe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.53"
android:text="Start Swipe/CTLS" />
<Button
android:id="@+id/btn_cancelSwipe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.53"
android:text="Cancel Swipe/CTLS" />
</LinearLayout>
</LinearLayout>
Step 5: Configure Method File
In the activity file, perform the following:
private IDT_UniMag myUniMagReader = null;
private TextView connectStatusTextView;
private TextView textLog;
private TextView lcdLog;
private Button btnGetFirmware;
private Button btnStartSwipe;
private Button btnCancelSwipe;
private Handler handler = new Handler();
private boolean isReaderConnected = false;
private String info = "";
private String detail = "";
private BluetoothAdapter mBtAdapter = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new Handler();
btnGetFirmware = (Button)findViewById(R.id.btn_getFirmware);
btnStartSwipe = (Button)findViewById(R.id.btn_startSwipe);
btnCancelSwipe = (Button)findViewById(R.id.btn_cancelSwipe);
textLog = (TextView)findViewById(R.id.textLog);
lcdLog = (TextView)findViewById(R.id.lcdLog);
connectStatusTextView = (TextView)findViewById(R.id.status_text);
if(myUniMagReader!=null){
myUniMagReader.unregisterListen();
myUniMagReader.release();
myUniMagReader = null;
}
myUniMagReader = new IDT_UniMag(this,this);
myUniMagReader.device_setDeviceType(DEVICE_TYPE.DEVICE_UNIMAG);
myUniMagReader.registerListen();
}
private Runnable doUpdateLabel = new Runnable()
{
public void run()
{
if(!isReaderConnected){
connectStatusTextView.setText("UniMag DISCONNECTED");
}
else{
connectStatusTextView.setText("UniMag CONNECTED");
}
}
};
@Override
public void deviceConnected() {
isReaderConnected = true;
handler.post(doUpdateLabel);
}
@Override
public void deviceDisconnected() {
isReaderConnected = false;
handler.post(doUpdateLabel);
}
-Implement protocol delegate com.idtechproducts.device.OnReceiverListener.swipeMSRData() to receive unsolicited card swipe data.
private Runnable doUpdateStatus = new Runnable()
{
public void run()
{
lcdLog.setText(info);
textLog.setText(detail);
}
};
@Override
public void swipeMSRData(IDTMSRData card) {
if (card.cardData[0] != (byte)0x01 && card.track1Length == 0 && card.track2Length == 0 && card.track3Length == 0)
info = "Swipe/Tap data didn't read correctly";
else
info = "Swipe/Tap Read Successfully";
detail = Common.parse_MSRData(myUniMagReader.device_getDeviceType(), card);
handler.post(doUpdateStatus);
}
- Implement the button press methods
btnGetFirmware.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
info = "Getting Firmware\n";
detail = "";
handler.post(doUpdateStatus);
StringBuilder sb = new StringBuilder();
int ret = mUniMagReader.device_getFirmwareVersion(sb);
if (ret == ErrorCode.SUCCESS) {
info += "Firmware Version: " + sb.toString();
detail = "";
handler.post(doUpdateStatus);
}
else {
info += "GetFirmwareVersion: Failed\n";
info += "Status: "+ myUniMagReader.device_getResponseCodeString(ret)+"";
detail = "";
handler.post(doUpdateStatus);
}
}
});
btnStartSwipe.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
detail = "";
info = "Starting Swipe/Tap Transaction\n";
handler.post(doUpdateStatus);
myUniMagReader.msr_startMSRSwipe();
}
});
btnCancelSwipe.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
detail = "";
info = "Cancelling Swipe/Tap Transaction\n";
handler.post(doUpdateStatus);
myUniMagReader.msr_cancelMSRSwipe();
}
});
Complete code listing
package com.example.Unimag_sdk_tutorial;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Set;
import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends Activity implements OnReceiverListener{
private IDT_UniMag myUniMagReader = null;
private TextView connectStatusTextView;
private TextView textLog;
private TextView lcdLog;
private Button btnGetFirmware;
private Button btnStartSwipe;
private Button btnCancelSwipe;
private Handler handler = new Handler();
private boolean isReaderConnected = false;
private String info = "";
private String detail = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new Handler();
btnGetFirmware = (Button)findViewById(R.id.btn_getFirmware);
btnStartSwipe = (Button)findViewById(R.id.btn_startSwipe);
btnCancelSwipe = (Button)findViewById(R.id.btn_cancelSwipe);
textLog = (TextView)findViewById(R.id.textLog);
lcdLog = (TextView)findViewById(R.id.lcdLog);
connectStatusTextView = (TextView)findViewById(R.id.status_text);
if(myUniMagReader!=null){
myUniMagReader.unregisterListen();
myUniMagReader.release();
myUniMagReader = null;
}
myUniMagReader = new IDT_UniMag(this,this);
myUniMagReader.device_setDeviceType(DEVICE_TYPE.DEVICE_UNIMAG);
myUniMagReader.registerListen();
loadXMLfile();
btnGetFirmware.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
info = "Getting Firmware\n";
detail = "";
handler.post(doUpdateStatus);
StringBuilder sb = new StringBuilder();
int ret = myUniMagReader.device_getFirmwareVersion(sb);
if (ret == ErrorCode.SUCCESS) {
info += "Firmware Version: " + sb.toString();
detail = "";
handler.post(doUpdateStatus);
}
else {
info += "GetFirmwareVersion: Failed\n";
info += "Status: "+ myUniMagReader.device_getResponseCodeString(ret)+"";
detail = "";
handler.post(doUpdateStatus);
}
}
});
btnStartSwipe.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
detail = "";
info = "Starting Swipe/Tap Transaction\n";
handler.post(doUpdateStatus);
myUniMagReader.msr_startMSRSwipe();
}
});
btnCancelSwipe.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
detail = "";
info = "Cancelling Swipe/Tap Transaction\n";
handler.post(doUpdateStatus);
myUniMagReader.msr_cancelMSRSwipe();
}
});
}
@Override
public void ICCNotifyInfo(byte[] arg0, String arg1) {
}
@Override
public void LoadXMLConfigFailureInfo(int arg0, String arg1) {
}
@Override
public void autoConfigCompleted(StructConfigParameters arg0) {
}
@Override
public void autoConfigProgress(int arg0) {
}
private Runnable doUpdateLabel = new Runnable()
{
public void run()
{
if(!isReaderConnected){
connectStatusTextView.setText("UniMag DISCONNECTED");
}
else{
connectStatusTextView.setText("UniMag CONNECTED");
}
}
};
@Override
public void deviceConnected() {
isReaderConnected = true;
handler.post(doUpdateLabel);
}
@Override
public void deviceDisconnected() {
isReaderConnected = false;
handler.post(doUpdateLabel);
}
private void printTags(IDTEMVData emvData)
{
}
@Override
public void emvTransactionData(IDTEMVData emvData) {
}
public void lcdDisplay(int mode, String[] lines, int timeout) {
}
@Override
public void msgAudioVolumeAjustFailed() {
}
@Override
public void msgRKICompleted(String arg0) {
}
@Override
public void msgToConnectDevice() {
}
private Runnable doUpdateStatus = new Runnable()
{
public void run()
{
lcdLog.setText(info);
textLog.setText(detail);
}
};
@Override
public void swipeMSRData(IDTMSRData card) {
if (card.cardData[0] != (byte)0x01 && card.track1Length == 0 && card.track2Length == 0 && card.track3Length == 0)
info = "Swipe/Tap data didn't read correctly";
else
info = "Swipe/Tap Read Successfully";
detail = Common.parse_MSRData(myUniMagReader.device_getDeviceType(), card);
handler.post(doUpdateStatus);
}
@Override
public void timeout(int arg0) {
}
private String getXMLFileFromRaw(String fileName ,int res){
String fileNameWithPath = null;
fileNameWithPath = fileName;
String newFilename = fileName;
try {
InputStream in = getResources().openRawResource(res);
int length = in.available();
byte [] buffer = new byte[length];
in.read(buffer);
in.close();
deleteFile(fileNameWithPath);
FileOutputStream fout = openFileOutput(fileNameWithPath, MODE_PRIVATE);
fout.write(buffer);
fout.close();
File fileDir = this.getFilesDir();
fileNameWithPath = fileDir.getParent() + java.io.File.separator + fileDir.getName();
fileNameWithPath += java.io.File.separator+newFilename;
} catch(Exception e){
e.printStackTrace();
fileNameWithPath = null;
}
return fileNameWithPath;
}
private String getConfigurationFileFromRaw( ){
return getXMLFileFromRaw("idt_unimagcfg_default.xml",R.raw.idt_unimagcfg_default);
}
private boolean isFileExist(String path) {
if(path==null)
return false;
File file = new File(path);
if (!file.exists()) {
return false ;
}
return true;
}
private void loadXMLfile(){
String fileNameWithPath = getConfigurationFileFromRaw();
if(!isFileExist(fileNameWithPath)) {
fileNameWithPath = null;
}
myUniMagReader.config_setXMLFileNameWithPath(fileNameWithPath);
Log.d("Demo Info >>>>>","loadingConfigurationXMLFile begin.");
myUniMagReader.config_loadingConfigurationXMLFile(true);
}
}