摘要】随着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

更多相关文章

  1. android获取Mac地址和IP 地址
  2. 在webView 中使用JS 调用 Android(安卓)/ IOS的函数 Function
  3. Android———从GitHub上下载源码的方法【Written By KillerLege
  4. 栈处理问题
  5. android2.1短信应用
  6. android N 获取手机内存信息方案
  7. 由浅入深全面剖析ThreadLocal
  8. android头像设置:从本地照片库或拍照获取并剪裁
  9. DexClassLoader 实现 Android(安卓)插件加载

随机推荐

  1. springboot+vue前后端分离项目
  2. [cobra]-强大的CLI应用程序库
  3. 订单和产品的多对多表关系在crudapi系统
  4. 你必须掌握的 21 个 Java 核心技术
  5. 华为麒麟990 5G芯片重磅发布!全球首个旗舰
  6. 程序员最大的遗憾:在大学时忽略了数学
  7. 最强深度学习优化器Ranger开源:RAdam+Look
  8. “高级工程师”没用!你应该成为一名 “成
  9. 数据科学家年薪12万美元算高吗?我爬取近6
  10. 20201112 装饰器之函数即变量