NFC开发入门篇
来源:互联网 发布:数据库管理系统产品 编辑:程序博客网 时间:2024/05/16 16:59
之前做过一些关于NFC的项目,比如手机羊城通卡芯片的充值,粤通卡的充值(与微信的羊城通充值功能类似),NFC功能是需要硬件的支持的,不过现在越来越多手机支持NFC功能了,所以这里简单的介绍它的开发流程吧。
一、NFC简介
NFC(Near Field Communication)近距离无线通信技术。工作模式分为两种:卡模式(Card emulation)、点对点模式(P2P mode)。这里主要是介绍卡模式的的开发,卡模式的开发又分为机卡通道和非机卡通道两种,机卡通道就是手机卡里面集成了相关的芯片,一卡多用,卡离开手机之后无法工作,比如手机卡里面又附带羊城通的芯片的功能,这样既可以打电话又可以刷公交和地铁。非机卡通道就是卡和手机是分开使用的,就是平常使用单独一张公交卡一样。
二、开发流程
1、非机卡通道模式
(1)在AndroidManifest.xml中声明权限
<uses-permission android:name=”android.permission.NFC” /><uses-feature android:name=”android.hardware.nfc” android:required=”true” />
(2)在AndroidManifest.xml 中的activity中声明可以处理的NFC Tag。
当手机开启了NFC,并且检测到一个TAG后,TAG分发系统会自动创建一个封装了NFC TAG信息的intent。如果多于一个应用程序能够处理这个intent的话,那么手机就会弹出一个框,让用户选择处理该TAG的Activity。 TAG分发系统定义了3中intent。按优先级从高到低排列为:
NDEF_DISCOVERED, TECH_DISCOVERED,TAG_DISCOVERED
当Android设备检测到有NFC Tag靠近时,会根据Action申明的顺序给对应的Activity 发送含NFC消息的 Intent。在某个Activity中添加以下的代码:
(3)编写xml文件。
在res目录下新建xml,编写上面红色框的xml文件:nfc_tech_filter,声明要处理的NFC Tag。
(4)测试
打开Android手机的NFC,运行程序,并把羊城通靠近手机背部,这样就可以看到可以处理NFC卡的应用。
(5)设置Activity
在onCreate()方法里添加以下代码。
nfcAdapter = NfcAdapter.getDefaultAdapter(this);pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);//区分系统版本sysVersion = Integer.parseInt(VERSION.SDK);if(sysVersion<19){ onNewIntent(getIntent());}
在onPause里面解除
@Override protected void onPause() { super.onPause(); if (nfcAdapter != null){ nfcAdapter.disableForegroundDispatch(this); disableReaderMode(); } }
重写OnnewIntent方法,在低于4.4系统时会用到这方法。
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); //获取数据 final Parcelable p = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); Log.d("NFCTAG", intent.getAction()); board.setText((p != null) ? CardReader.load(p) : null); if(p==null){ board.setText("the intent=="+intent); }else{ //board.setText("the intent !=null"); } }
重写onResume方法
public static String[][] TECHLISTS;public static IntentFilter[] FILTERS;static { try {TECHLISTS = new String[][] { { IsoDep.class.getName() },{ NfcV.class.getName() }, { NfcF.class.getName() }, };FILTERS = new IntentFilter[] { new IntentFilter( NfcAdapter.ACTION_TECH_DISCOVERED, "*/*") }; } catch (Exception e) { } }
//4.4以上系统,在这个页面,多次发现标签,onresume只执行一次,4.4以下的会执行多次,但是onNewIntent()和enableReaderMode()都能够执行多次@Override protected void onResume() { super.onResume(); if (nfcAdapter != null){ nfcAdapter.enableForegroundDispatch(this, pendingIntent, CardReader.FILTERS, CardReader.TECHLISTS); enableReaderMode(); } Log.e("NFC----", IsoDep.class.getName()); }
(6)与卡片的交互方法的实现
public String tagDiscovered(Tag tag) { Log.i(TAG, "New tag discovered"); IsoDep isoDep = IsoDep.get(tag); System.out.println("isodep=="+isoDep); if (isoDep != null) { try { isoDep.connect(); //读余额 byte[] bal = new byte[]{(byte) 0x80,(byte) 0x5c,(byte) 0x00,(byte) 0x02,(byte) 0x04}; byte[] result = isoDep.transceive(bal); // 如果连接成功将返回 0x9000 int resultLength = result.length; byte[] statusWord = { result[resultLength - 2],result[resultLength - 1] }; byte[] payload = Arrays.copyOf(result,resultLength - 2); if (Arrays.equals(SELECT_OK_SW, statusWord)) { //余额结果保存在前4位 int n = Util.toInt(payload, 0, 4); if (n > 100000 || n < -100000) n -= 0x80000000; String s = toAmountString(n / 100.0f);//余额 return "余额=="+s; } } catch (IOException e) { Log.e(TAG, "Error communicating with card: " + e.toString()); } } return null; } public static String load(Parcelable parcelable) { // 从Parcelable筛选出各类NFC标准数据 final Tag tag = (Tag) parcelable; return tagDiscovered(tag); }
至此非机卡通道方式的代码设置结束。
2、机卡通道模式
(1)选择API
使用的API是Open mobile api,这是基于android平台的用于APP与SIM卡建立通信连接的规范。添加的方法和添加其它版本API一样。
(2) 添加权限
<uses-permission android:name="org.simalliance.openmobileapi.SMARTCARD"/><uses-library android:name="org.simalliance.openmobileapi" android:required="true" />
(3)在Activity类实现以下代码
SEService mSeService = new SEService(this, this);
实现回调的方法:
@Override public void serviceConnected(SEService service) {// DebugLog.i(LOG_TAG, "service connected");// 可以读取卡的数据了 NFCResponeController.getCardInfo(mSeService); } @Override protected void onDestroy() { if (mSeService != null && mSeService.isConnected()) { mSeService.shutdown(); } super.onDestroy(); }/** * 传输API访问卡,执行command命令 * @param aid AID标识字节 * @param command 执行命令字节 至少4个字节 * @param mseService SE服务 * @return resulteStr 卡返回字节 */ public static byte[] queryCardCommand(byte[] aid,byte[] command,SEService mseService) { try { Reader[] readers = mseService.getReaders(); if (readers.length < 1) return null; Session session = readers[0].openSession(); Channel channel = session.openLogicalChannel(aid); byte[] respApdu = channel.transmit(command); channel.close();// DebugLog.d(DebugLog_TAG,"读卡接口结果:"+NFCUtil.bytesToHexString(respApdu)); return respApdu; }catch(java.lang.IllegalArgumentException e) {// DebugLog.e(DebugLog_TAG, "ERROR<<<<<<<<发送命令至少4个字节"); return null; } catch (Exception e) {// DebugLog.e(DebugLog_TAG, "Error occured:", e); return null; } }
3、参考内容
参考的博客
三、总结
刚开始接触的时候会不知道怎么入手,但这些基本的操作是需要掌握的,用多几次之后,就可以算入门了。
- NFC开发入门篇
- nfc入门
- [NFC]NFC App开发
- [NFC]NFC App开发
- Android NFC开发-理论篇
- Android NFC开发-实践篇
- nfc开发
- nfc开发
- NFC开发
- Android NFC编程入门
- NFC设计开发
- BlackBerry NFC开发参考资料
- android NFC开发实例
- Android NFC 开发实例
- Android NFC 开发教程
- Android NFC 开发实例
- Android NFC开发
- Android NFC 开发实例 .
- python连接mysql处理数据pymysql模块的使用
- 玩转iOS开发:集成 Union Pay - 银联支付
- 如何选择适合的微信号码开通状态检测工具
- 人脸识别之人脸对齐(三)--AAM算法
- 数据库置疑的处理步骤(以数据库'shop07'为例)
- NFC开发入门篇
- linux下git的配置
- 《The.Go.Programming.Language.2015.11》之 reflect
- 青岛亚洲赛网络赛--1005(超级水)
- 对iOS10新增Api的详细探究
- JDK1.8中如何用ScriptEngine动态执行JS
- Web服务器是如何使用JSP来创建网页
- Beautiful Year
- 像360悬浮窗那样,用WindowManager做一个炫酷的悬浮迷你音乐盒(上)