Android中NFC标签卡的读取

news/2024/10/18 6:04:36/

前几天老大把一张卡拿给我说要我把用NFC技术读出它的uid来,写成一个demo给他,我第一反应就是一脸闷逼,可是卡已经交给我了,只能照办不误了!在我不长的开发生涯中是从来没有接触过NFC的,所以在接到任务后,我也是急忙的恶补一波相关知识,最后也算是完成任务了吧,但对于NFC还只是入了门而已,我今天要说的也就是常见的NFC标签读取,给大家领个路而已,互相学习。我先给大家说一下NFC(Near Field Communication)的工作模式 :NFC支持如下3种工作模式:读卡器模式(Reader/writer mode)、仿真卡模式(Card Emulation Mode)、点对点模式(P2P mode)。下来分别看一下这三种模式:

1)读卡器模式

数据在NFC芯片中,可以简单理解成刷标签。本质上就是通过支持NFC的手机或其它电子设备从带有NFC芯片的标签、贴纸、名片等媒介中读写信息。通常NFC标签是不需要外部供电的。当支持NFC的外设向NFC读写数据时,它会发送某种磁场,而这个磁场会自动的向NFC标签供电。

2)仿真卡模式

数据在支持NFC的手机或其它电子设备中,可以简单理解成刷手机。本质上就是将支持NFC的手机或其它电子设备当成借记卡、公交卡、门禁卡等IC卡使用。基本原理是将相应IC卡中的信息凭证封装成数据包存储在支持NFC的外设中  
在使用时还需要一个NFC射频器(相当于刷卡器)。将手机靠近NFC射频器,手机就会接收到NFC射频器发过来的信号,在通过一系列复杂的验证后,将IC卡的相应信息传入NFC射频器,最后这些IC卡数据会传入NFC射频器连接的电脑,并进行相应的处理(如电子转帐、开门等操作)。

3)点对点模式

该模式与蓝牙、红外差不多,用于不同NFC设备之间进行数据交换,不过这个模式已经没有有的感觉了。其有效距离一般不能超过4厘米,但传输建立速度要比红外和蓝牙技术快很多,传输速度比红外块得多,如过双方都使用Android4.2NFC会直接利用蓝牙传输。这种技术被称为Android Bean。所以使用Android Bean传输数据的两部设备不再限于4厘米之内。 
点对点模式的典型应用是两部支持NFC的手机或平板电脑实现数据的点对点传输,例如,交换图片或同步设备联系人。因此,通过NFC,多个设备如数字相机,计算机,手机之间,都可以快速连接,并交换资料或者服务。

NFC全称为Near Field Communication意思是近场通讯,作为和蓝牙,红外线一起成为当前的主流的数据传输技术我们来看看他们之间的区别:

对比项NFC蓝牙红外
网络类型点对点单点对多点点对点
有效距离<=0.1m<=10m,最新的蓝牙4.0有效距离可达100m一般在1m以内,热技术连接,不稳定
传输速度最大424kbps最大24Mbps慢速115.2kbps,快速4Mbps
建立时间<0.1s6s0.5s
安全性安全,硬件实现安全,软件实现不安全,使用IRFM时除外
通信模式主动-主动/被动主动-主动主动-主动
成本

我们读取id就是利用的读卡器模式,当把卡片靠近手机的NFC天线的时候,NFC会识别到卡,然后把卡对象装到intent里面,并发送广播NfcAdapter.ACTION_TECH_DISCOVERED,应用程序接到这个广播之后,通过intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)来获取到卡对象,然后就可以对卡进行读写。下面我就直接上代码了。

首先类似蓝牙通讯,NFC开发也是相应的权限的:

<uses-permission android:name="android.permission.NFC" />
<!-- 要求当前设备必须要有NFC芯片 -->
<uses-feature android:name="android.hardware.nfc" android:required="true" />

然后你要进行NFC操作的activity这么注册,注意启动模式务必要设置成singleTop或singleTask ,至于广播过滤大家看自己需要添加

<activity android:name=".MainActivity"android:launchMode="singleTop"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter><intent-filter><action android:name="android.nfc.action.TECH_DISCOVERED" /></intent-filter><meta-data android:name="android.nfc.action.TECH_DISCOVERED"android:resource="@xml/nfc_tech_filter" /><intent-filter><action android:name="android.nfc.action.TAG_DISCOVERED" /><category android:name="android.intent.category.DEFAULT" /></intent-filter>
</activity>

nfc_tech_filter.xml是过滤器,过滤哪些卡片(由于我们需要读取的是MifareClassic卡,所以以外的过滤

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"><tech-list><tech>android.nfc.tech.IsoDep</tech></tech-list><tech-list><tech>android.nfc.tech.NfcV</tech></tech-list><tech-list><tech>android.nfc.tech.NfcA</tech></tech-list><tech-list><tech>android.nfc.tech.NfcC</tech></tech-list><tech-list><tech>android.nfc.tech.NfcF</tech></tech-list>
</resources>

我先给大家看一下界面布局吧,很简单就是读取之后用textview显示:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/activity_main"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#151414"><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"android:layout_centerInParent="true"><TextViewandroid:layout_width="wrap_content"android:text="读取到的卡UID: "android:textColor="#fff"android:layout_height="wrap_content" /><TextViewandroid:textColor="#fff"android:id="@+id/tv_uid"android:text="                            "android:layout_width="wrap_content"android:layout_height="wrap_content"/></LinearLayout>
</RelativeLayout>

接下来看下activity代码:

public class MainActivity extends AppCompatActivity {private NfcAdapter nfcAdapter;private PendingIntent pendingIntent;private TextView tvUid;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);tvUid = (TextView) findViewById(R.id.tv_uid);//获取NfcAdapter实例nfcAdapter = NfcAdapter.getDefaultAdapter(this);//获取通知pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);if (nfcAdapter == null) {Toast.makeText(MainActivity.this,"设备不支持NFC",Toast.LENGTH_LONG).show();return;}if (nfcAdapter!=null&&!nfcAdapter.isEnabled()) {Toast.makeText(MainActivity.this,"请在系统设置中先启用NFC功能",Toast.LENGTH_LONG).show();return;}//因为启动模式是singleTop,于是会调用onNewIntent方法onNewIntent(getIntent());}@Overrideprotected void onNewIntent(Intent intent) {super.onNewIntent(intent);resolveIntent(intent);}void resolveIntent(Intent intent) {Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);if (tag != null) {processTag(intent);}}private String ByteArrayToHexString(byte[] inarray) {int i, j, in;String[] hex = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A","B", "C", "D", "E", "F" };String out = "";for (j = 0; j < inarray.length; ++j) {in = (int) inarray[j] & 0xff;i = (in >> 4) & 0x0f;out += hex[i];i = in & 0x0f;out += hex[i];}return out;}private String flipHexStr(String s){StringBuilder  result = new StringBuilder();for (int i = 0; i <=s.length()-2; i=i+2) {result.append(new StringBuilder(s.substring(i,i+2)));}return result.toString();}public void processTag(Intent intent) {//处理tag//获取到卡对象Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);//获取卡id这里即uidbyte[] aa = tagFromIntent.getId();String str = ByteArrayToHexString(aa);str = flipHexStr(str);tvUid.setText(str);}@Overrideprotected void onPause() {super.onPause();if (nfcAdapter != null)//设置程序不优先处理nfcAdapter.disableForegroundDispatch(this);}@Overrideprotected void onResume() {super.onResume();if (nfcAdapter != null)//设置程序优先处理nfcAdapter.enableForegroundDispatch(this, pendingIntent,null, null);}}

这里我给大家说几个要注意的地方,首先为啥要采用onNewIntent方法,我不知道在这之前,各位有没有理解过这个方法,这里我简单说下,大家都知道activity有四种启动模式singleTop,standard,singleTask,singleInstance,当你从activityA跳转到activityB,然后从B又跳回来并带数据,这个时候如果启动模式为singleTask,A是不会再执行onCreate方法了,那么我们怎么取数据呢,这个时候onNewIntent就起作用了,这个intent才是你跳转过来的新Intent,这里同样,因为NFC检测到对象时,会在系统startActivity,那么目标activity已经是启动了,所以我们需要在onNewIntent方法中接受tag对象,同时activity启动模式设为singleTop或singleTask也为了避免重复创建实例!还有一点要注意的是,我们知道不在前台的activity在系统内存告急,或者时间太久都有被杀死的可能,没办法这是底层的一种策略,就是前台可见的东西,优先级永远大于不可见的,所以为了避免这种血案,我们应该在onCreate方法和onNewIntent方法中都执行getIntent操作,这样就万无一失了!

以上代码很容易理解了,好了,那么读取NFC标签就这些了!


http://www.ppmy.cn/news/465041.html

相关文章

android 苹果支付,不仅应用于支付 手机上的NFC功能解析

对于NFC功能大家都已经比较熟悉&#xff0c;在之前就已经有手机配备NFC功能。此前北京移动还联合一卡通推出过NFC-SIM卡&#xff0c;可以让手机作为北京市政一卡通来使用。而在去年苹果推出Apple Pay之后&#xff0c;NFC功能俨然成为了手机支付必不可少的环节&#xff0c;在未来…

NFC 协议简介

NFC技术标准 NFC标准兼容飞利浦的 Mifare 标准(ISO 14443 A&#xff0c;B)&#xff0c;以及索尼公司的FeliCa 标准&#xff0c;其中TypeA&#xff0c;TypeB为Mifare标准&#xff0c;F为Felica标准。 特性说明频段13.56 MHz通讯距离约10厘米传输速度106kbps、212kbps、424kbps…

苹果7pnfc功能门禁卡_苹果NFC功能不再鸡肋?原来还能这么玩,内附门禁卡复制教程...

安卓手机用户NFC功能发展越来越好&#xff0c;很多功能以及涉及到我们日常生活&#xff0c;乘公交、门禁卡等。而苹果早在iPhone 6S的时候就开始搭载NFC功能&#xff0c;却只能实现Apple pay支付功能&#xff0c;且使用程度不高。 对于用户反馈&#xff0c;苹果于去年逐渐开放部…

android nfc读写demo,android nfc常用标签读取总结

有几天没有更新博客了,不过本篇却准备了许久,希望能带给每一位开发者最简单高效的学习方式。废话到此为止,下面开始正文。 NFC(Near Field Communication,近场通信)是一种数据传输技术。与Wi-Fi、蓝牙、红外线等数据传输技术的一个主要差异就是有效距离一般不能超过4厘米。…

屏幕录制没有声音?快看看这2个方法!

案例&#xff1a;我今天尝试在电脑上进行屏幕录制&#xff0c;一开始一切都挺正常的。直到结束后&#xff0c;查看刚刚录制的视频发现没有声音。 【录屏只有画面没有声音&#xff0c;会影响视频的观感体验&#xff0c;甚至你根本不知道视频想表达的意思。那录屏的同时如何录制…

机器学习与深度学习——基于潜在语义分析(LSA)的文档相似度计算

机器学习与深度学习——基于潜在语义分析&#xff08;LSA&#xff09;的文档相似度计算 基于潜在语义分析&#xff08;LSA&#xff09;是一种使用数学和统计方法来分析文本数据的技术。该技术可用于发现文本之间的关系&#xff0c;以及为文本提供有关其含义的更深层次的信息。…

AI生成--git 常用命令

git init&#xff1a;初始化Git仓库git clone&#xff1a;克隆Git仓库git add&#xff1a;将文件添加到暂存区git commit&#xff1a;将暂存区的文件提交到本地仓库git push&#xff1a;将本地仓库的文件推送到远程仓库git pull&#xff1a;从远程仓库拉取代码到本地git status…

cannon linux驱动下载

“Linux 专用 Canon UFR II/UFRII LT 打印机驱动程序”是支持Canon设备的 Linux 操作系统打印机驱动程序。 它使用 Linux 操作系统用的(Common Unix Printing System)打印系统。 下载链接&#xff1a; https://www.canon.com.cn/supports/download/simsdetail/0100832109.html …