在这节内容中,我们为大家介绍一下NFC的读写卡模式的开发。 
读写卡模式是通过手机对nfc标签卡信息经行读写操作,但是,在使用前,我们应该去检查一下设置和添加一些权限。 
在这里我建议大家将NFC的一些基础操作放入到一个NfcBaseActivity中,这样,我们在使用时就不需要每次都经行重复的操作。 
1、检测NFC状态

    public int nfcAdapterInitialize() {//自定义的函数//尝试去获取设备默认的NfcAdapter(NFC适配器)对象,由于手机中一般只有一个NFC设备,所以我们这里获取默认的即可。NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);//判断nfcAdapter是否为空,若为空则手机不支持NFC设备if (nfcAdapter == null) {Toast.makeText(this, "不支持nfc", Toast.LENGTH_SHORT).show();return 0;} else {//若不为空,则判断NFC是否开启if (!nfcAdapter.isEnabled()) {Toast.makeText(this, "nfc没有开启", Toast.LENGTH_SHORT).show();//我们将跳转到设置页面去开启NFCstartActivity(new Intent(Settings.ACTION_NFC_SETTINGS));return 0;}}return 1;}
  • 建议以上代码放入NfcBaseActivity的onCreate中,当你的程序需要调用NFC时直接继承即可。 
    2、NFC前台调度系统 
    NFC中有两种响应标签的方式,一种是前台调度系统,另一种是intent过滤器的方式。前台调度系统其实就是运行Activity高优先的来处理Tag的技术,前台调用系统的优先级要高于intent过滤器。但前台调度系统要求Activity是被打开的。 
    首先我们需要在Activity被创建时,去初始化NFC的信息
    private NfcAdapter nfcAdapter;private NfcManager nfcManager;private PendingIntent pendingIntent;private IntentFilter[] intentFilters;private String[][] mTechList;private void nfcInitialization(){//该参数的作用是指定用哪个Activity来处理标签//参数1:上下文// 参数二 不使用了——0,// 参数三:一个意图用来存储信息,这里会根据这个意图来调用指定Activity//FLAG_ACTIVITY_SINGLE_TOP:指定Activity不能被重复创建// 参数四:对参数的操作标志pendingIntent= PendingIntent.getActivity(this,0,newIntent(this,getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0);//创建意图过滤器,指定该前台调度系统拦截那些类型的标签//这里说明IntentFilter不是很熟悉的童鞋先去查一下这里的资料//在这里我们现在*/*表示拦截所有标签IntentFilter intentFilter=new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);IntentFilter intentFilter1=new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);try {intentFilter.addDataType("*/*");} catch (IntentFilter.MalformedMimeTypeException e) {e.printStackTrace();}//将我们的意图放入到数组中(在我的案例中,intentFilter1其实是没有使用的)intentFilters=new IntentFilter[]{intentFilter,intentFilter1};//指定过滤标签,这里填入null就好mTechList=null;}

这里我们初始化了前台调度系统的一些参数,下面我们看一下怎么启用前台调度系统

//在activity不可见的时候我们关闭前台调度@Overrideprotected void onPause() {super.onPause();if(nfcAdapter!=null)nfcAdapter.disableForegroundDispatch(this);}//在Activity显示的时候,我们让NFC前台调度系统处于打开状态@Overrideprotected void onResume() {super.onResume();Log.w("nfclive","resume"+nfcAdapter);if(nfcAdapter!=null)nfcAdapter.enableForegroundDispatch(this,pendingIntent,intentFilters,mTechList);}
  • 当完成这些代码后,我们就可以将标签拦截,不在向下传递。 
    当我们拦截到标签后,我们需要获取标签中的信息,由于我们在前面采用了FLAG_ACTIVITY_SINGLE_TOP,所以在每次刷入标签时不会去调用onCreate而是调用onNewIntent来经行回调,且会将Tag放入到Intent中。下面我们通过一些代码来尝试获取NFC标签中的Uid和Tag对象,并将uid转为字符串
    protected void onNewIntent(Intent intent) {super.onNewIntent(intent);//这里我们去得到tag对象tag=intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);uid= getUid(tag);//Uid样子:4-106-91-119-72-2-78}public static String getUid(Tag tag){//获取tag中ID的byte数组byte[] tagByteId=tag.getId();//通过流来经行解析为字符串StringBuffer stringBuffer=new StringBuffer();for (byte b:tagByteId){stringBuffer.append(b);}return stringBuffer.toString();}
  • 当然,单纯的只获取ID对我们来说可能并不满足,我们想获取一下NFC中的存放了说明数据,接下来让我们去获取一下NFC中的数据。 
    在看数据之前让我们来看一下NFC中的数据结构吧 
    Parcelable[] rawmsgs=intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);来获取NdefMessage消息,在这里Parcelable和NdefMessage是实现关系。下面是我的一段代码的实现,我们只讲第一个NdefMessage取出。
public static NdefMessage getNdefMessage(Intent intent) {NdefMessage[] ndefMessage=null;Parcelable[] rawmsgs=
intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);if (rawmsgs!=null){ndefMessage=new NdefMessage[rawmsgs.length];for (int i=0;i<rawmsgs.length;i++){ndefMessage[i]= (NdefMessage) rawmsgs[i];}}return ndefMessage[0];}

这样我们就可以得到NdefMessage了,但是我们通过这个消息如何解析到我们想要的数据呢?其实在NdefMessage中,又包含了多个NdefRecord,每个NdefRecord就表示一个NFC数据的记录,可以通过message.getRecords()来获取。 
NdefRecord[] record=message.getRecords() 
然后我们需要解析的是record中的消息如果你是NDEF消息,先把这个东西copy到你的代码中

public static final Map<Byte, String> URI_PREFIX_MAP = new HashMap<Byte, String>();static {//设置NDEF Uri规范支持的Uri前缀,在解析payload时,需要根据payload的第1个字节定位相应的uri前缀URI_PREFIX_MAP.put((byte) 0x00, "");URI_PREFIX_MAP.put((byte) 0x01, "http://www.");URI_PREFIX_MAP.put((byte) 0x02, "https://www.");URI_PREFIX_MAP.put((byte) 0x03, "http://");URI_PREFIX_MAP.put((byte) 0x04, "https://");URI_PREFIX_MAP.put((byte) 0x05, "tel:");URI_PREFIX_MAP.put((byte) 0x06, "mailto:");URI_PREFIX_MAP.put((byte) 0x07, "ftp://anonymous:anonymous@");URI_PREFIX_MAP.put((byte) 0x08, "ftp://ftp.");URI_PREFIX_MAP.put((byte) 0x09, "ftps://");URI_PREFIX_MAP.put((byte) 0x0A, "sftp://");URI_PREFIX_MAP.put((byte) 0x0B, "smb://");URI_PREFIX_MAP.put((byte) 0x0C, "nfs://");URI_PREFIX_MAP.put((byte) 0x0D, "ftp://");URI_PREFIX_MAP.put((byte) 0x0E, "dav://");URI_PREFIX_MAP.put((byte) 0x0F, "news:");URI_PREFIX_MAP.put((byte) 0x10, "telnet://");URI_PREFIX_MAP.put((byte) 0x11, "imap:");URI_PREFIX_MAP.put((byte) 0x12, "rtsp://");URI_PREFIX_MAP.put((byte) 0x13, "urn:");URI_PREFIX_MAP.put((byte) 0x14, "pop:");URI_PREFIX_MAP.put((byte) 0x15, "sip:");URI_PREFIX_MAP.put((byte) 0x16, "sips:");URI_PREFIX_MAP.put((byte) 0x17, "tftp:");URI_PREFIX_MAP.put((byte) 0x18, "btspp://");URI_PREFIX_MAP.put((byte) 0x19, "btl2cap://");URI_PREFIX_MAP.put((byte) 0x1A, "btgoep://");URI_PREFIX_MAP.put((byte) 0x1B, "tcpobex://");URI_PREFIX_MAP.put((byte) 0x1C, "irdaobex://");URI_PREFIX_MAP.put((byte) 0x1D, "file://");URI_PREFIX_MAP.put((byte) 0x1E, "urn:epc:id:");URI_PREFIX_MAP.put((byte) 0x1F, "urn:epc:tag:");URI_PREFIX_MAP.put((byte) 0x20, "urn:epc:pat:");URI_PREFIX_MAP.put((byte) 0x21, "urn:epc:raw:");URI_PREFIX_MAP.put((byte) 0x22, "urn:epc:");URI_PREFIX_MAP.put((byte) 0x23, "urn:nfc:");}

这是一些头函数代表的含义 
接下来我们获取一下NFC中字节流 
byte[] bytes=records[0].getPayload(); 
然后我们来判断一下NDEF的类型records[0].getType(); 
在NdefRecord定义了

    public static final byte[] RTD_ALTERNATIVE_CARRIER ;public static final byte[] RTD_HANDOVER_CARRIER ;public static final byte[] RTD_HANDOVER_REQUEST l;public static final byte[] RTD_HANDOVER_SELECT ;public static final byte[] RTD_SMART_POSTER ;public static final byte[] RTD_TEXT ;public static final byte[] RTD_URI ;

这些格式。RTD_TEXT 是文本格式,RTD_URI是可以直接调用系统。这是比较常用的两个,其中URI又可以指定这些类型

    public static final short TNF_ABSOLUTE_URI = 3;//绝对URIpublic static final short TNF_EMPTY = 0;public static final short TNF_EXTERNAL_TYPE = 4;public static final short TNF_MIME_MEDIA = 2;public static final short TNF_UNCHANGED = 6;public static final short TNF_UNKNOWN = 5;public static final short TNF_WELL_KNOWN = 1;//已知类型,NDEF论坛定义

若我们解析的数据仅为TEXT类型时,只需要将字节的第一位取出,判断编码格式,其他位按照指定编码进行解析

public static  String parseWellKonwnUriRecord(NdefMessage message){NdefRecord[] records=message.getRecords();byte[]bytes=records[0].getPayload();byte charData=bytes[0];byte[] data=new byte[bytes.length-1];System.arraycopy(bytes,1,data,0,data.length);LogUtil.w("-------------------------"+new String(data,charData==1?"UTF-8","GBK"));return new String(data,charData==1?"UTF-8","GBK");}

RTD_URI 方式和读取字符串类似,只是没有首位的编码位;TNF_WELL_KNOWN 类型时,表示数据为已知类型,从URI_PREFIX_MAP中获取首位对应的字符串即可。


以上就是NFC的读卡模式,下面我们来说一下NFC的写入模式 
其实NFC的写卡模式与NFC的读卡模式是相似的。 
首先我们需要将信息准备好!如URI,或text信息 
然后我们创建一个 NdefRecord record=new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payload); 
NdefRecord.TNF_WELL_KNOWN:表示已知数据类型 
NdefRecord.RTD_TEXT:为指定数据的格式 
payload:为准备好的字节数据 
然后就可以生成一个NdefRecord,在将多个或一个NdefRecord放入NdefMessage中

new NdefMessage(record,arrRecord);
  • 1

然后我们在onNewIntent,获取到Ndef对象Ndef ndef=Ndef.get(getTag()); 
经行提交:ndef.connect();,接下来判断是否NFC标签的标签是否可以写入

if (ndef.getMaxSize() < message.getByteArrayLength()){Toast.makeText(this,"NFC标签空间不足",Toast.LENGTH_SHORT).show();return;
}else if (ndef==null){Toast.makeText(this,"非NDEF数据",Toast.LENGTH_SHORT).show();writeTag(ndefMessage, tag);//通过这种方式写入Toast.makeText(this,"完成",Toast.LENGTH_SHORT).show();return;
}
ndef.writeNdefMessage(message);

NFC的读写卡模式——前台调度系统相关推荐

  1. Linux笔记——运行模式之调度系统-作业管理-用户命令

    跑模式自然需要用到调度系统来进行作业管理,根据我在不同服务器上的使用经验总结几个非常常用的命令. 调度系统是个非常复杂的东西,所以细节不说太多了,要用的时候对应去查. 相关概念: 集群:利用高性能通信 ...

  2. 荔枝机器学习平台与大数据调度系统“双剑合璧”,打造未来数据处理新模式!...

    点击上方 蓝字关注我们 ✎ 编 者 按 在线音频行业在中国仍是蓝海一片.根据 CIC 数据显示,中国在线音频行业市场规模由 2016 年的 16 亿元增长至 2020 年的 131 亿元,复合年增长率 ...

  3. springboot冷链物流信息调度系统毕业设计源码210951

    摘  要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势:对于冷链物流信息调度系统当然也不能排除在外,随着网络技术的不断成熟,带动了冷链物流信息调度系统,它彻底 ...

  4. 基于springboot冷链物流信息调度系统毕业设计源码210951

    摘  要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势:对于冷链物流信息调度系统当然也不能排除在外,随着网络技术的不断成熟,带动了冷链物流信息调度系统,它彻底 ...

  5. 供水管网综合调度系统-智慧水务应用系统

    平台概述 柳林智慧水务应用系统平台是以物联感知技术.大数据.智能控制.云计算.人工智能.数字孪生.AI算法.虚拟现实技术为核心,以监测仪表.通讯网络.数据库系统.数据中台.模型软件.前台展示.智慧运维 ...

  6. Android适配 - 实现4.3以后NFC的CardReader模式

    Android 4.4更新了NFC的读卡器模式,具体API差异可以查看官方报告,本篇将梳理Android 4.3.Android 4.4以及之后版本的NFC读卡器模式的写法.(主要是对CPU卡的操作) ...

  7. 无线对讲调度服务器,无线对讲系统---智能调度系统

    无线对讲系统---智能调度系统 时间:2019-04-24   来源 :无线对讲系统---智能调度系统   点击次数: 次 分享: 智能调度系统,该方式属于全网录音,即通过网络直接获取数字中继台的语音 ...

  8. 黑马程序员----银行业务调度系统面试题

    这种程序就是模拟一个去取票系统,大家平时都有移动营业厅或者银行,都知道进去之后需要在门口的取票取一张票,那张票上面记录你的号码和需要等待的人楼,然后窗口会有显示当前服务的号码,如果轮到相应的数字就到对 ...

  9. 工作流调度系统介绍,常见工作流调度系统对比,azkaban与Oozie对比,Azkaban介绍与特性(来自学习笔记)

    1. 工作流调度器azkaban 1.1 概述 1.1.1为什么需要工作流调度系统 一个完整的数据分析系统通常都是由大量任务单元组成:shell脚本程序,java程序,mapreduce程序.hive ...

最新文章

  1. smarty 模板引擎
  2. 互联网1分钟 |1119
  3. MySQL 性能优化的最佳20多条经验分享
  4. Angular 导致公司损失数十亿美元!
  5. web.xml 详细介绍
  6. linux基础命令---bzip2
  7. Linux中配置pacman镜像源(manjaro)
  8. 上海科技大学计算机研究生调剂,2021年上海科技大学考研招生调剂信息
  9. 配置php apache,apache如何配置php
  10. svn服务端可视化界面
  11. dnf手游体验服显示无法连接服务器,《DNF手游》体验服服务器人数上限怎么办 体验服服务器人数上限解决办法...
  12. 两种方法删除顽固的DLL文件
  13. vue+jsonp跨域
  14. Kettle之Excel输入的简单使用
  15. 上海驾驶证满6年换证
  16. win7设置桌面豆绿色
  17. 最常见的几种手机快充方式和原理
  18. 三坐标检测基础知识之建立工件坐标系
  19. Java8中文api汉化文档下载【谷歌翻译最精准版】【jdk api 1.8_google.CHM】
  20. 无监督学习-自编码器-补充|深度学习(李宏毅)(二十)

热门文章

  1. 线性代数学习笔记——第三十八讲——直线与直线的位置关系
  2. windows中新建任何后缀的文件(包括无后缀名)
  3. 项目 cg day04
  4. 经典算法-递归-角谷定理
  5. 外汇天眼:外汇市场上不得不说的两大类庄家!
  6. John Morgan:黎曼几何、曲率、Ricci流以及在三维流形上的应用二讲
  7. 集成公告|Moonbeam宣布与ShowMe集成
  8. C++ 模板元编程的应用有哪些,意义是什么?
  9. OSChina 周六乱弹 ——快来看美国总统候选人怎么被打脸
  10. java gui pdf_java gui 程序设计基础.pdf