一、NFC
1、三种模式
(1)读卡器模式 主动
就是通过手机从带有NFC芯片的设备中读和写数据
(2)仿真卡模式 被动
将支持NFC的手机或其他电子设备当成借记卡、信用卡、公交卡、门禁卡等IC卡使用,手机是被动, NFC射频器主动读
(3)点对点模式 p2p mode 主动
用于不同NFC设备之间进行数据交换,只是NFC的点对点模式有效距离通常不能超过4厘米,而且传输建立速度要比红外和蓝牙快很多,如果双方都使用Android4.2,NFC会直接利用蓝牙传输,这种技术被称为Android Beam。所以使用Android Beam传输数据的两部设备不再限于4厘米之内。
点对点模式的典型应用就是两部支持NFC的手机或平板电脑实现点对点传输,例如下载音乐,交换图片或同步设备地址簿等,因此通过NFC多个设备如数字相机、PDA、计算机、手机之间都可以快速连接并交换资料或者服务。
2、NFC、蓝牙、红外对比
3、用途
电子标签识别、刷手机、点对点付款、身份识别、信息记录等
二、Android中的NFC
1、Android对NFC的支持
从2.3.1支持NFC,但是支持不好,从Android 4.0开始google开始向NFC发力, 4.1以后可以用NFC传输较大数据(NFC会利用蓝牙进行大数据的传输)
2、NFC标签
不同的NFC标签之间差异较大,有的很简单只支持读写操作,有时还会采用支持一次性写入的芯片,将NFC标签设计成只读的(就跟光盘一样只能刻录一次),也有复杂的。Android SDK API主要支持NFC论坛标准,这种标准被称为NDEF(NFC Data Exchange form,NFC数据交换格式),不支持非NDEF格式的数据
3、NDEF数据
Android SDK API支持如下3中NDEF数据的操作
1> 从NFC标签读取NDEF格式的数据
2> 从NFC标签写入NDEF格式的数据
3> 通过Android Beam技术将NDEF数据发送到另一部NFC设备上
NDEF是轻量级的二进制格式,可带有URL、vCard和NFC定义的各种数据类型
NdefMessage:描述NDEF格式的信息
NdefRecord:描述NDEF信息的一段
NdefMessage和NdefRecord是Android NFC技术核心类,无论读写NDEF格式的NFC标签,还是通过Android Beam技术传递Ndef格式的数据,都需要这两个类。
三、来看一个例子
我从网上25块钱买了5个NFC标签,可读写,专门用于开发,最大能写入80个字节,大家也可以买一个试试,话不多说,上代码:
1、布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="请将NFC标签靠近手机来写入微信包名"
android:textSize="16dp"
android:textColor="#000"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
首先呢以上xml用于提示用户将NFC标签靠近手机来写入
2、Android MainActivity
public class MainActivity extends Activity {
NfcAdapter mNfcAdapter;
PendingIntent mPendingIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, this.getClass()), 0);
}
@Override
protected void onResume() {
super.onResume();
if (mNfcAdapter != null) {
// 设置优先于所有可以处理NFC标签的窗口,即使关闭此窗口依然有效,因此一定要在对应生命周期中disable掉
mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
}
}
@Override
protected void onPause() {
super.onPause();
mNfcAdapter.disableForegroundDispatch(this);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (tag != null) {
NdefMessage ndefMessage = new NdefMessage(new NdefRecord[] {NdefRecord.createApplicationRecord("com.tencent.mm")});
int size = ndefMessage.toByteArray().length;
try {
// NFC容量有限,因此有可能写不进去
Ndef ndef = Ndef.get(tag); // 判断是否是ndef
if (ndef != null) {
ndef.connect(); // 连接NFC
if (ndef.isWritable()) { // 判断NFC标签是否可写
if (ndef.getMaxSize() > size) { // 如果最大容量大于要写入的数据才可以,否则写不进去
ndef.writeNdefMessage(ndefMessage);
Toast.makeText(this, "写入成功", Toast.LENGTH_SHORT).show();
}
}
}
}
catch (Exception e) {
}
}
}
}
解释:首先呢需要两个类NfcAdapter和PendingIntent,前者用于对NFC进行一些设置(具体见代码注释),后者是当感应到标签靠近以后的动作,此处是打开当前MainActivity,因此MainActivity需要设置为单例,需要在onNewIntent里面执行真正的写入过程。onResume()中这句mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null); 意思是设置优先于所有可以处理NFC标签的窗口,即使关闭此窗口依然有效,因此一定要在对应生命周期中disable掉。
在写入的时候需要这么几个方法:
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); // 获取NFC的TAG
Ndef ndef = Ndef.get(tag); // 判断是否是ndef数据,Android不支持除NDEF以外的数据
ndef.writeNdefMessage(ndefMessage); 写入数据
在开发过程中不要忘记加权限,否则会崩溃:<uses-permission android:name="android.permission.NFC"/>
如果想只有带有nfc功能的手机才能下载你的app那就这么声明:
<uses-feature android:name="android.hardware.nfc"
android:required="true"/>
完成以后运行程序,打开MainActivity, 然后用标签靠近你的手机,如果感应到了会弹出Toast “写入成功”,这时候你的标签已经被写入了微信包名,你可以试试靠近任何一个带NFC的手机来打开微信。