1. 從NFC tag讀取NDEF data
2. 利用Android Beam將NDEF messages從一台機器傳送到另一台機器
The Tag Dispatch System
- 當Android機台發現一個NFC tag時,最好是可以直接叫起最適當的activity來處理它而不用讓使用者選擇哪個application來處理,因為選擇的動作可能會讓使用者必須將機台離開tag。
- Android提供一個特別的tag dispatch system
1. Parse這個tag,找出data的MIME type或URI
2. 封裝這個MIME type或URI到一個intent裡面
3. 根據這個intent啟動activity
NFC tags如何map到MIME types跟URIs
- NDEF data:
- 被封裝在一個message (NdefMessage)內
- 包含一個或多個record (NdefRecord)
- Android也能支援沒有NDEF data的tags,透過android.nfc.tech package來處理
- 在標準的NDEF message中,第一個NdefRecord包含下列欄位:
1. 3-bit TNF (Type Name Format)
決定如何解譯variable length type欄位,如下表
Type Name Format (TNF) | Mapping |
---|---|
TNF_ABSOLUTE_URI | URI based on the type field. |
TNF_EMPTY | Falls back to ACTION_TECH_DISCOVERED . |
TNF_EXTERNAL_TYPE | URI based on the URN in the type field. The URN is encoded into the NDEF type field in a shortened form: <domain_name>:<service_name> . Android maps this to a URI in the form: vnd.android.nfc://ext/<domain_name>:<service_name> . |
TNF_MIME_MEDIA | MIME type based on the type field. |
TNF_UNCHANGED | Invalid in the first record, so falls back to ACTION_TECH_DISCOVERED . |
TNF_UNKNOWN | Falls back to ACTION_TECH_DISCOVERED . |
TNF_WELL_KNOWN | MIME type or URI depending on the Record Type Definition (RTD), which you set in the type field. See Table 2. for more information on available RTDs and their mappings. |
- 描述這個record的type
- 若在上個欄位使用TNF_WELL_KNOWN,則此欄位用來描述Record Type Definition (RTD),如下表所示:
Record Type Definition (RTD) | Mapping |
---|---|
RTD_ALTERNATIVE_CARRIER | Falls back to ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_CARRIER | Falls back to ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_REQUEST | Falls back to ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_SELECT | Falls back to ACTION_TECH_DISCOVERED . |
RTD_SMART_POSTER | URI based on parsing the payload. |
RTD_TEXT | MIME type of text/plain . |
RTD_URI | URI based on payload. |
- 這個record的unique ID
- 這個欄位並不常用,只有當想標明唯一tag時才需要產生這個ID
4. Variable Length Payload
- 想要讀/寫的實際data payload
- 由於一個NDEF message可能有好幾個record,所以第一個record並不一定包含全部的payload
- 若可mapping成功,則tag dispatch system會把這個map的資訊以及實際的payload封裝到一個ACTION_NDEF_DISCOVERED intent
- 若無法辨別,則會將一個
Tag
物件(包含tag的技術以及payload等資訊)封裝到一個ACTION_TECH_DISCOVERED intent- 舉例來說,當tag dispatch system遇到TNF_ABSOLUTE_URI,則它會將variable length type欄位map到一個URI,接著把這個UIR封裝到ACTION_NDEF_DISCOVERED intent中,同時也會把其他的資訊(如payload)一起包進去。
NFC tags如何dispatch到application
- tag dispatch system定義了三個intent,優先權由高到低如下:
1. ACTION_NDEF_DISCOVERED
2. ACTION_TECH_DISCOVERED
3. ACTION_TAG_DISCOVERED
Requesting NFC Access in the Android Manifest
- 必須使用<uses-permission> element以存取NFC hardware
<uses-permission android:name="android.permission.NFC" />
- 使用<uses-feature> element則有NFC的device才能在Google Play上看到你的AP
<uses-feature android:name="android.hardware.nfc" android:required="true" />
- 如果不想用<uses-feature>,那就用NfcAdapter.getDefaultAdapter()動態檢查NFC是否存在
Filtering for NFC Intents
ACTION_NDEF_DISCOVERED
- 例子: 用intent filter指出你想處理MIME type為text/plain的intent
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain" /> </intent-filter>
- 例子:處理 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
- 必須建立一個xml resource檔指出你的activity支持那些技術
<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>