Using Eclipse, we will create a sample project that will interface with the KioskIII 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
Step 2: Import IDTechSDK for Kiosk III
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 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
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:
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{
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) {
}
@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("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() {
}
@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) {
}
@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;
}
myUniPayReader.config_setXMLFileNameWithPath(fileNameWithPath);
Log.d("Demo Info >>>>>","loadingConfigurationXMLFile begin.");
myUniPayReader.config_loadingConfigurationXMLFile(true);
}
@Override
public void dataInOutMonitor(byte[] arg0, boolean arg1) {
}
@Override
public void msgBatteryLow() {
}
@Override
public void lcdDisplay(int mode, String[] lines, int timeout) {
}
}