IDTech Android SDK Guide  1.00.133
API reference for SecureMag
Sample Project Tutorial Android Studio

Using Android Studio, we will create a sample project that will interface with the SecureMag 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

AS_NewProject1.JPG
AS_NewProject2.JPG
AS_NewProject3.JPG
AS_NewProject4.JPG
AS_NewProject5.JPG

Step 2: Import IDTechSDK for SecureMag

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 SecureMag. 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
AS_DesignInterface.JPG

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="SecureMag 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:

// declaring the instance of the SecureMagReader;
private IDT_SecureMag mySecureMagReader = 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(mySecureMagReader!=null){
mySecureMagReader.unregisterListen();
mySecureMagReader.release();
mySecureMagReader = null;
}
mySecureMagReader = new IDT_SecureMag(this,this);
mySecureMagReader.device_setDeviceType(DEVICE_TYPE.DEVICE_SECUREMAG);
mySecureMagReader.registerListen();
}
private Runnable doUpdateLabel = new Runnable()
{
public void run()
{
if(!isReaderConnected){
connectStatusTextView.setText("SecureMag DISCONNECTED");
}
else{
connectStatusTextView.setText("SecureMag 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(mySecureMagReader.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 = mSecureMagReader.device_getFirmwareVersion(sb);
    if (ret == ErrorCode.SUCCESS) {
    info += "Firmware Version: " + sb.toString();
    detail = "";
    handler.post(doUpdateStatus);
    }
    else {
    info += "GetFirmwareVersion: Failed\n";
    info += "Status: "+ mySecureMagReader.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);
    mySecureMagReader.msr_startMSRSwipe();
    }
    });
    btnCancelSwipe.setOnClickListener(new Button.OnClickListener(){
    public void onClick(View v) {
    detail = "";
    info = "Cancelling Swipe/Tap Transaction\n";
    handler.post(doUpdateStatus);
    mySecureMagReader.msr_cancelMSRSwipe();
    }
    });

Complete code listing

package com.example.securemag_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{
// declaring the instance of the SecureMagReader;
private IDT_SecureMag mySecureMagReader = 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(mySecureMagReader!=null){
mySecureMagReader.unregisterListen();
mySecureMagReader.release();
mySecureMagReader = null;
}
mySecureMagReader = new IDT_SecureMag(this,this);
mySecureMagReader.device_setDeviceType(DEVICE_TYPE.DEVICE_SECUREMAG);
mySecureMagReader.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 = mySecureMagReader.device_getFirmwareVersion(sb);
if (ret == ErrorCode.SUCCESS) {
info += "Firmware Version: " + sb.toString();
detail = "";
handler.post(doUpdateStatus);
}
else {
info += "GetFirmwareVersion: Failed\n";
info += "Status: "+ mySecureMagReader.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);
mySecureMagReader.msr_startMSRSwipe();
}
});
btnCancelSwipe.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
detail = "";
info = "Cancelling Swipe/Tap Transaction\n";
handler.post(doUpdateStatus);
mySecureMagReader.msr_cancelMSRSwipe();
}
});
}
@Override
public void ICCNotifyInfo(byte[] arg0, String arg1) {
// TODO Auto-generated method stub
}
@Override
public void LoadXMLConfigFailureInfo(int arg0, String arg1) {
// TODO Auto-generated method stub
}
@Override
public void autoConfigCompleted(StructConfigParameters arg0) {
// TODO Auto-generated method stub
}
@Override
public void autoConfigProgress(int arg0) {
// TODO Auto-generated method stub
}
private Runnable doUpdateLabel = new Runnable()
{
public void run()
{
if(!isReaderConnected){
connectStatusTextView.setText("SecureMag DISCONNECTED");
}
else{
connectStatusTextView.setText("SecureMag 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() {
// TODO Auto-generated method stub
}
@Override
public void msgRKICompleted(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void msgToConnectDevice() {
// TODO Auto-generated method stub
}
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(mySecureMagReader.device_getDeviceType(), card);
handler.post(doUpdateStatus);
}
@Override
public void timeout(int arg0) {
// TODO Auto-generated method stub
}
private String getXMLFileFromRaw(String fileName ,int res){
//the target filename in the application path
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();
// to refer to the application path
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(){
//load the XML configuration file
String fileNameWithPath = getConfigurationFileFromRaw();
if(!isFileExist(fileNameWithPath)) {
fileNameWithPath = null;
}
// Network operation is prohibited in the UI Thread if target API is 11 or above.
// If target API is 11 or above, please use AsyncTask to avoid errors.
mySecureMagReader.config_setXMLFileNameWithPath(fileNameWithPath);
Log.d("Demo Info >>>>>","loadingConfigurationXMLFile begin.");
mySecureMagReader.config_loadingConfigurationXMLFile(true);
}
}