NFC-标签内容的读取
来源:互联网 发布:php默认登录页面 编辑:程序博客网 时间:2024/06/05 22:36
NFC即近场通信(Near Field Communication)的英文缩写.
读取NFC标签
当开发NFC的相关应用程序时,首先我们需要在AndroidManifest.xml清单文件中,配置相关内容。1、硬件要求:<uses-feature android:name="android.hardware.nfc" android:required="true" />2、权限要求:<uses-permission android:name="android.permission.NFC" />3.sdk版本要求:<uses-sdk android:minSdkVersion="14"/>4.NFC内容识别原理当一个Android设备用于扫描一个NFC标签时,其系统将使用自己的标签分派系统解码传入的有效荷载。这个标签分派系统会分析标签,将数据分类,并使用Intent启动一个应用程序接受数据。为使应用程序接受数据NFC数据,需要踢哪加一个Activity IntentFilter来监听某个Intent动作:a.NfcAdapter.ACTION_NDEF_DISCOVERED 优先级最高、也是最具体的NFC消息动作。使用这个动作的Intent包括MimeType和/或URI数据。最好的做法是只要有可能,就监听这个广播,因为其extra数据允许更加具体地定义要响应的标签。b.NfcAdapter.ACTION_TECH_DISCOVERED 当NFC技术已知、但是标签不包含数据(或者包含数据不能被映射为MineType或者URI)时广播这个动作。c.NfcAdapter.ACTION_DISCOVERED 如果从未知技术收到一个标签,则使用此Intent动作广播该标签。NFC两种识别过程:第一种:使用前台分派系统默认情况下,标签分派系统会根据标准的Intent解析过程确定哪个应用程序应该收到特定的标签,在Intent解析过程中,位于前台的Activity并不必其他应用程序优先级更高,因此,如果几个应用程序都被注册为接受扫描的标签,用户就需要选择使用哪个应用程序,即使此时你的应用程序位于前台。通过使用前台分派系统,可以指定特定的一个具有高优先级的Activity使得当它位于前台时成为默认接受标签的应用程序,使用NFCAdapter的enable/disableForegroundDispatch方法可以切换前台分派系统。只有当一个Activity位于前台时才能使用前台分派系统,所以应该在onResume和onPause处理程序内启用和禁用改系统。以下代码在onCreate方法中实现。nfcAdapter = NfcAdapter.getDefaultAdapter(this);Intent nfcIntent = new Intent(this, getClass());nfcIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);nfcPendingIntent = PendingIntent.getActivity(this, requestCode, nfcIntent, flags);IntentFilter ndefIntentFilter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);ndefIntentFilter.addCategory(Intent.CATEGORY_DEFAULT);try { ndefIntentFilter.addDataType("text/plain");} catch (IntentFilter.MalformedMimeTypeException e) { e.printStackTrace();}IntentFilter tagIntentFilter = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);tagIntentFilter.addCategory(Intent.CATEGORY_DEFAULT);IntentFilter techIntentFilter = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);techIntentFilter.addCategory(Intent.CATEGORY_DEFAULT);IntentFilterArray = new IntentFilter[]{ndefIntentFilter, tagIntentFilter, techIntentFilter};techListArray = new String[][]{ new String[]{ NfcF.class.getName() }};protected void onResume() { super.onResume(); nfcAdapter.enableForegroundDispatch( this, nfcPendingIntent, //用于打包Tag Intent的Intent IntentFilterArray, //用于声明想要拦截的Intent的Intent Filter数组 techListArray // 想要处理的标签技术 );}使用前台分派系统,返回的Intent是通过onNewIntent方法中获取到的。protected void onNewIntent(Intent intent){ String action = intent.getAction(); if(TextUtils.isEmpty(action)){ return; } if(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)){ parseNdef(intent); //方法实现在后面 }else if(NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)){ parseTech(intent);//方法实现在后面 }else if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)){ parseTag(intent); //方法实现在后面 }}第二种:一般识别过程一般识别过程就是不使用前台分排系统,这种情况和前台分派系统不一样,不需要进入到响应的Activity的前台(也就是当前Activity的可视化页面),但是她需要在响应的Activity对应的清单文件内容中添加IntentFilter。<activity android:name=".ShowActivity" android:launchMode="singleTop" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter></activity>一般情况下该Activity的启动模式为SingleTop或者SingleTask,是为了方便接受标签返回的Intent。而Intent的返回一般则该Activity生命周期方法onResume()中获得。protected void onResume(){ super.onReume(); Intent intent = getIntent(); String action = intent.getAction(); if(TextUtils.isEmpty(action)){ return; } if(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)){ parseNdef(intent); //方法实现在后面 }else if(NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)){ parseTech(intent);//方法实现在后面 }else if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)){ parseTag(intent); //方法实现在后面 }}
以上大概已经阐述清楚了NFC标签的识别过程,下面就阐述一下,如何具体识别NFC标签中包含的数据内容。
1、MifareClassic射频卡
一般来说,给予MifareClassic的射频卡,一般内存大小有3种:
1K: 16个分区(sector),每个分区4个块(block),每个块(block) 16个byte数据。
2K: 32个分区,每个分区4个块(block),每个块(block) 16个byte数据。
4K:64个分区,每个分区4个块(block),每个块(block) 16个byte数据。
2、NFC射频卡结构
读取NFC标签内容需要知道标签的结构,当然以上图片显示的是1kb大小的NFC射频卡。
要想获得想要的内容,需要获得数据区的数据,由图可知每个块(block)的大小为16字节(byte),当然为了准确获取数据取内容,还需要根据写标签的具体结构操作。
解析NFC方法代码(以上作注释的方法)
private String parseTag(Intent intent) { int sectorCount = 0; byte[] content = {}; Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); MifareClassic mifageClassic = MifareClassic.get(tag); try { mifageClassic.connect(); sectorCount = mifageClassic.getSectorCount(); int byteIndex = 0; for (int i = 1; i < sectorCount; i++) { boolean auth = mifageClassic.authenticateSectorWithKeyA(i,MifareClassic.KEY_DEFAULT); if (!auth) { return null; } int blockCount = mifageClassic.getBlockCountInSector(i); int blockIndex = mifageClassic.sectorToBlock(i); for (int j = 0; j < blockCount; j++) { if (j + 1 == blockCount) { continue; } byte buffer[] = new byte[16]; buffer = mifageClassic.readBlock(blockIndex); if (blockIndex == 4) { System.arraycopy(buffer, 9, content, byteIndex, 6); byteIndex += 6; } else { System.arraycopy(buffer, 0, content, byteIndex, 16); byteIndex += 16; } blockIndex++; Log.i("content_buffer" + blockIndex, new String(content)); } } String contentStr = new String(content); return contentStr; } catch (IOException e) { e.printStackTrace(); return null; } } private String parseNdef(Intent intent) { wait2Scan(true); Parcelable[] messages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); NdefMessage ndefs[]; String data = ""; if (messages != null) { ndefs = new NdefMessage[messages.length]; for (int i = 0; i < messages.length; i++) { ndefs[i] = (NdefMessage) messages[i]; } if (ndefs != null && ndefs.length > 0) { NdefRecord record = ndefs[0].getRecords()[0]; byte[] payload = record.getPayload(); String textEncoding = ((payload[0] & 0200) == 0) ? "UTF-8" : "UTF-16"; int languageCodeLength = payload[0] & 0077; try { data = new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding); textContentTips.setText(data); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } } return data; } private String parseTech(Intent intent) { return parseTag(intent); }
阅读全文
0 0
- NFC-标签内容的读取
- android nfc常用标签读取
- NFC标签的读写
- NFC之读写NFC标签的文本
- java读取xml指定标签的内容
- Dailys NFC标签阅读器Dl710plus适合于众多的NFC应用
- 如何使用NFC读卡器读取NFC卡片的UID?
- ANDROID 一个app中有多个activity读取NFC标签问题
- 安卓手机使用NFC读取MifareClassic等标签信息
- 选择适当的NFC标签类型
- 选择适当的NFC标签类型
- BlackBerry读取NFC卡的Serial Number
- Android读取NFC卡的编号
- 替换从数据库中读取的一段文字中的某些标签及标签之间的内容
- Android NFC 标签 读写
- 选择合适NFC标签
- 购买恩智浦的NFC标签NFC支付系统由中国RFID
- BB10 读取NFC tag
- nodejs 的expess框架安装及使用
- 最常用 最完整 最清晰 的git使用命令大全!
- JavaScript获取浏览器高度和宽度值(documentElement,clientHeight,offsetHeight,scrollHeight,scrollTop,offsetParent,
- Nginx invalid socket number 解决思路
- eclipse jpa project change event handler问题解决
- NFC-标签内容的读取
- window.print()打印时,如何自定义页眉/页脚、页边距
- 用CSS开启硬件加速来提高网站性能
- IOS 添加子控制器
- Redis入门到精通只需要三篇博客
- 57. Insert Interval
- vSphere及vCenter安装及使用说明
- springboot的druid监控
- 轻量化网络:MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications