Android 2.3.3 近場通信NFC介紹
NFC 是一套短距離的無線通信,通常距離是 4 厘米或更短。 NFC 工作頻率是 13.56M Hz, 傳輸速率是 106kbit/s 到848kbit/s. NFC 總是在一個發(fā)起者和一個被動目標之間發(fā)生。發(fā)起者發(fā)出近場無線電波,這個近場可以給被動目標供電。這些被動的目標包括不需要電源的標簽,卡,也可以是有電源的設(shè)備。
與其他無線通信技術(shù)比較, 例如藍牙和 WiFi , NFC 提供更低貸款和距離,并且低成本,不需要供電,不需要實現(xiàn)匹配,整個通信過程僅僅是短短的靠近一秒就能完成。
一個帶有 NFC 支持的 android 設(shè)備通常是一個發(fā)起者。也可以作為 NFC 的讀寫設(shè)備。他將檢測 NFC tags 并且打開一個Activity 來處理 . Android 2.3.3 還有支持有限的 P2P 。
Tags 分很多種,其中簡單的只提供讀寫段,有的只能讀。復(fù)雜的 tags 可以支持一些運算,加密來控制對 tags 里數(shù)據(jù)段的讀寫。甚至一些 tags 上有簡單的操作系統(tǒng),允許一些復(fù)雜的交互和可以執(zhí)行一些代碼。
API 概覽
Android.nfc package 包含頂層類用來與本地 NFC 適配器交互 . 這些類可以表示被檢測到的 tags 和用 NDEF 數(shù)據(jù)格式。
android.nfc.techpackage 包含那些對 tag 查詢屬性和進行 I/O 操作的類。這些類分別標示一個 tag 支持的不同的NFC 技術(shù)標準。
聲明 Android Manifest.xml 的元素
在你能訪問一個設(shè)備的 NFC 硬件和正確的處理 NFC 的 Intent 之前,需要在 AndroidManifest.xml 中先聲明下面的項:
1. NFC 使用 元素來訪問 NFC 硬件 :
2. 最小 SDK 版本需要設(shè)置正確, API level 9 只包含有限的 tag 支持 , 包括:
. 通過 ACTION_TAG_DISCOVERED來發(fā)布 Tag 信息
. 只有通過 EXTRA_NDEF_MESSAGES擴展來訪問 NDEF 消息
. 其他的 tag 屬性和 I/O 操作都不支持
所以你可能想要用 API level 10 來實現(xiàn)對 tag 的廣泛的讀寫支持。
3. uses-feature 元素定義:你的程序可以再 android 市場里顯示有 NFC 硬件。
4. NFC intent filter 告訴 android 系統(tǒng)你的 activity 能處理 NFC 數(shù)據(jù),可以定義 1 個或多個 intent filter :
android:resource = @xml/nfc_tech_filter .xml />
上邊 3 個 intent filters 有優(yōu)先級,更多信息可以看下面的 Tag 發(fā)布系統(tǒng)
也可以看 NFCDemo 例子的 AndroidManifest.xml 來有個更深的理解。
Tag 發(fā)布系統(tǒng)
當(dāng) android 設(shè)備掃描到一個 NFC tag ,通用的行為是自動找最合適的 Activity 會處理這個 tag Intent 而不需要用戶來選擇哪個 Activity 來處理。因為設(shè)備掃描 NFC tags 是在很短的范圍和時間,如果讓用戶選擇的話,那就有可能需要移動設(shè)備,這樣將會打斷這個掃描過程。你應(yīng)該開發(fā)你只處理需要處理的 tags 的 Activity ,以防止讓用戶選擇使用哪個 Activity來處理的情況。 Android 提供兩個系統(tǒng)來幫助你正確的識別一個 NFC tag 是否是你的 Activity 想要處理的: Intent 發(fā)布系統(tǒng)和前臺 Activity 發(fā)布系統(tǒng)。
Intent 發(fā)布系統(tǒng)檢查所有 Activities 的 intent filters ,找出那些定義了可以處理此 tag 的 Activity ,如果有多個 Activity 都配置了處理同一個 tag Intent ,那么將使用 Activity 選擇器來讓用戶選擇使用哪個 Activity 。用戶選擇之后,將使用選擇的 Activity 來處理此 Intent .
前臺發(fā)布系統(tǒng)允許一個 Activity 覆蓋掉 Intent 發(fā)布系統(tǒng)而首先處理此 tag Intent ,這要求你將要處理 Tag Intent 的 Activity運行在前臺,這樣當(dāng)一個 NFC tag 被掃描到,系統(tǒng)先檢測前臺的 Activity 是否支持處理此 Intent ,如果支持,即將此Intent 傳給此 Activity ,如果不支持,則轉(zhuǎn)到 Intent 發(fā)布系統(tǒng)。
使用 Intent 發(fā)布系統(tǒng)
Intent 發(fā)布系統(tǒng)指定了 3 個 intent 有不同的優(yōu)先級。通常當(dāng)一個 tag 被檢測到之后, Intent 就被啟動( start )了,這個啟動遵循以下行為 :
· android.nfc.action.NDEF_DISCOVERED : 這個 intent 是在一個包含 NDEF 負載的 tag 被檢測到時啟動,這是最高優(yōu)先級的 intent, android 系統(tǒng)不會讓你指定一個 Intent 能處理所有的 NFC 數(shù)據(jù)類型,你必須在AndroidManifest.xml 中指定與 NFC tag 對應(yīng)的 元素,這樣當(dāng)掃描到的 tag 傳過來的數(shù)據(jù)類型與你定義的相匹配時,你的 Activity 就會被調(diào)用。例如想處理一個包含 plain text 的 NDEF_DISCOVERED intent ,你要按照如下定義AndroidManifest.xml file:
如果 NDEF_DISCOVERED intent 已經(jīng)被啟動, TECH_DISCOVERED 和 TAG_DISCOVERED intents 將不會被啟動。假如一個未知的 tag 或者不包含 NDEF 負載的 tag 被檢測到,此 Intent 就不會被啟動。
· android.nfc.action.TECH_DISCOVERED : 如果 NDEF_DISCOVERED intent 沒啟動或者沒有一個 Activity 的filter 檢測 NDEF_DISCOVERED ,并且此 tag 是已知的,那么此 TECH_DISCOVERED Intent 將會啟動 .TECH_DISCOVERED intent 要求你在一個資源文件里 (xml) 里指定你要支持 technologies 列表。更多細節(jié)請看下面的Specifying tag technologies to handle .
· android.nfc.action.TAG_DISCOVERED : 如果沒有一個 activity 處理 _DISCOVERED and TECH_DISCOVEREDintents 或者 tag 被檢測為未知的,那么此 Intent 將會被啟動。
Specifying tag technologies to handle 指定處理的 technologies
假如你的 Activity 在 AndroidManifest.xml 文件里聲明了處理 android.nfc.action.TECH_DISCOVERED intent,你必須創(chuàng)建一個 Xml 格式的資源文件,并加上你的 activity 支持的 technologies 到 tech-list 集合里。這樣你的 activity將被認作能處理這些 tech-list 的處理者,如果 tag 使用的 technology 屬于你的定義的 list 里,你的 Activity 將接收此Intent 。你可以用 getTechList() 來獲得 tag 支持的 technologies 。
例如:如果一個 tag 被檢測到支持 MifareClassic, NdefFormatable, 和 NfcA ,你的 tech-list 集合必須指定了其中的一項或者多項來保證你的 Activity 能處理此 Intent 。
下面是一個資源文件例子,定義了所有的 technologies. 你可以根據(jù)需要刪掉不需要的項,將此文件以任意名字 +.xml 保存到 /res/xml 文件夾 .
asis:names:tc:xliff:document:1.2 >
android.nfc.tech.IsoDep
android.nfc.tech.NfcA
android.nfc.tech.NfcB
android.nfc.tech.NfcF
android.nfc.tech.NfcV
android.nfc.tech.Ndef
android.nfc.tech.NdefFormatable
android.nfc.tech.MifareClassic
android.nfc.tech.MifareUltralight
你也可以指定多個 tech-list 集合,每個集合都認做獨立的。如果任何單個 tech-list 集合是 getTechList() 返回的technologies 集合的子集,那么你的 Activity 將被認為匹配了。這個還提供 ’ 與 ’ 和 ’ 或 ’ 操作。下面的例子表示支持NfcA 和 NDef 的卡,或者支持 NfcB 和 NDef 的卡:
asis:names:tc:xliff:document:1.2 >
android.nfc.tech.NfcA
android.nfc.tech.Ndef
asis:names:tc:xliff:document:1.2 >
android.nfc.tech.NfcB
android.nfc.tech.Ndef
在 AndroidManifest.xml 文件中 , 指定這個 tech-list 資源文件的方法是在 元素中創(chuàng)建 元素,例如下面例子 :
...
android:resource = @xml/nfc_tech_filter />
...
使用前臺發(fā)布系統(tǒng) Using the foreground dispatch system
前臺發(fā)布系統(tǒng)允許一個 Activity 攔截一個 tag Intent 獲得最高優(yōu)先級的處理,這種方式很容易使用和實現(xiàn):
1. 添加下列代碼到 Activity 的 onCreate() 方法里
a. 創(chuàng)建一個 PendingIntent對象 , 這樣 Android 系統(tǒng)就能在一個 tag 被檢測到時定位到這個對象
PendingIntent pendingIntent = PendingIntent . getActivity (
this , 0 , new Intent ( this , getClass ()). addFlags ( Intent .FLAG_ACTIVITY_SINGLE_TOP ), 0 );
b. 在 Intent filters 里聲明你想要處理的 Intent ,一個 tag 被檢測到時先檢查前臺發(fā)布系統(tǒng),如果前臺 Activity 符合Intent filter 的要求,那么前臺的 Activity 的將處理此 Intent 。如果不符合,前臺發(fā)布系統(tǒng)將 Intent 轉(zhuǎn)到 Intent 發(fā)布系統(tǒng)。如果指定了 null 的 Intent filters ,當(dāng)任意 tag 被檢測到時,你將收到 TAG_DISCOVERED intent 。因此請注意你應(yīng)該只處理你想要的 Intent 。
p2p機相關(guān)文章:p2p原理
評論