NFC 基礎

文章來源:NFC Basics,此文章是google 官方對NFC的簡介。

       本文檔介紹了基本的NFC任務在Android上。它說明了如何發送和接收的NDEF消息的形式數據,並介紹支持這些功能的框架API。對於更高級內容,包括非NDEF數據的討論,請參閱高級NFC
在Android使用NDEF數據,有兩個主要的用途:
       ● 閱讀NDEF數據從一個NFC標籤
       ● 傳送NDEF信息從一個設備到另一個支持Android Beam的設備
       標籤的調度系統處理從一個NFC標籤讀取NDEF數據,它分析發現的NFC標籤,適當的數據進行分類,並針對不同的數據啓動一個應用程序。要處理的掃描NFC標籤的應用程序可以聲明一個意圖過濾器,並要求處理的數據。
        Andr​​oid Beam功能,允許一臺設備推送NDEF消息另一臺設備上通過兩臺設備物理接觸在一起。這種相互作用提供了一個比其它無線技術簡單的方法來發送數據,如藍牙,因爲有了NFC,手動發現設備或配對不是必需的。兩個設備進入範圍時,連接自動啓動。Android Beam 也成爲了一種可能可通過NFC 的一系列API,因此,任何應用都可以在設備之間傳輸信息。例如:聯繫人,瀏覽器和YouTube應用程序使用Android Beam與其他設備共享聯繫人,網頁和視頻。

標籤調度系統

        Android設備通常是在屏幕解鎖的時候掃描NFC標籤,除非NFC功能在設置菜單中被禁用。當Android 設備發現了一個NFC標籤,啓動最適當的activity處理intent,而不需要詢問用戶使用什麼應用程序處理。因爲設備掃描NFC標籤在很短的範圍內,讓用戶手動選擇的活動很有可能將迫使他們從標籤上移動設備,進而斷開連接。應該開發activity處理NFC標籤,activity以防止activity選擇出現。
        爲實現這個目標,Android提供了一個特殊的標籤調度系統來分析掃描NFC標籤並解析它們,並試圖在掃描數據中找到對應的的應用程序。這是通過:
        1. 解析NFC標籤和搞清楚的MIME類型或在標籤中用於標識一個數據URI。
        2. 封裝MIME類型或URI和有效載荷到Intent。前兩個步驟在下面的”NFC標籤是如何映射到MIME類型和URI“中有介紹。
        3. 基於Intent啓動activity。這部分具體描述在” 如何NFC標籤被分派到應用“。

NFC標籤是如何映射到MIME類型和URI

        在開始寫NFC應用前,重要的是要了解不同類型的NFC標籤,調度系統如何解析NFC標籤,和當標籤調度系統檢測到一個NDEF消息時的專項的工作。NFC標籤來在各種各樣的技術組織,也可以有許多不同方式的數據寫入。Android使用的是最受支持的NDEF標準,它是由NFC論壇定義的。
        NDEF數據被封裝內部消息(NdefMessage),它包含一個或多個的記錄(NdefRecord)。每個NDEF記錄必須形成規範的記錄。Android還支持其他的標籤不包含NDEF數據,可以通過使用在android.nfc.tech包中的類。要了解有關這些技術的更多信息,請參閱高級NFC篇。工作涉及到編寫自己的協議棧與其他類型的標籤進行通信,因此我們建議在可能的情況下使用NDEF爲易於開發和對Android的設備的最大支持。
         ★注意: 要下載完整的的NDEF規範,請到NFC論壇,參考創建通用NDEF記錄 ,學習如何構建NDEF記錄。
        現在有了NFC標籤的一些背景知識,下面的章節更詳細的描述了Android是如何處理NDEF格式的標籤。當Android手機掃 ​​描一個包含NDEF數據格式的NFC標籤,它會解析消息,並試圖找出數據的MIME類型或標識URI。要做到這一點,系統讀取NdefMessage裏的第一個NdefRecord,以確定如何解析整個的的NDEF消息(NDEF消息可以有多個NDEF記錄)。在一個良好的NDEF消息,第一NdefRecord 包含以下字段:

3-bit TNF (Type Name Format)
        指示如何解析variable length type區域。有效值像在表1中描述的。
Variable length type
         描述記錄類型。如果使用TNF_WELL_KNOWN,使用此字段指定記錄類型定義(RTD)。有效的RTD值描述在表2中。
Variable length ID
         記錄的唯一標識符。此字段不經常使用,但如果需要唯一識別的標籤,你可以爲其創建一個ID。
Variable length payload
         這個是要讀取或寫入的實際數據負載。NDEF消息可以包含多個NDEF記錄,所以不要以爲全部負載就是在第一NDEF創紀錄的NDEF消息。
         標籤調度系統使用TNF和類型字段試圖去映射的MIME類型或URI的NDEF消息。如果成功的話,它封裝了內部信息的實際有效載荷的ACTION_NDEF_DISCOVERED intent。然而,也會發生標籤調度系統不能基於第一NDEF記錄的數據確定類型。發生這種情況時,NDEF數據不能被映射到一個MIME類型或URI,或當NFC標籤不包含NDEF數據做爲開始。在這種情況下,標籤的對象,該對象具有標記的技術和有效載荷的信息,封裝一個成ACTION_TECH_DISCOVERED intent。

        表1。介紹了標籤調度系統如何根據TNF和類型字段映射到MIME類型或URIs。也說明了哪些TNFs不能被映射到MIME類型或URI。在這種情況下,標籤調度系統回到 ACTION_TECH_DISCOVERED的。

        例如,如果標籤調度系統遇到一個類型TNF_ABSOLUTE_URI紀錄,該記錄的可變長度類型字段映射到一個URI。標籤調度系統將該URI封裝成ACTION_NDEF_DISCOVERED的Intent,並攜帶關於標籤的其他信息,如負載。另一方面,如果它遇到的的記錄類型TNF_UNKNOWN,它創建封裝標籤技術的Intnet。

表1    支持TNFs和它們的映射

類型名稱格式(TNF) 映射
TNF_ABSOLUTE_URI                        基於URI的基礎類型字段
TNF_EMPTY 回到  ACTION_TECH_DISCOVERED 
TNF_EXTERNAL_TYPE 在類型字段中基於URN的URI。URN被編碼成NDEF類型縮寫形式:<domain_name>:<service_name>Android映射成URI的形式: vnd.android.nfc ://ext/ <domain_name>: <service_name>。 
TNF_MIME_MEDIA 基於類型字段MIME字段。
TNF_UNCHANGED 無效的第一條記錄中,因此回落到 ACTION_TECH_DISCOVERED的
TNF_UNKNOWN 回到 ACTION_TECH_DISCOVERED 
TNF_WELL_KNOWN 根據記錄類型定義(RTD),在類型字段設置MIME類型或URI。RTD和映射的更多信息,請參閱表2

表2  支持RTD爲TNF_WELL_KNOWN及其映射

記錄類型定義(RTD) 映射
RTD_ALTERNATIVE_CARRIER 回到 ACTION_TECH_DISCOVERED 
RTD_HANDOVER_CARRIER 回到 ACTION_TECH_DISCOVERED
RTD_HANDOVER_REQUEST 回到 ACTION_TECH_DISCOVERED 
RTD_HANDOVER_SELECT 回到 ACTION_TECH_DISCOVERED
RTD_SMART_POSTER 基於解析有效載荷的URI。
RTD_TEXT MIME類型爲text / plain
RTD_URI 基於有效載荷URI。

NFC標籤分發到應用

        標籤調度系統創建一個intent,intent封裝了NFC標籤和它的識別信息,調度系統發送給對應的應用程序,它是依據intent的過濾器。如果有一個以上的應用程序可以處理這個intent,activity選擇器就會出現,使用戶可以選擇的activity。標籤調度系統定義了三個意向,按照最高優先級到最低優先級的順序:
       1. ACTION_NDEF_DISCOVERED:當包含NDEF有效載荷或是一個公認的類型的NFC tag被掃描到時,這個Intent用來啓動一個activity。這是最高優先級的intent,標籤調度系統嘗試用這個intent啓動一個activity,早於任何其他的intent。
        2. ACTION_TECH_DISCOVERED:如果沒有activity處理ACTION_NDEF_DISCOVERED  intent,標籤調度系統嘗試使用這個intent啓動應用程序。如果被掃描tag包含NDEF的數據不能被映射到一個MIME類型或URI,或者tag不包含NDEF數據,但是是一個已知的標籤技術,在這兩種情況下,此intent也可以直接啓動(首先沒有啓動ACTION_NDEF_DISCOVERED)。
        3. ACTION_TAG_DISCOVERED:在沒有activity處理ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED的 intent時,此intent纔會被啓用。

標籤調度系統的工作原理,基本方法如下:
        1.  用intent啓動一個activity,此intent是由標籤調度系統解析NFC的tag所創建的(ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED)。
        2.  如果activity過濾器沒有過濾那個intent,就要用下一個低優先級的的intent(ACTION_TECH_DISCOVERED或ACTION_TAG_DISCOVERED)啓動activity,直到應用程序過濾器找到相應的intent,或者標籤調度系統嘗試所有可能的intent。
        3. 如果應用程序不針對任何的intent過濾,那就do nothing。


        只要有可能,都會用NDEF 消息和ACTION_NDEF_DISCOVERED 來工作,因爲它是三個Intent中最突出使用的。ACTION_NDEF_DISCOVERED 可以比其他的兩個intent能在更合適的時間啓動應用,給了用戶很好的體驗。

AndroidManifest NFC訪問的請求

在訪問NFC硬件設備和妥善處理NFCintent之前,需要在AndroidManifest.xml文件做如下動作

●訪問NFC硬件的權限

<uses-permission android:name="android.permission.NFC" />
●應用支持的最小SDK的版本。API 9通過ACTION_TAG_DISCOVERED只支持有限的標籤派遣,只通過額外 的EXTRA_NDEF_MESSAGES訪問NDEF消息。沒有其他標記的屬性或I / O操作都可以訪問。API 10包括對NDEF有了全面的讀/寫支持,API 14提供了一個簡單的方法來推送NDEF消息到其他設備和額外便捷的方法創建NDEF記錄。

<uses-sdk android:minSdkVersion="10"/>
●uses-feature可以使應用在google Play僅向支持NFC的功能的設備顯示

<uses-feature android:name="android.hardware.nfc" android:required="true" />
      如果應用程序使用NFC功能,但該功能並不重要對於應用程序來說,那就可以省略uses-feature元素,並在運行時檢查NFC的可用性,看看getDefaultAdapter() 是否爲null。

NFC Intent 過濾

        爲了要處理掃描的NFC標籤而啓動應用程序,應用程可以過濾一個,兩個或全部三個NFC intent,在Android manifest 中配置。然而,通常希望控制應用程序啓動時過濾ACTION_NDEF_DISCOVERED。沒有應用處理ACTION_NDEF_DISCOVERED或者負載數據不是NDEF時,ACTION_TECH_DISCOVERED是一個ACTION_NDEF_DISCOVERED的備用。通常ACTION_TAG_DISCOVERED是過於籠統的類別過濾。許多應用程序將過濾ACTION_TAG_DISCOVERED之前過濾ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED,所以應用程序啓動的概率很低。ACTION_TAG_DISCOVERED僅可作爲應用處理的最後手段,防止沒有其他應用程序處理 ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED。
        由於NFC標籤部署有所不同,很多時候不是你的控制之下,這並不總是可能的,這就是爲什麼在必要時可以回退到其他兩個意圖。當你有類型的標籤和數據寫入的控制權,它是建議使用的NDEF格式化標籤。以下各節描述了每種intent如何過濾。

ACTION_NDEF_DISCOVERED

          爲了過濾ACTION_NDEF_DISCOVERED,聲明intent過濾器要過濾的數據類型。下面的例子是過濾器 過濾MIME類型text / plain的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>
          下面的示例過濾器中的URI的形式 http://developer.android.com/index.html:

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
    <category android:name="android.intent.category.DEFAULT"/>
   <data android:scheme="http"
              android:host="developer.android.com"
              android:pathPrefix="/index.html" />
</intent-filter>

ACTION_TECH_DISCOVERED

        如果activityx想過濾ACTION_TECH_DISCOVERED,你必須創建含有activity支持tag的tech-list列表XML資源文件。如果tech-list列表的一個子集的技術可以被tag所支持的話,則activity被認爲是匹配的,你可以得到通過調用getTechList()獲取到tech-list列表 。例如,如果掃描到的tag支持MifareClassic的,NdefFormatable,NfcA,tech-list列表必須指定所有三個,兩個或技術中的一個(還可以有其他的),以便匹配activity。
        下面的示例定義的所有技術。你可以刪除你不需要的那些。將此文件保存在<project-root> / res / xml文件夾(你可以將其命名爲任何你希望的) 。

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <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>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>
        還可以定義多重的tech-list列表,他們被認爲是獨立的。如果任何單一的tech-list列表中技術作爲getTechList()返回集合的子集,那activity被認爲是匹配的。這提供了AND和OR 匹配技術。下面的例子匹配的標籤,可以支持NFCA及NDEF,也可以支持NfcB 和NDEF:
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.NfcA</tech>
        <tech>android.nfc.tech.Ndef</tech>
    </tech-list>
</resources>

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.NfcB</tech>
        <tech>android.nfc.tech.Ndef</tech>
    </tech-list>
</resources>
           在AndroidManifest.xml文件中,指定剛剛創建資源文件到的<meta-data>元素,它是<activity> 元素的子元素,下面的例子:
<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>

           關於tag技術和ACTION_TECH_DISCOVERED協作更多信息,請參閱高級NFC文檔。

ACTION_TAG_DISCOVERED

要過濾ACTION_TAG_DISCOVERED使用下面的intent過濾器:

<intent-filter>
    <action android:name="android.nfc.action.TAG_DISCOVERED"/>
</intent-filter>

從意圖獲取信息

        如果一項活動開始因爲NFC的intent,從intent可以得到掃描到的NFC標籤的信息。intent包含依附在tag上以下額外的信息:
        ● EXTRA_TAG(必需的):標籤對象代表掃描標籤。
        ● EXTRA_NDEF_MESSAGES(可選):解析tag獲取的NDEF消息數組。這額外的意圖是強制性的。
        ● {android.nfc.NfcAdapter#EXTRA_ID(可選):低級別的ID標籤。
         要獲得這些額外檢查,看是否活動推出的與NFC意圖之一,以確保標籤被掃描,然後獲取額外的意圖。下面的例子檢查的ACTION_NDEF_DISCOVERED 意圖,並得到意向額外的NDEF消息。






未完待續

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章