安卓NFC標籤讀取快速開發教程(附源代碼demo下載)

Demo下載

1.NFC的工作模式

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.2,NFC會直接利用藍牙傳輸。這種技術被稱爲Android Beam。所以使用Android Beam傳輸數據的兩部設備不再限於4釐米之內。
點對點模式的典型應用是兩部支持NFC的手機或平板電腦實現數據的點對點傳輸,例如,交換圖片或同步設備聯繫人。因此,通過NFC,多個設備如數字相機,計算機,手機之間,都可以快速連接,並交換資料或者服務。

下面看一下NFC、藍牙和紅外之間的差異:

對比項 NFC 藍牙 紅外
網絡類型 點對點 單點對多點 點對點
有效距離 <=0.1m <=10m,最新的藍牙4.0有效距離可達100m 一般在1m以內,熱技術連接,不穩定
傳輸速度 最大424kbps 最大24Mbps 慢速115.2kbps,快速4Mbps
建立時間 <0.1s 6s 0.5s
安全性 安全,硬件實現 安全,軟件實現 不安全,使用IRFM時除外
通信模式 主動-主動/被動 主動-主動 主動-主動
成本

2.Android對NFC的支持

不同的NFC標籤之間差異很大,有的只支持簡單的讀寫操作,有時還會採用支持一次性寫入的芯片,將NFC標籤設計成只讀的。當然,也存在一些複雜的NFC標籤,例如,有一些NFC標籤可以通過硬件加密的方式限制對某一區域的訪問。還有一些標籤自帶操作環境,允許NFC設備與這些標籤進行更復雜的交互。這些標籤中的數據也會採用不同的格式。但Android SDK API主要支持NFC論壇標準(Forum Standard),這種標準被稱爲NDEF(NFC Data Exchange Format,NFC數據交換格式)。

NDEF格式其實就類似於硬盤的NTFS,下面我們看一下NDEF數據:

(1)NDEF數據的操作

Android SDK API支持如下3種NDEF數據的操作:

1)從NFC標籤讀取NDEF格式的數據。
2)向NFC標籤寫入NDEF格式的數據。
3)通過Android Beam技術將NDEF數據發送到另一部NFC設備。

用於描述NDEF格式數據的兩個類:

1)NdefMessage:描述NDEF格式的信息,實際上我們寫入NFC標籤的就是NdefMessage對象。
2)NdefRecord:描述NDEF信息的一個信息段,一個NdefMessage可能包含一個或者多個NdefRecord。

NdefMessage和NdefRecord是Android NFC技術的核心類,無論讀寫NDEF格式的NFC標籤,還是通過Android Beam技術傳遞Ndef格式的數據,都需要這兩個類。

(2)非NDEF數據的操作

對於某些特殊需求,可能要存任意的數據,對於這些數據,我們就需要自定義格式。這些數據格式實際上就是普通的字節流,至於字節流中的數據代表什麼,就由開發人員自己定義了。

(3)編寫NFC程序的基本步驟

1)設置權限,限制Android版本、安裝的設備:

2)定義可接收Tag的Activity

Activity清單需要配置一下launchMode屬性:

而Activity中,我們也抽取了一個通用的BaseNfcActivity,如下(後面的Activity實現都繼承於BaseNfcActivity):

注意:通常來說,所有處理NFC的Activity都要設置launchMode屬性爲singleTop或者singleTask,保證了無論NFC標籤靠近手機多少次,Activity實例只有一個。

接下來看幾個具體的NFC標籤應用實例,通過情景學習快速掌握NFC技術:

3.兩個NFC標籤的簡單實例

1.利用NFC標籤讓Android自動運行程序

場景是這樣的:現將應用程序的包寫到NFC程序上,然後我們將NFC標籤靠近Android手機,手機就會自動運行包所對應的程序,這個是NFC比較基本的一個應用。下面以貼近標籤自動運行Android自帶的「短信」爲例。

向NFC標籤寫入數據一般分爲三步:

1)獲取Tag對象

2)判斷NFC標籤的數據類型(通過Ndef.get方法)

3)寫入數據

詳細實現代碼如下:

注意:設置 RunAppActivity 的 launchMode 屬性爲 singleTop。

現在看一下效果圖:

android-nfc-dev1

將NFC標籤貼近手機背面,自動寫入數據,此時退出所有程序,返回桌面,然後再將NFC標籤貼近手機背面,將會看到自動打開了「短信」。

android-nfc-dev2
下來再看一個有趣的例子:

2.利用NFC標籤讓Android自動打開網頁

如何讓NFC標籤貼近手機,手機可以自動打開一個網頁呢?

首先我們創建一個NdefRecord,Android已經爲我們提供好了這樣的方法:

實現代碼對比「3.利用NFC標籤讓Android自動運行程序」部分只是修改了writeNFCTag方法中

其餘不變。

android-nfc-dev3

上面這個功能還是比較有用的,例如我們往某些商品上貼上NFC標籤,裏面寫入該商品的詳細介紹網頁Uri,當用戶貼近商品時,就會自動打開該商品的詳情介紹。

通過上面這兩個案例的學習相信很多人已經對NFC感起了興趣,那麼下來滲透式的分析一下NDEF文本格式,看看NDEF到底是個什麼東西。

4.NDEF文本格式深度解析

獲取NFC標籤中的數據要通過 NdefRecord.getPayload 方法完成。當然,在處理這些數據之前,最好判斷一下NdefRecord對象中存儲的是不是NDEF文本格式數據。

(1)判斷數據是否爲NDEF格式

1)TNF(類型名格式,Type Name Format)必須是NdefRecord.TNF_WELL_KNOWN。
2)可變的長度類型必須是NdefRecord.RTD_TEXT。

如果這兩個標準同時滿足,那麼就爲NDEF格式。

(2)NDEF文本格式規範

不管什麼格式的數據本質上都是由一些字節組成的。對於NDEF文本格式來說,這些數據的第1個字節描述了數據的狀態,然後若干個字節描述文本的語言編碼,最後剩餘字節表示文本數據。這些數據格式由NFC Forum的相關規範定義,可以通過 http://members.nfc-forum.org/specs/spec_dashboard 下載相關的規範。

下面這兩張表是規範中 3.2節 相對重要的翻譯部分:

NDEF文本數據格式:

偏移量 長度(bytes) 描述
0 1 狀態字節,見下表(狀態字節編碼格式)
1 n ISO/IANA語言編碼。例如」en-US」,」fr-CA」。編碼格式是US-ASCII,長度(n)由狀態字節的後6位指定。
n+1 m 文本數據。編碼格式是UTF-8或UTF-16。編碼格式由狀態字節的前3位指定。

狀態字節編碼格式:

字節位(0是最低位,7是最高位) 含義
7 0:文本編碼爲UTF-8,1:文本編碼爲UTF-16
6 必須設爲0
5..0 語言編碼的長度(佔用的字節個數)

下面我們動手實現NFC標籤中的文本數據的讀寫操作:

1.讀NFC標籤文本數據

注意:Activity清單需要配置一下launchMode屬性(後面一樣要注意):

2.寫NFC標籤文本數據

我們將手機貼近NFC標籤,當寫入成功會彈出「寫入成功」的吐司。下面我們再驗證一下是否成功寫入:

android-nfc-dev5

我們看到,數據已經寫入成功了,說明到此我們已經成功的讀寫NFC標籤中的文本數據了。

5.NDEF Uri格式深度解析

與NDEF文本格式一樣,存儲在NFC標籤中的Uri也有一定的格式,http://members.nfc-forum.org/specs/spec_dashboard

(1)Uri的格式規範要比文本格式簡單一些:

Name 偏移 大小 描述
識別碼 0 1byte Uri識別碼 用於存儲已知Uri的前綴
Uri字段 1 N UTF-8類型字符串 用於存儲剩餘字符串

(2)Uri的前綴如下(都是十六進制的一個數):

十進制 十六進制 協議 十進制 十六進制 協議
0 0x00 N/A 1 0x01 http://www.
2 0x02 https://www. 3 0x03 http://
4 0x04 https:// 5 0x05 tel:
6 0x06 mailto: 7 0x07 ftp://anonymous:[email protected]
8 0x08 ftp://ftp. 9 0x09 ftps://
10 0x0A sftp:// 11 0x0B smb://
12 0x0C nfs:// 13 0x0D ftp://
14 0x0E dav:// 15 0x0F news:
16 0x10 telnet:// 17 0x11 imap:
18 0x12 rtsp:// 19 0x13 urn:
20 0x14 pop: 21 0x15 sip:
22 0x16 sips: 23 0x17 tftp:
24 0x18 btspp:// 25 0x19 btl2cap://
26 0x1A btgoep:// 27 0x1B tcpobex://
28 0x1C irdaobex:// 29 0x1D file://
30 0x1E urn:epc:id: 31 0x1F urn:epc:tag:
32 0x20 urn:epc:pat: 33 0x21 urn:epc:raw:
34 0x22 urn:epc: 35 0x23 urn:nfc:

每一個協議,都是用十六進制來存儲於識別碼位置(佔1byte)。

是不是相對簡單了些,那麼下來我們來解析一個Uri。

(3)預先定義已知Uri前綴

這裏我們定義一個UriPrefix類,以便方便的獲取Uri前綴:

然後我們來看一下清單文件中Activity的相關配置:

好了,接下來就可以進行讀寫NFC標籤中的Uri數據了:

1.讀NFC標籤中的Uri數據

相關文章
相關標籤/搜索