I am trying to build an android application to read credit card / Smart card data form a Micro USB Smart Card reader. When I use this app from google play, it can read all card data successfully using my card reader: https://play.google.com/store/apps/details?id=com.scdroid.emvdemo&hl=en
According to developer's website they use this library to build this app: https://code.google.com/p/javaemvreader/
Unfortunately I tried to use the code in it but I am getting Terminal Exception :
sasc.terminal.TerminalException: No provider available
My Code looks like this:
protected void testSCReader() {
SmartCard smartCard = null;
CardConnection conn = null;
try {
conn = TerminalUtil.connect(TerminalUtil.State.CARD_PRESENT);
if(conn == null){
rawT.append("TerminalUtil.connect returned null");
return;
}
SessionProcessingEnv env = new SessionProcessingEnv();
env.setReadMasterFile(true);
env.setProbeAllKnownAIDs(true);
CardSession cardSession = CardSession.createSession(conn, env);
smartCard = cardSession.initCard();
EMVSession session = EMVSession.startSession(smartCard, conn);
session.initContext();
for (EMVApplication app : smartCard.getEmvApplications()) {
session.selectApplication(app);
session.initiateApplicationProcessing(); //GET PROCESSING OPTIONS + READ RECORD(s)
if (!app.isInitializedOnICC()) {
//Skip if GPO failed (might not be a EMV card, or conditions not satisfied)
continue;
}
//Be VERY CAREFUL when setting this, as it WILL block the application if the PIN Try Counter reaches 0
//Must be combined with a PIN callback handler
EMVTerminal.setDoVerifyPinIfRequired(false);
session.prepareTransactionProcessing();
//Check if the transaction processing skipped some steps
if(app.getATC() == -1 || app.getLastOnlineATC() == -1) {
session.testReadATCData(); //ATC, Last Online ATC
}
//If PIN Try Counter has not been read, try to read it
if(app.getPINTryCounter() == -1) {
session.readPINTryCounter();
}
if(!app.isTransactionLogProcessed()) {
session.checkForTransactionLogRecords();
}
//testGetChallenge (see if the app supports generating an unpredictable number)
session.testGetChallenge();
}
System.out.println("\n");
System.out.println("Finished Processing card.");
System.out.println("Now dumping card data in a more readable form:");
System.out.println("\n");
rawT.append("Finished Processing card.");
//See the finally clause
} catch (TerminalException ex) {
ex.printStackTrace(System.err);
rawT.append(ex.toString());
} catch (UnsupportedCardException ex) {
System.err.println("Unsupported card: " + ex.getMessage());
rawT.append(ex.toString());
if (conn != null) {
//System.err.println("ATR: " + Util.prettyPrintHexNoWrap(conn.getATR()));
System.err.println(ATR_DB.searchATR(conn.getATR()));
}
} catch (SmartCardException ex) {
ex.printStackTrace(System.err);
rawT.append(ex.toString());
} finally {
if (conn != null){
try{
conn.disconnect(true);
}catch(TerminalException ex){
ex.printStackTrace(System.err);
}
}
if (smartCard != null) {
try {
/* int indent = 0;
Log.d("FHD_DBG","======================================");
Log.d("FHD_DBG"," [Smart Card] ");
Log.d("FHD_DBG","======================================");
smartCard.dump(Log.d, indent);
Log.d("FHD_DBG","---------------------------------------");
Log.d("FHD_DBG"," FINISHED ");
Log.d("FHD_DBG","---------------------------------------");
//Log.getPrintWriter().flush();*/
rawT.append(smartCard.toString());
} catch (RuntimeException ex) {
ex.printStackTrace(System.err);
}
Log.d("FHD_DBG","");
} else if (conn != null) {
rawT.append(new sasc.iso7816.ATR(conn.getATR()).toString());
}
}
}
I received the same problem, java.lang.ClassNotFoundException: javax.smartcardio.TerminalFactory. This is because javax.smartcardio.* is not available in the java environment which comes with the android java compiler, its available in JRE.