轉載自 http://blog.sina.com.cn/s/blog_67d95f4001011uiv.htmlhtml
啥是NFC你要是不知道就不用往下看了。另外這裏全部寫的東西不少都是基於android文檔的,因此你最好本身去看,不然就要看我本身的理解了android
一:NFC的tag分發系統web
若是想讓android設備感應到NFC標籤,你要保證兩點數組
1:屏幕沒有鎖住 2:NFC功能已經在設置中打開ui
當系統檢測到一個NFC標籤的時候,他會自動去尋找最合適的activity去處理這個intent.this
他所發出的這個Intent將會有三種action:google
ACTION_NDEF_DISCOVERED:當系統檢測到tag中含有NDEF格式的數據時,且系統中有activity聲明能夠接受包含NDEF數據的Intent的時候,系統會優先發出這個action的intent。spa
ACTION_TECH_DISCOVERED:當沒有任何一個activity聲明本身能夠響應ACTION_NDEF_DISCOVERED時,系統會嘗試發出TECH的intent.即使你的tag中所包含的數據是NDEF的,可是若是這個數據的MIME type或URI不能和任何一個activity所聲明的想吻合,系統也同樣會嘗試發出tech格式的intent,而不是NDEF.code
ACTION_TAG_DISCOVERED:當系統發現前兩個intent在系統中無人會接受的時候,就只好發這個默認的TAG類型的orm
二:NFC相關androidManifest文件設置
首先是權限:<uses-permission android:name="android.permission.NFC" />
而後是sdk級別限制:我我的建議API10開始比較合適:<uses-sdk android:minSdkVersion="10"/>
接着是特殊功能限制<uses-feature android:name="android.hardware.nfc"android:required="true" />這個生命可讓你的應用在google play上被聲明使用者必須擁有nfc功能。
三:NFC標籤過濾
在activity的intent過濾xml聲明中,你能夠同時聲明過濾這三種action.可是由以前所說,你應該知道系統在發送intent的時候是有優先級的,因此你最好清楚本身最想處理哪一個。
1:過濾ACTION_TAG_DISCOVERED:
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
這個最簡單,也是最後一個被嘗試接受intent的選項。
2:過濾ACTION_NDEF_DISCOVERED:
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain" />
</intent-filter>
其中最重要的應該算是data的mimeType類型了,這個定義的越準確,intent指向你這個activity的成功率就越高,不然系統可能不會發出你想要的NDEF intent了。下面在講如何使用NDEF寫入NFC標籤的時候會多舉幾個類型的例子。
3:過濾ACTION_TECH_DISCOVERED:
你首先須要在你的<project-path>/res/xml下面建立一個過濾規則文件。名字任取,好比能夠叫作nfc_tech_filter.xml。這個裏面定義的是nfc實現的各類標準,每個nfc卡都會符合多個不一樣的標準,我的理解爲這些標準有些相互之間也是兼容的。你能夠在檢測到nfc標籤後使用getTechList()方法來查看你所檢測的tag到底支持哪些nfc標準。
一個nfc_tech_filter.xml中能夠定義多個<tech-list>結構組。每一組表明我聲明我只接受同時知足這些標準的nfc標籤。好比A組表示,只有同時知足IsoDep,NfcA,NfcB,NfcF這四個標準的nfc標籤的intent才能進入。A與B組之間的關係就是隻要知足其中一個就能夠了。換句話說,你的nfc標籤技術,知足A的聲明也能夠,知足B的聲明也能夠。
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list> --------------------------------A組
<tech>android.nfc.tech.IsoDep</tech> <tech>android.nfc.tech.NfcA</tech><tech>android.nfc.tech.NfcB</tech> <tech>android.nfc.tech.NfcF</tech>
</tech-list>
<tech-list>-----------------------------------------B組
<tech>android.nfc.tech.NfcV</tech> <tech>android.nfc.tech.Ndef</tech><tech>android.nfc.tech.NdefFormatable</tech><tech>android.nfc.tech.MifareClassic</tech><tech>android.nfc.tech.MifareUltralight</tech>
</tech-list>
</resources>
在androidManifest文件中聲明xml過濾的舉例以下
<activity>
<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" />-------------這個就是你的資源文件名
</activity>
4:nfc標籤前臺分發系統
之因此把他也歸類在nfc的過濾裏面,主要是由於他跟解析nfc標籤到不是那麼的緊密,他解決的是接受哪些nfc標準的標籤問題。因此更接近nfc的過濾。
什麼叫nfc的前臺發佈系統?就是說當咱們已經打開咱們的應用的時候,那麼經過這個前臺發佈系統的設置,咱們可讓咱們已經啓動的activity擁有更高的優先級來依據咱們在代碼中定義的標準來過濾和處理intent,而不是讓別的聲明瞭intent filter的activity來干擾,甚至連本身聲明在androidManifest中的intent filter都不會來干擾。也就是說foreground Dispatch的優先級大於intent filter。
第一種狀況:當你的activity沒有啓動的時候,去掃描tag,那麼系統中全部的intent filter都將一塊兒參與過濾。
第二種狀況:當你的actiity啓動了,去掃描tag時,那麼將直接使用你在foreground dispatch中代碼寫入的過濾標準。若是這個標準沒有命中任何intent,那麼系統將使用全部activity聲明的intent filter xml來過濾。
在OnCreate中你能夠添加以下代碼
// Create a generic PendingIntent that will be deliver to this activity. The NFC stack will fill in the intent with the details of the discovered tag before delivering to this activity.
mPendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
// 作一個IntentFilter過濾你想要的action 這裏過濾的是ndef
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
//若是你對action的定義有更高的要求,好比data的要求,你能夠使用以下的代碼來定義intentFilter
// try {
// ndef.addDataType("*/*");
// } catch (MalformedMimeTypeException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//生成intentFilter
mFilters = new IntentFilter[] {
ndef,
};
// 作一個tech-list。能夠看到是二維數據,每個一維數組之間的關係是或,可是一個一維數組以內的各個項就是與的關係了
mTechLists = new String[][] {
new String[] { NfcF.class.getName()},
new String[]{NfcA.class.getName()},
new String[]{NfcB.class.getName()},
new String[]{NfcV.class.getName()}
};
在onPause和 onResume中須要加入相應的代碼。
public void onPause() {
super.onPause();
//反註冊 mAdapter.disableForegroundDispatch(this);
}
[object Object]
public void onResume() {
super.onResume();
//設定intentfilter和tech-list。若是兩個都爲null就表明優先接收任何形式的TAG action。也就是說系統會主動發TAG intent。
mAdapter.enableForegroundDispatch(this, mPendingIntent, mFilters, mTechLists);
}