Android通过OMA获得ESE的CPLC
【摘要】随着NFC支付的不断发展,以及NFC城市一卡通的不断普及,越来越多的大众开始接触到NFC技术带来的安全以及便捷,本文主要针对ANDROID如何通过OMA获取ESE的CPLC作下简单的介绍
OMA调用的流程图如下:
public class OMASEServiceCallBack implements SEService.CallBack { @Override public void serviceConnected(SEService seService) { Log.d(TAG, "connect to SEService"); mSEservice = seService; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mContext = getApplicationContext(); setContentView(R.layout.activity_cplc_layout); mBtn_sendCommand = (Button) findViewById(R.id.bt_sendCommand); mBtn_sendCommand.setOnClickListener(this); mTxtShowCplc = (TextView) findViewById(R.id.txt_showCplc); getSEService(); }
首先我们得获取SEService的对象,上述的代码实现了这一点,当我们new SEService(mContext, mCallBack)时,会提供一个callback,在SEService的构造函数里面,会去bind SmartcardService,一旦bind成功,会通过callback回调上面的serviceConnected方法,这时候,就可以拿到SEService对象了,这个操作一般方法onCreate()方法里面执行。
private Reader getEseReader(Reader[] readers){ Reader eseReader = null; Log.d(TAG, "getReader start"); if(readers != null && readers.length >= 1){ int idx = 0; for(Reader reader : readers){ if(reader.getName().startsWith("eSE")){ break; } idx++; } if(idx < readers.length){ eseReader = readers[idx]; }else{ Log.d(TAG, "eSE reader not exist"); } }else{ Log.d(TAG, "_readers is null"); } Log.d(TAG,"getReader end"); return eseReader; }
接下来,我们需要获得eSEReader,通过SEService的getReaders()方法,我们可以获得一个Readers的数组,这里用reader.getName().startsWith(“eSE”)筛选出来。
private Session initSession(Reader[] readers) { Log.d(TAG, "initSession start"); Session session = null; try { session = getEseReader(readers).openSession(); } catch (Exception e) { e.printStackTrace(); } Log.d(TAG, "initSession end"); if (session == null){ Log.d(TAG, "session null, re-connect"); if (mSEservice != null && mSEservice.isConnected()) mSEservice.shutdown(); SEService seService = getSEService(); if (seService == null){ return null; } mReaders = seService.getReaders(); try { session = getEseReader(mReaders).openSession(); } catch (Exception e) { e.printStackTrace(); } Log.d(TAG, "re-connect end session is " + session); } return session; }
拿到eSEReader之后,接下来就是openSession的操作了,这里我们加入了一个re-connect机制,如果第一次get失败了,会重新get一次。
public static final String openChannelCommand = "A000000151000000";public static final String getCplcCommand = "80CA9F7F00"; synchronized private boolean sendCommand() { boolean result = true; Session session = null; Channel channel = null; if (mSEservice == null) { Log.d(TAG, "init failed !!!"); return false; } try { if (mReaders == null) { mReaders = mSEservice.getReaders(); } session = initSession(mReaders); if (session == null) { return false; } byte[] openChannelAidByte = CplcUtils.hexStringToBytes(openChannelCommand); channel = session.openBasicChannel(openChannelAidByte); Log.d(TAG, "sendCommand openBasicChannel"); if (channel != null) { byte[] respSetstatus = channel.transmit(CplcUtils.hexStringToBytes(getCplcCommand)); mStrCplc = CplcUtils.bytesToHexString(respSetstatus); Log.d(TAG, "aid response" + mStrCplc); channel.close(); } session.close(); } catch (IOException e) { e.printStackTrace(); return false; } catch (Exception e1) { e1.printStackTrace(); return false; } finally { if (channel != null && !channel.isClosed()) { channel.close(); } if (session != null && !session.isClosed()) { session.close(); } } return true; }
最后就是openChannel以及sendCommand了,对于Ese来说,basicChannel和logicChannel都可以,我们这里打开的是BasicChannel,select的Aid为”A000000151000000”,当然如果我们把参数设置为null的话,也会用默认的Aid去执行,效果是一样的。Channel打开之后,通过transmit方法,就可以把查询CPLC的命令发送过去,正常情况下会成功返回9000结尾的一串数字,解析之后就是我们最终需要的CPLC了
完整的代码请见这里: http://download.csdn.net/download/shaoyuan1314520/10176536
更多相关文章
- android获取Mac地址和IP 地址
- 在webView 中使用JS 调用 Android(安卓)/ IOS的函数 Function
- Android———从GitHub上下载源码的方法【Written By KillerLege
- 栈处理问题
- android2.1短信应用
- android N 获取手机内存信息方案
- 由浅入深全面剖析ThreadLocal
- android头像设置:从本地照片库或拍照获取并剪裁
- DexClassLoader 实现 Android(安卓)插件加载