IDTech Android SDK Guide  1.00.091
API reference for Kiosk III/IV
Sample Project Tutorial

Using Eclipse, we will create a sample project that will interface with the Kiosk III/IV and will perform the following activities:

  • Auto-Connect and display connection status
  • Get Device Firmware
  • Start/Cancel CTLS Transaction

Listeners:

  • Listener to detect device connected
  • Listener to detect device disconnected
  • Listener to receive CTLS tag data

Step 1: Create New Project

Create a new Android Application project in Eclipse as an Empty Activity

NewProjAugusta.png

Step 2: Import IDTechSDK for Kiosk III/IV

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 Kiosk III/IV and for EMV LCD display. 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 CTLS
    • Cancel CTLS
layout.png

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="DEVICE DISCONNECTED"
android:textColor="#FFFFFF" />
<LinearLayout
android:id="@+id/linearLayoutBottom2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<Button
android:id="@+id/btn_StartEMV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.53"
android:gravity="center_vertical|center_horizontal"
android:text="Start CTLS" />
<Button
android:id="@+id/btn_CancelEMV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.53"
android:gravity="center_vertical|center_horizontal"
android:text="Cancel CTLS" />
</LinearLayout>
<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>

Step 5: Configure Method File

In the activity file, perform the following:

// declaring the instance of the UniPayReader;
private IDT_KioskIII myUniPayReader = null;
private TextView connectStatusTextView;
private TextView textLog;
private TextView lcdLog;
private Button btnGetFirmware;
private Button btnStartSwipe;
private Button btnCancelSwipe;
private Button btnStartEMV;
private Button btnCancelEMV;
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();
btnStartEMV = (Button)findViewById(R.id.btn_StartEMV);
btnCancelEMV = (Button)findViewById(R.id.btn_CancelEMV);
btnGetFirmware = (Button)findViewById(R.id.btn_getFirmware);
textLog = (TextView)findViewById(R.id.textLog);
lcdLog = (TextView)findViewById(R.id.lcdLog);
connectStatusTextView = (TextView)findViewById(R.id.status_text);
if(myUniPayReader!=null){
myUniPayReader.unregisterListen();
myUniPayReader.release();
myUniPayReader = null;
}
myUniPayReader = new IDT_KioskIII(this,this);
myUniPayReader.registerListen();
loadXMLfile();
}
private Runnable doUpdateLabel = new Runnable()
{
public void run()
{
if(!isReaderConnected){
connectStatusTextView.setText("KIOSKIII DISCONNECTED");
}
else{
connectStatusTextView.setText("KIOSKIII 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.emvTransactionData() to report transaction results
    public void emvTransactionData(IDTEMVData emvData) {
    if (emvData == null) return;
    detail += Common.emvErrorCodes(emvData.result);
    detail += "\r\n";
    detail += "\r\nCTLS Transaction response:\r\n";
    if (emvData.unencryptedTags != null && !emvData.unencryptedTags.isEmpty())
    {
    detail += "Unencrypted Tags:\r\n";
    Set<String> keys = emvData.unencryptedTags.keySet();
    for(String key: keys){
    detail += key + ": ";
    byte[] data = emvData.unencryptedTags.get(key);
    detail += Common.getHexStringFromBytes(data) + "\r\n";
    }
    }
    if (emvData.maskedTags!= null && !emvData.maskedTags.isEmpty())
    {
    detail += "Masked Tags:\r\n";
    Set<String> keys = emvData.maskedTags.keySet();
    for(String key: keys){
    detail += key + ": ";
    byte[] data = emvData.maskedTags.get(key);
    detail += Common.getHexStringFromBytes(data) + "\r\n";
    }
    }
    if (emvData.encryptedTags != null && !emvData.encryptedTags.isEmpty())
    {
    detail += "Encrypted Tags:\r\n";
    Set<String> keys = emvData.encryptedTags.keySet();
    for(String key: keys){
    detail += key + ": ";
    byte[] data = emvData.encryptedTags.get(key);
    detail += Common.getHexStringFromBytes(data) + "\r\n";
    }
    }
    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 = myUniPayReader.device_getFirmwareVersion(sb);
    if (ret == ErrorCode.SUCCESS) {
    info += "Firmware Version: " + sb.toString();
    detail = "";
    handler.post(doUpdateStatus);
    }
    else {
    info += "GetFirmwareVersion: Failed\n";
    info += "Status: "+ myUniPayReader.device_getResponseCodeString(ret)+"";
    detail = "";
    handler.post(doUpdateStatus);
    }
    }
    });
    btnStartEMV.setOnClickListener(new Button.OnClickListener(){
    public void onClick(View v) {;
    detail = "";
    info = "Starting CTLS Transaction\n";
    handler.post(doUpdateStatus);
    myUniPayReader.ctls_startTransaction(1.00, 0.00, 0, 30, null);
    }
    });
    btnCancelEMV.setOnClickListener(new Button.OnClickListener(){
    public void onClick(View v) {
    detail = "";
    info = "Canceling CTLS Transaction\n";
    handler.post(doUpdateStatus);
    myUniPayReader.ctls_cancelTransaction();
    }
    });

Complete code listing

package com.example.android_sdk_tutorial;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Set;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements OnReceiverListener{
// declaring the instance of the UniPayReader;
private IDT_KioskIII myUniPayReader = null;
private TextView connectStatusTextView;
private TextView textLog;
private TextView lcdLog;
private Button btnGetFirmware;
private Button btnStartEMV;
private Button btnCancelEMV;
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();
btnStartEMV = (Button)findViewById(R.id.btn_StartEMV);
btnCancelEMV = (Button)findViewById(R.id.btn_CancelEMV);
btnGetFirmware = (Button)findViewById(R.id.btn_getFirmware);
textLog = (TextView)findViewById(R.id.textLog);
lcdLog = (TextView)findViewById(R.id.lcdLog);
connectStatusTextView = (TextView)findViewById(R.id.status_text);
if(myUniPayReader!=null){
myUniPayReader.unregisterListen();
myUniPayReader.release();
myUniPayReader = null;
}
myUniPayReader = new IDT_KioskIII(this,this);
myUniPayReader.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 = myUniPayReader.device_getFirmwareVersion(sb);
if (ret == ErrorCode.SUCCESS) {
info += "Firmware Version: " + sb.toString();
detail = "";
handler.post(doUpdateStatus);
}
else {
info += "GetFirmwareVersion: Failed\n";
info += "Status: "+ myUniPayReader.device_getResponseCodeString(ret)+"";
detail = "";
handler.post(doUpdateStatus);
}
}
});
btnStartEMV.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {;
detail = "";
info = "Starting CTLS Transaction\n";
handler.post(doUpdateStatus);
myUniPayReader.ctls_startTransaction(1.00, 0.00, 0, 30, null);
}
});
btnCancelEMV.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
detail = "";
info = "Canceling CTLS Transaction\n";
handler.post(doUpdateStatus);
myUniPayReader.ctls_cancelTransaction();
}
});
}
@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("KIOSKIII DISCONNECTED");
}
else{
connectStatusTextView.setText("KIOSKIII CONNECTED");
}
}
};
@Override
public void deviceConnected() {
isReaderConnected = true;
handler.post(doUpdateLabel);
}
@Override
public void deviceDisconnected() {
isReaderConnected = false;
handler.post(doUpdateLabel);
}
@Override
public void emvTransactionData(IDTEMVData emvData) {
if (emvData == null) return;
detail += Common.emvErrorCodes(emvData.result);
detail += "\r\n";
detail += "\r\nCTLS Transaction response:\r\n";
if (emvData.unencryptedTags != null && !emvData.unencryptedTags.isEmpty())
{
detail += "Unencrypted Tags:\r\n";
Set<String> keys = emvData.unencryptedTags.keySet();
for(String key: keys){
detail += key + ": ";
byte[] data = emvData.unencryptedTags.get(key);
detail += Common.getHexStringFromBytes(data) + "\r\n";
}
}
if (emvData.maskedTags!= null && !emvData.maskedTags.isEmpty())
{
detail += "Masked Tags:\r\n";
Set<String> keys = emvData.maskedTags.keySet();
for(String key: keys){
detail += key + ": ";
byte[] data = emvData.maskedTags.get(key);
detail += Common.getHexStringFromBytes(data) + "\r\n";
}
}
if (emvData.encryptedTags != null && !emvData.encryptedTags.isEmpty())
{
detail += "Encrypted Tags:\r\n";
Set<String> keys = emvData.encryptedTags.keySet();
for(String key: keys){
detail += key + ": ";
byte[] data = emvData.encryptedTags.get(key);
detail += Common.getHexStringFromBytes(data) + "\r\n";
}
}
handler.post(doUpdateStatus);
}
@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) {
}
@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 configuratin 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.
myUniPayReader.config_setXMLFileNameWithPath(fileNameWithPath);
Log.d("Demo Info >>>>>","loadingConfigurationXMLFile begin.");
myUniPayReader.config_loadingConfigurationXMLFile(true);
}
@Override
public void dataInOutMonitor(byte[] arg0, boolean arg1) {
// TODO Auto-generated method stub
}
@Override
public void msgBatteryLow() {
// TODO Auto-generated method stub
}
@Override
public void lcdDisplay(int mode, String[] lines, int timeout) {
// TODO Auto-generated method stub
}
}