SkySeraph
- 部落格園
- 首頁
- 新随筆
- 聯系
- 訂閱
- 管理
随筆- 192 文章- 0 評論- 441
【NFC】Android NFC API Reference中英文
【NFC】Android NFC API Reference中英文
SkySeraph Jan 25th 2013
Email:[email protected]
0 Near Field Communication
Near Field Communication (NFC) is a set of short-range wireless technologies, typically requiring a distance of 4cm or less to initiate a connection. NFC allows you to share small payloads of data between an NFC tag and an Android-powered device, or between two Android-powered devices. | 近場通信(NFC)是一個短範圍無線技術集合,通常需要4厘米或更短的距離才能初始化連接配接。NFC允許在NFC标簽和Android裝置之間或兩個Android裝置之間共享小的資料的負載。 |
Tags can range in complexity. Simple tags offer just read and write semantics, sometimes with one-time-programmable areas to make the card read-only. More complex tags offer math operations, and have cryptographic hardware to authenticate access to a sector. The most sophisticated tags contain operating environments, allowing complex interactions with code executing on the tag. The data stored in the tag can also be written in a variety of formats, but many of the Android framework APIs are based around a NFC Forum standard called NDEF (NFC Data Exchange Format). | NFC标簽具有複雜的分類。簡單的NFC标簽隻提供讀寫文法,某些時候一次隻能以隻讀的方式讀取卡片的可程式設計區域。複雜一點的NFC标簽提供了數學運算能力,而且有加密的硬體來認證對一個扇區的通路。最複雜的NFC标簽包含了運算環境,允許在标簽上執行複雜的互動代碼。存儲在标簽中的資料也可以用各種格式來編寫,但是大多數的Android架構API都使用基于NDEF(NFC Data Exchange Format)的标準。 |
1 NFC Basic
This document describes the basic NFC tasks you perform in Android. It explains how to send and receive NFC data in the form of NDEF messages and describes the Android framework APIs that support these features. For more advanced topics, including a discussion of working with non-NDEF data, seeAdvanced NFC. There are two major uses cases when working with NDEF data and Android: Reading NDEF data from an NFC tag Beaming NDEF messages from one device to another with Android Beam™ | 本文介紹在Android系通過你所能執行的基本任務。它解釋了如何用NDEF消息格式來發送和接收NFC資料,并且介紹了支援這些功能的Android架構API。有關更進階的話題,包括對非NDEF格式資料的讨論,情況“進階 NFC” NDEF資料和Android一起工作的場景主要有兩個: 1. 從NFC标簽中讀取NDEF資料; 【讀資料】 2. 把NDEF消息從一個裝置發送給另一個裝置。【資料傳遞】 |
Reading NDEF data from an NFC tag is handled with thetag dispatch system, which analyzes discovered NFC tags, appropriately categorizes the data, and starts an application that is interested in the categorized data. An application that wants to handle the scanned NFC tag can declare an intent filter and request to handle the data. | 從NFC标簽中讀取NDEF資料是用标簽排程系統來處理的,它會分析被發現的NFC标簽,對資料進行适當的分類,并啟動對該類資料感興趣的應用程式。想要處理被掃描到NFC标簽的應用程式會聲明一個Intent過濾器,并請求處理資料。 |
The Android Beam™ feature allows a device to push an NDEF message onto another device by physically tapping the devices together. This interaction provides an easier way to send data than other wireless technologies like Bluetooth, because with NFC, no manual device discovery or pairing is required. The connection is automatically started when two devices come into range. Android Beam is available through a set of NFC APIs, so any application can transmit information between devices. For example, the Contacts, Browser, and YouTube applications use Android Beam to share contacts, web pages, and videos with other devices. | Android Beam™ 功能允許裝置把一個NDEF消息推送到實體/硬體上互相監聽的另一個裝置上。這種互動提供了比其他無線技術(如藍牙)更容易的發送資料的方法。因為NFC不需要手動的裝置發現或配對要求,兩個裝置在接近到一定範圍時會自動的連接配接。Android Beam通過一組NFC API來使用,以便應用程式能夠在裝置之間來傳輸資訊。例如,通信錄、浏覽器以及YouTube等應用程式都使用Android Beam來跟其他裝置共享通信錄、網頁和視訊。 |
1.1 NFC标簽排程系統 (The Tag Dispatch System)
Android-powered devices are usually looking for NFC tags when the screen is unlocked, unless NFC is disabled in the device's Settings menu. When an Android-powered device discovers an NFC tag, the desired behavior is to have the most appropriate activity handle the intent without asking the user what application to use. Because devices scan NFC tags at a very short range, it is likely that making users manually select an activity would force them to move the device away from the tag and break the connection. You should develop your activity to only handle the NFC tags that your activity cares about to prevent the Activity Chooser from appearing. | 通常,除非是在裝置的設定菜單中NFC被禁用,否則Android裝置會在非鎖屏的狀态下搜尋NFC。當Android裝置發現NFC标簽時,期望的行為是用最合适的Activity來處理該Intent,而不是詢問使用者使用什麼應用程式。因為裝置隻能在很短的範圍内掃描到NFC标簽,強制的讓使用者手動的選擇一個Activity,會導緻裝置離開NFC标簽,進而中斷該連接配接。你應該開發你自己的Activity來處理你所關心的NFC标簽,進而阻止 選擇器的操作。 |
To help you with this goal, Android provides a special tag dispatch system that analyzes scanned NFC tags, parses them, and tries to locate applications that are interested in the scanned data. It does this by:
| 為了幫助你達到這個目标,Android提供了特殊的标簽排程系統,來分析掃描到的NFC标簽,通過解析資料,在被掃描到的資料中嘗試找到感興趣的應用程式,具體做法如下: 1. 解析NFC标簽并搞清楚标簽中辨別資料負載的MIME類型或URI; 2. 把MIME類型或URI以及資料負載封裝到一個Intent中。 3. 基于Intent來啟動Activity。 |
1.1.1 怎樣把NFC标簽映射到MIME類型和URI (How NFC tags are mapped to MIME types and URIs)
Before you begin writing your NFC applications, it is important to understand the different types of NFC tags, how the tag dispatch system parses NFC tags, and the special work that the tag dispatch system does when it detects an NDEF message. NFC tags come in a wide array of technologies and can also have data written to them in many different ways. Android has the most support for the NDEF standard, which is defined by the NFC Forum. | 開始編寫NFC應用程式之前,重要的是要了解不同類型的NFC标簽、标簽排程系統是如何解析NFC标簽的、以及在檢測到NDEF消息時,标簽排程系統所做的特定的工作等。NFC标簽涉及到廣泛的技術,并且有很多不同的方法向标簽中寫入資料。Android支援由NFC Forum所定義的NDEF标準。 |
NDEF data is encapsulated inside a message (NdefMessage) that contains one or more records (NdefRecord). Each NDEF record must be well-formed according to the specification of the type of record that you want to create. Android also supports other types of tags that do not contain NDEF data, which you can work with by using the classes in theandroid.nfc.tech package. To learn more about these technologies, see the Advanced NFC topic. Working with these other types of tags involves writing your own protocol stack to communicate with the tags, so we recommend using NDEF when possible for ease of development and maximum support for Android-powered devices. | NDEF資料被封裝在一個消息(NdefMessage)中,該消息中包含了一條或多條記錄(NdefRecord)。每個NDEF記錄必須具有良好的你想要建立的記錄類型的規範的格式。Android也支援其他的不包含NDEF資料類型的标簽,你能夠使用android.nfc.tech包中的類來工作。要使用其他類型标簽來工作,涉及到編寫自己的跟該标簽通信的協定棧,是以我們建議你盡可能的使用NDEF,以便減少開發難度,并且最大化的支援Android裝置。 |
Note:To download complete NDEF specifications, go to the NFC Forum Specification Download site and seeCreating common types of NDEF records for examples of how to construct NDEF records. | 注意:要下載下傳完整的NDEF規範,請去“NFC論壇規範下載下傳”網址來下載下傳。 |
Now that you have some background in NFC tags, the following sections describe in more detail how Android handles NDEF formatted tags. When an Android-powered device scans an NFC tag containing NDEF formatted data, it parses the message and tries to figure out the data's MIME type or identifying URI. To do this, the system reads the first NdefRecord inside the NdefMessage to determine how to interpret the entire NDEF message (an NDEF message can have multiple NDEF records). In a well-formed NDEF message, the first NdefRecordcontains the following fields: | 現在,你已經具備了一些NFC标簽的背景知識,接下來要詳細的介紹Android是如何處理NDEF格式的标簽的。當Android裝置掃描到包含NDEF格式資料的NFC标簽時,它會解析該消息,并嘗試搞清楚資料的MIME類型或URI辨別。首先系統會讀取消息(NdefMessage)中的第一條NdefRecord,來判斷如何解釋整個NDEF消息(一個NDEF消息能夠有多條NDEF記錄)。 在格式良好的NDEF消息中,第一條NdefRecord包含以下字段資訊: |
3-bit TNF (Type Name Format) Indicates how to interpret the variable length type field. Valid values are described in described in Table 1. Variable length type Describes the type of the record. If usingTNF_WELL_KNOWN, use this field to specify the Record Type Definition (RTD). Valid RTD values are described in Table 2. Variable length ID A unique identifier for the record. This field is not used often, but if you need to uniquely identify a tag, you can create an ID for it. Variable length payload The actual data payload that you want to read or write. An NDEF message can contain multiple NDEF records, so don't assume the full payload is in the first NDEF record of the NDEF message. | 3-bit TNF(類型名稱格式) 訓示如何解釋可變長度類型字段,在下表1中介紹有效值。 可變長度類型 說明記錄的類型,如果使用TNF_WELL_KNOWN,那麼則使用這個字段來指定記錄的類型定義(RTD)。在下表2中定義了有效的RTD值。 可變長度ID 唯一辨別該記錄。這個字段不經常使用,但是,如果需要唯一的辨別一個标記,那麼就可以為該字段建立一個ID。 可變長度負載 你想讀/寫的實際的資料負載。一個NDEF消息能夠包含多個NDEF記錄,是以不要以為在NDEF消息的第一條NDEF記錄中包含了所有的負載。 |
The tag dispatch system uses the TNF and type fields to try to map a MIME type or URI to the NDEF message. If successful, it encapsulates that information inside of a ACTION_NDEF_DISCOVERED intent along with the actual payload. However, there are cases when the tag dispatch system cannot determine the type of data based on the first NDEF record. This happens when the NDEF data cannot be mapped to a MIME type or URI, or when the NFC tag does not contain NDEF data to begin with. In such cases, aTag object that has information about the tag's technologies and the payload are encapsulated inside of a ACTION_TECH_DISCOVERED intent instead. | 标簽排程系統使用TNF和類型字段來嘗試把MIME類型或URI映射到NDEF消息中。如果成功,它會把資訊跟實際的負載一起封裝到ACTION_NEDF_DISCOVERED類型的Intent中。但是,會有标簽排程系統不能根據第一條NDEF記錄來判斷資料類型的情況,這樣就會有NDEF資料不能被映射到MIME類型或URI,或者是NFC标簽沒有包含NDEF開始資料的情況發生。在這種情況下,就會用一個标簽技術資訊相關的Tag對象和封裝在ACTION_TECH_DISCOVERED類型Intent對象内部的負載來代替。 |
Table 1. describes how the tag dispatch system maps TNF and type fields to MIME types or URIs. It also describes which TNFs cannot be mapped to a MIME type or URI. In these cases, the tag dispatch system falls back toACTION_TECH_DISCOVERED. | 表1. 介紹标簽排程系統映射如何把TNF和類型字段映射到MIME型或URI上。同時也介紹了那種類型的TNF不能被映射到MIME類型或URI上。這種情況下,标簽排程系統會退化到ACTION_TECH_DISCOVERED類型的Intent對象。 |
For example, if the tag dispatch system encounters a record of type TNF_ABSOLUTE_URI, it maps the variable length type field of that record into a URI. The tag dispatch system encapsulates that URI in the data field of an ACTION_NDEF_DISCOVERED intent along with other information about the tag, such as the payload. On the other hand, if it encounters a record of type TNF_UNKNOWN, it creates an intent that encapsulates the tag's technologies instead. | 例如,如果标簽排程系統遇到一個TNF_ABSOLUTE_URI類型的記錄,它會把這個記錄的可變長度類型字段映射到一個URI中。标簽排程系統會把這個URI跟其他相關的标簽的資訊(如資料負載)一起封裝到ACTION_NDEF_DISCOVERED的Intent對象中。在另一方面,如果遇到了TNF_UNKNOWN類型,它會建立一個封裝了标簽技術資訊的Intent對象來代替。 |
表1. 所支援的TNF和它們的映射
類型名稱格式(TNF) | 映射 |
TNF_ABSOLUTE_URI | 基于類型字段的URI |
TNF_EMPTY | 退化到ACTION_TECH_DISCOVERED類型的Intent對象 |
TNF_EXTERNAL_TYPE | 基于類型字段中URN的URI。URN是縮短的格式(<domain_name>:<service_name)被編碼到NDEF類型中。 Android會把這個URN映射成以下格式的URI:vnd.android.nfc://ext/<domain_name>:<service_name> |
TNF_MIME_MEDIA | 基于類型字段的MIME類型 |
TNF_UNCHANGED | 退化到ACTION_TECH_DISCOVERED類型的Intent對象 |
TNF_UNKNOWN | 退化到ACTION_TECH_DISCOVERED類型的Intent對象 |
TNF_WELL_KNOWN | 依賴你在類型字段中設定的記錄類型定義(RTD)的MIME類型或URI |
表2. TNF_WELL_KNOWN所支援的RTD和它們的映射
記錄類型定義(RTD) | 映射 |
RTD_ALTERNATIVE_CARRIER | 退化到ACTION_TECH_DISCOVERED類型的Intent對象 |
RTD_HANDOVER_CARRIER | 退化到ACTION_TECH_DISCOVERED類型的Intent對象 |
RTD_HANDOVER_REQUEST | 退化到ACTION_TECH_DISCOVERED類型的Intent對象 |
RTD_HANDOVER_SELECT | 退化到ACTION_TECH_DISCOVERED類型的Intent對象 |
RTD_SMART_POSTER | 基于負載解析的URI |
RTD_TEXT | text/plain類型的MIME |
RTD_URI | 基于有效負載的URI |
1.1.2 應用程式如何排程NFC标簽(How NFC Tags are Dispatched to Applications)
When the tag dispatch system is done creating an intent that encapsulates the NFC tag and its identifying information, it sends the intent to an interested application that filters for the intent. If more than one application can handle the intent, the Activity Chooser is presented so the user can select the Activity. The tag dispatch system defines three intents, which are listed in order of highest to lowest priority:
| 當标簽排程系統完成對NFC标簽和它的辨別資訊封裝的Intent對象的建立時,它會把該Intent對象發送給感興趣的應用程式。如果有多個應用程式能夠處理該Intent對象,就會顯示Activity選擇器,讓使用者選擇Activity。标簽排程系統定義了三種Intent對象,以下按照由高到低的優先級列出這三種Intent對象: 1. ACTION_NDEF_DISCOVERED: 這種Intent用于啟動包含NDEF負載和已知類型的标簽的Activity。這是最高優先級的Intent,并且标簽排程系統在任何其他Intent之前,都會盡可能的嘗試使用這種類型的Intent來啟動Activity。 2. ACTION_TECH_DISCOVERED: 如果沒有注冊處理ACTION_NDEF_DISCOVERED類型的Intent的Activity,那麼标簽排程系統會嘗試使用這種類型的Intent來啟動應用程式。如果被掃描到的标簽包含了不能被映射到MIME類型或URI的NDEF資料,或者沒有包含NDEF資料,但是是已知的标簽技術,那麼也會直接啟動這種類型的Intent對象(而不是先啟動ACTION_NDEF_DISCOVERED類型的Intent) 3. ACTION_TAB_DISCOVERED: 如果沒有處理ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED類型Intent的Activity,就會啟動這種類型的Intent。 |
The basic way the tag dispatch system works is as follows:
| 标簽排程系統的基本工作方法如下: 1. 用解析NFC标簽時由标簽排程系統建立的Intent對象(ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED)來嘗試啟動Activity; 2. 如果沒有對應的處理Intent的Activity,那麼就會嘗試使用下一個優先級的Intent(ACTION_TECH_DISCOVERED或ACTION_TAG_DISCOVERED)來啟動Activity,直到有對應的應用程式來處理這個Intent,或者是直到标簽排程系統嘗試了所有可能的Intent。 3. 如果沒有應用程式來處理任何類型的Intent,那麼就不做任何事情。 |
Whenever possible, work with NDEF messages and the ACTION_NDEF_DISCOVERED intent, because it is the most specific out of the three. This intent allows you to start your application at a more appropriate time than the other two intents, giving the user a better experience. | 在可能的情況下,都會使用NDEF消息和ACTION_NDEF_DISCOVERED類型的Intent來工作,因為它是這三種Intent中最标準的。這種Intent與其他兩種Intent相比,它會允許你在更加合适的時機來啟動你的應用程式,進而給使用者帶來更好的體驗。 |
圖1. 标簽排程系統 Tag Dispatch System
1.2 在Android的Manifest中申請NFC通路
Before you can access a device's NFC hardware and properly handle NFC intents, declare these items in your AndroidManifest.xml file: | 在通路裝置的NFC硬體和正确的處理NFC的Intent之前,要在AndroidManifest.xml檔案中進行以下聲明: |
1 The NFC <uses-permission> element to access the NFC hardware: <uses-permission android:name="android.permission.NFC" /> 2 The minimum SDK version that your application can support. API level 9 only supports limited tag dispatch via ACTION_TAG_DISCOVERED, and only gives access to NDEF messages via theEXTRA_NDEF_MESSAGES extra. No other tag properties or I/O operations are accessible. API level 10 includes comprehensive reader/writer support as well as foreground NDEF pushing, and API level 14 provides an easier way to push NDEF messages to other devices with Android Beam and extra convenience methods to create NDEF records. <uses-sdk android:minSdkVersion="10"/> 3 The uses-feature element so that your application shows up in Google Play only for devices that have NFC hardware: <uses-feature android:name="android.hardware.nfc" android:required="true" /> | 1. 在<uses-permission>元素中聲明通路NFC硬體: <uses-permission android:name="android.permission.NFC" /> 2. 你的應用程式所支援的最小的SDK版本。API Level 9隻通過ACTION_TAG_DISCOVERED來支援有限的标簽排程,并且隻能通過EXTRA_NDEF_MESSAGES來通路NDEF消息。沒有其他的标簽屬性或I/O操作可用。API Level 10中包含了廣泛的讀寫支援,進而更好的推動了NDEF的應用前景,并且API Leve 14用Android Beam和額外的友善的建立NDEF記錄的方法,向外提供了更容易的把NDEF消息推送給其他裝置的方法。 <uses-sdkandroid:minSdkVersion="10"/> 3. 使用uses-feature元素,在Google Play中,以便你的應用程式能夠隻針對有NFC硬體的裝置來顯示。 <uses-featureandroid:name="android.hardware.nfc"android:required="true"/> |
If your application uses NFC functionality, but that functionality is not crucial to your application, you can omit the uses-feature element and check for NFC avalailbility at runtime by checking to see ifgetDefaultAdapter()is null. | 如果你的應用程式使用了NFC功能,但是相關的功能又不是你的應用程式的關鍵功能,你可以忽略uses-feature元素,并且要在運作時通過調用getDefaultAdapter()方法來檢查NFC是否有效。 |
1.3 過濾NFC的Intent (Filtering for NFC Intents)
To start your application when an NFC tag that you want to handle is scanned, your application can filter for one, two, or all three of the NFC intents in the Android manifest.
| 要在你想要處理被掃描到的NFC标簽時啟動你的應用程式,可以在你的應用程式的Android清單中針對一種、兩種或全部三種類型的NFC的Intent來過濾。
|
Because NFC tag deployments vary and are many times not under your control, this is not always possible, which is why you can fallback to the other two intents when necessary. When you have control over the types of tags and data written, it is recommended that you use NDEF to format your tags. The following sections describe how to filter for each type of intent. | 因為NFC标簽的多樣性,并且很多時候不在你的控制之下,是以在必要的時候你要回退到其他兩種類型的Intent。在你能夠控制标簽的類型和寫入的資料時,我們建議你使用NDEF格式。下文将介紹如何過濾每種類型的Intent對象。 |
1.3.1 ACTION_NDEF_DISCOVERED
To filter for ACTION_NDEF_DISCOVERED intents, declare the intent filter along with the type of data that you want to filter for. The following example filters for ACTION_NDEF_DISCOVERED intents with a MIME type of text/plain: <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain" /> </intent-filter> The following example filters for a URI in the form ofhttp://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_NDEF_DISCOVERED類型的Intent,就要在清單中跟你想要過濾的資料一起來聲明該類型的Intent過濾器。 以下是過濾text/plain類型的MIME的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> 以下示例使用http://developer.android.com/index.html格式的URI來過濾: <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> |
1.3.2 ACTION_TECH_DISCOVERED
If your activity filters for theACTION_TECH_DISCOVERED intent, you must create an XML resource file that specifies the technologies that your activity supports within a tech-list set. Your activity is considered a match if a tech-list set is a subset of the technologies that are supported by the tag, which you can obtain by calling getTechList(). | 如果你的Activity要過濾ACTION_TECH_DISCOVERED類型的Intent,你必須建立一個XML資源檔案,該檔案在tech-list集合中指定你的Activity所支援的技術。如果tech-list集合是标簽所支援的技術的一個子集,那麼你的Activity被認為是比對的。通過調用getTechList()方法來獲得标簽所支援的技術集合。 |
For example, if the tag that is scanned supports MifareClassic, NdefFormatable, and NfcA, your tech-list set must specify all three, two, or one of the technologies (and nothing else) in order for your activity to be matched. | 例如,如果掃描到的标簽支援MifareClassic、NdefFormatable和NfcA,那麼為了跟它們比對,tech-list集合就必須指定所有這三種技術,或者指定其中的兩種或一種。 |
The following sample defines all of the technologies. You can remove the ones that you do not need. Save this file (you can name it anything you wish) in the <project-root>/res/xml folder. | 以下示例定義了所有的相關的技術。你可以根據需要删除其中一些設定。然後把這個檔案儲存到<project-root>/res/xml檔案夾中(你能夠把命名為任何你希望的名字): |
View Code
You can also specify multiple tech-list sets. Each of the tech-list sets is considered independently, and your activity is considered a match if any single tech-list set is a subset of the technologies that are returned bygetTechList(). This provides AND and OR semantics for matching technologies. The following example matches tags that can support the NfcA and Ndef technologies or can support the NfcB and Ndef technologies: | 你也能夠指定多個tech-list集合,每個tech-list集合被認為是獨立的,并且如果任何一個tech-list集合是由getTechList()傳回的技術的子集,那麼你的Activity就被認為是比對的。 下列示例能夠跟支援NfcA和Ndef技術NFC标簽或者跟支援NfcB和Ndef技術的标簽相比對: |
View Code
In your AndroidManifest.xml file, specify the resource file that you just created in the <meta-data> element inside the <activity> element like in the following example: | 在你的AndroidManifest.xml檔案中,要像向下列示例那樣,在<activity>元素内的<meta-data>元素中指定你建立的資源檔案: |
View Code
1.3.3 ACTION_TAG_DISCOVERED
To filter for ACTION_TAG_DISCOVERED use the following intent filter: | 使用下列Intent過濾器來過濾ACTION_TAG_DISCOVERED類型的Intent: |
View Code
1.3.4 從Intent中擷取資訊 (Obtaining information from intents)
If an activity starts because of an NFC intent, you can obtain information about the scanned NFC tag from the intent. Intents can contain the following extras depending on the tag that was scanned: | 如果因為NFC的Intent而啟動一個Activity,那麼你就能夠從Intent中擷取被掃描到的NFC标簽的相關資訊。根據被掃描到的标簽,Intent對象能夠以下額外的資訊: |
EXTRA_TAG (required): A Tag object representing the scanned tag. EXTRA_NDEF_MESSAGES (optional): An array of NDEF messages parsed from the tag. This extra is mandatory onintents. {@link android.nfc.NfcAdapter#EXTRA_ID (optional): The low-level ID of the tag. | 1. EXTRA_TAG(必須的):它是一個代表了被掃描到的标簽的Tag對象; 2. EXTRA_NDEF_MESSAGES(可選):它是一個解析來自标簽中的NDEF消息的數組。這個附加資訊是強制在Intent對象上的; 3. {@link android.nfc.NfcAdapter#EXTRA_ID(可選):标簽的低級ID。 |
To obtain these extras, check to see if your activity was launched with one of the NFC intents to ensure that a tag was scanned, and then obtain the extras out of the intent. The following example checks for theACTION_NDEF_DISCOVEREDintent and gets the NDEF messages from an intent extra. | 要擷取這些附加資訊,就要確定你的Activity是被掃描到的NFC的Intent對象啟動的,然後才能獲得Intent之外的附加資訊。 下例檢查ACTION_NDEF_DISCOVERED類型的Intent,并從Intent對象的附加資訊中擷取NDEF消息。 |
View Code
Alternatively, you can obtain a Tag object from the intent, which will contain the payload and allow you to enumerate the tag's technologies: Tag tag= intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); | 此外,你還能夠從Intent對象中獲得一個Tag對象,該對象包含了資料負載,并允許你列舉标簽的技術: Tag tag= intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); |
1.4 建立通用的NDEF記錄類型 (Creating Common Types of NDEF Records)
This section describes how to create common types of NDEF records to help you when writing to NFC tags or sending data with Android Beam. Starting with Android 4.0 (API level 14), thecreateUri() method is available to help you create URI records automatically. Starting in Android 4.1 (API level 16), createExternal()and createMime() are available to help you create MIME and external type NDEF records. Use these helper methods whenever possible to avoid mistakes when manually creating NDEF records. This section also describes how to create the corresponding intent filter for the record. All of these NDEF record examples should be in the first NDEF record of the NDEF message that you are writing to a tag or beaming. | 本節介紹如何建立通用的NDEF記錄類型,以便幫助你向NFC标簽寫入或用Android Beam發送資料。 從Android4.0(API Level14)開始,可以用createUri()方法來幫助你自動的建立URI記錄。 從Android4.1(API Level 16)開始,可以用createExternal()和createMime()方法來幫助你建立MIME和外部類型的NDEF記錄。 使用這些輔助方法會盡可能的避免手動建立NDEF記錄的錯誤。 本節還要介紹如何建立NDEF記錄對應的Intent過濾器。所有的這些寫入或發送到NFC标簽的NDEF記錄例子都應該是NDEF消息的第一條記錄。 |
1.4.1 TNF_ABSOLUTE_URI
Note: We recommend that you use the RTD_URI type instead of TNF_ABSOLUTE_URI, because it is more efficient. | 注意:我們推薦你使用RTD_URI類型,而不是TNF_ABSOLUTE_URI, 因為它更高效。 |
You can create a TNF_ABSOLUTE_URI NDEF record in the following way: | 用下列方法建立一個TNF_ABSOLUTE_URI類型的NDEF記錄: |
NdefRecord uriRecord = new NdefRecord( NdefRecord.TNF_ABSOLUTE_URI ,"http://developer.android.com/index.html".getBytes(Charset.forName("US-ASCII")),new byte[0], new byte[0]);
The intent filter for the previous NDEF record would look like this: | 對應的Intent過濾器如下: |
<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>
1.4.2 TNF_MIME_MEDIA
You can create a TNF_MIME_MEDIA NDEF record in the following ways. Using the createMime() method: | 使用下列方法建立TNF_MIME_MEDIA類型的NDEF記錄。 使用createMime()方法: |
NdefRecord mimeRecord = NdefRecord.createMime("application/vnd.com.example.android.beam","Beam me up, Android".getBytes(Charset.forName("US-ASCII")));
Creating the NdefRecord manually: | 手動的建立NdefRecord: |
NdefRecord mimeRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA ,"application/vnd.com.example.android.beam".getBytes(Charset.forName("US-ASCII")),
new byte[0], "Beam me up, Android!".getBytes(Charset.forName("US-ASCII")));
The intent filter for the previous NDEF records would look like this: | 對應的Intent過濾器如下: |
View Code
1.4.3 TNF_WELL_KNOWN和RTD_TEXT
You can create a TNF_WELL_KNOWN NDEF record in the following way: public NdefRecord createTextRecord(String payload, Locale locale, boolean encodeInUtf8) { byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII")); Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16"); byte[] textBytes = payload.getBytes(utfEncoding); int utfBit = encodeInUtf8 ? 0 : (1 << 7); char status = (char) (utfBit + langBytes.length); byte[] data = new byte[1 + langBytes.length + textBytes.length]; data[0] = (byte) status; System.arraycopy(langBytes, 0, data, 1, langBytes.length); System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length); NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data); return record; } | 用下列方法建立TNF_WELL_KNOWN類型的NDEF記錄: public NdefRecord createTextRecord(String payload, Locale locale, boolean encodeInUtf8) { byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII")); Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16"); byte[] textBytes = payload.getBytes(utfEncoding); int utfBit = encodeInUtf8 ? 0 : (1 << 7); char status = (char) (utfBit + langBytes.length); byte[] data = new byte[1 + langBytes.length + textBytes.length]; data[0] = (byte) status; System.arraycopy(langBytes, 0, data, 1, langBytes.length); System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length); NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data); return record; } |
the intent filter would look like this: <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> | 對應的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> |
1.4.4 TNF_WELL_KNOW和RTD_URI
You can create a TNF_WELL_KNOWN NDEF record in the following ways. Using the createUri(String) method: NdefRecord rtdUriRecord1=NdefRecord.createUri("http://example.com"); | 用下列方法建立TNF_WELL_KNOWN類型的NDEF記錄。 使用createUri(String)方法: NdefRecord rtdUriRecord1=NdefRecord.createUri("http://example.com"); |
Using the createUri(Uri) method: Uri uri = new Uri("http://example.com"); NdefRecord rtdUriRecord2 = NdefRecord.createUri(uri); | 使用createUri(Uri)方法: Uri uri = new Uri("http://example.com"); NdefRecord rtdUriRecord2 = NdefRecord.createUri(uri); |
Creating the NdefRecord manually: byte[] uriField = "example.com".getBytes(Charset.forName("US-ASCII")); byte[] payload = new byte[uriField.length + 1]; //add 1 for the URI Prefix byte payload[0] = 0x01; //prefixeshttp://www. to the URI System.arraycopy(uriField, 0, payload, 1, uriField.length); //appends URI to payload NdefRecord rtdUriRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload); | 手動的建立NdefRecord: byte[] uriField = "example.com".getBytes(Charset.forName("US-ASCII")); byte[] payload = new byte[uriField.length + 1]; //add 1 for the URI Prefix byte payload[0] = 0x01; //prefixeshttp://www. to the URI System.arraycopy(uriField, 0, payload, 1, uriField.length); //appends URI to payload NdefRecord rtdUriRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload); |
The intent filter for the previous NDEF records would look like this: <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="http" android:host="example.com" android:pathPrefix="" /> </intent-filter> | 對應的Intent過濾器如下: <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="http" android:host="example.com" android:pathPrefix="" /> </intent-filter> |
1.4.5 TNF_EXTERNAL_TYPE
You can create a TNF_EXTERNAL_TYPE NDEF record in the following ways: Using the createExternal() method: | 使用下列方法建立TNF_EXTERNAL_TYPE類型的記錄。 使用createExternal()方法: |
byte[] payload; //assign to your data
String domain = "com.example"; //usually your app's package name
String type = "externalType";
NdefRecord extRecord = NdefRecord.createExternal(domain, type, payload);
Creating the NdefRecord manually: | 手動的建立NdefRecord: |
byte[] payload;
...
NdefRecord extRecord = new NdefRecord(
NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType", new byte[0], payload);
The intent filter for the previous NDEF records would look like this: | 對應的Intent過濾器如下: |
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="vnd.android.nfc"
android:host="ext"
android:pathPrefix="/com.example:externalType"/>
</intent-filter>
Use TNF_EXTERNAL_TYPE for more generic NFC tag deployments to better support both Android-powered and non-Android-powered devices. | 使用更加一般化的TNF_EXTERNAL_TYPE類型NFC部署,以便更好的支援Android裝置和非Android裝置。 |
Note: URNs for TNF_EXTERNAL_TYPE have a canonical format of:urn:nfc:ext:example.com:externalType, however the NFC Forum RTD specification declares that the urn:nfc:ext: portion of the URN must be ommitted from the NDEF record. So all you need to provide is the domain (example.com in the example) and type (externalType in the example) separated by a colon. When dispatching TNF_EXTERNAL_TYPE, Android converts the urn:nfc:ext:example.com:externalType URN to avnd.android.nfc://ext/example.com:externalType URI, which is what the intent filter in the example declares. | 注意:TNF_EXTERNAL_TYPE類型的URN包含以下格式: urn:nfc:ext:example.com.externalType,但是,NFC論壇的RTD規範聲明,URN的urn:nfc:ext:部分在NDEF記錄中必須忽略。是以你需要提供的所有資訊是用“:”号把域名(示例中的example.com)和類型(示例中的externalType)分離開。在排程TNF_EXTERNAL_TYPE類型的記錄時,Android會把urn:nfc:ext:example.com:externalType的URN轉換成vnd.android.nfc://ext/example.com:externalType的URI,它是在示例中聲明的Intent過濾器。 |
1.5 Android應用程式記錄(Android Application Record---AAR)
Introduced in Android 4.0 (API level 14), an Android Application Record (AAR) provides a stronger certainty that your application is started when an NFC tag is scanned. An AAR has the package name of an application embedded inside an NDEF record. You can add an AAR to any NDEF record of your NDEF message, because Android searches the entire NDEF message for AARs. If it finds an AAR, it starts the application based on the package name inside the AAR. If the application is not present on the device, Google Play is launched to download the application. | 在Android4.0(API Level 14)中引入的Android應用程式記錄(AAR),提供了較強的在掃描到NFC标簽時,啟動應用程式的确定性。AAR有嵌入到NDEF記錄内部的應用程式的包名。你能夠把一個AAR添加到你的NDEF消息的任何記錄中,因為Android會針對AAR來搜尋整個NDEF消息。如果它找到一個AAR,它就會基于AAR内部的包名來啟動應用程式。如果該應用程式不在目前的裝置上,會啟動Google Play來下載下傳對應的應用程式。 |
AARs are useful if you want to prevent other applications from filtering for the same intent and potentially handling specific tags that you have deployed. AARs are only supported at the application level, because of the package name constraint, and not at the Activity level as with intent filtering. If you want to handle an intent at the Activity level, use intent filters. If a tag contains an AAR, the tag dispatch system dispatches in the following manner: | 如果你想要防止其他的應用對相同的Intent的過濾并潛在的處理你部署的特定的NFC标簽,那麼AAR是有用的。AAR僅在應用程式級被支援,因為包名的限制,并不能在Activity級别來過濾Intent。如果你想要在Activity級處理Intent,請使用Intent過濾器。 如果NFC标簽中包含了AAR,則NFC标簽排程系統會按照下列方式來排程: |
| 1. 通常,嘗試使用Intent過濾器來啟動一個Activity。如果跟該Intent比對的Activity也跟AAR比對,那麼就啟動該Activity。 2. 如果跟Intent隊形的Activity跟AAR不比對,或者是有多個Activity能夠處理該Intent,或者是沒有能夠處理該Intent的Activity存在,那麼就啟動由AAR指定的應用程式。 3. 如果沒有跟該AAR對應的應用程式,那麼就會啟動Google Play來小組基于該AAR的應用程式。 |
Note: You can override AARs and the intent dispatch system with the foreground dispatch system, which allows a foreground activity to have priority when an NFC tag is discovered. With this method, the activity must be in the foreground to override AARs and the intent dispatch system. | 注意:你能夠用前台排程系統來重寫AAR和Intent排程系統,在NFC标簽被發現時。它允許優先使用前台的Activity。用這種方法,Activity必須是在前台來重寫AAR和Intent排程系統。 |
If you still want to filter for scanned tags that do not contain an AAR, you can declare intent filters as normal. This is useful if your application is interested in other tags that do not contain an AAR. For example, maybe you want to guarantee that your application handles proprietary tags that you deploy as well as general tags deployed by third parties. Keep in mind that AARs are specific to Android 4.0 devices or later, so when deploying tags, you most likely want to use a combination of AARs and MIME types/URIs to support the widest range of devices. In addition, when you deploy NFC tags, think about how you want to write your NFC tags to enable support for the most devices (Android-powered and other devices). You can do this by defining a relatively unique MIME type or URI to make it easier for applications to distinguish. | 如果你依然想要過濾掃描到的沒有包含AAR的NFC标簽,通常,你能夠聲明Intent過濾器。如果你的應用程式對不包含AAR的其他NFC标簽感興趣,這種做法是有用的。例如,你可能想要保證你的應用程式處理你部署的專用NFC标簽,以及由第三方部署的普通的NFC标簽。要記住AAR是在Android4.0以後才指定的,是以部署NFC标簽時,你很可能希望使用能夠廣泛支援AAR和MIME類型/URI的是裝置。另外,在你部署NFC标簽時,還要想如何編寫你的NFC标簽,以便讓大多數裝置(Android裝置和其他裝置)支援。同過定義相對唯一的MIME類型或URI,讓應用程式更容易的區分,就可以做到這一點。 |
Android provides a simple API to create an AAR,createApplicationRecord(). All you need to do is embed the AAR anywhere in your NdefMessage. You do not want to use the first record of yourNdefMessage, unless the AAR is the only record in the NdefMessage. This is because the Android system checks the first record of an NdefMessage to determine the MIME type or URI of the tag, which is used to create an intent for applications to filter. The following code shows you how to create an AAR: | Android提供了簡單的建立AAR的API:createApplicationRecord()。你需要做的所有工作就是把AAR嵌入到你的NdefMessage中。除非AAR是NdefMessage中的唯一記錄,否則不要把使用NdefMessage的第一條記錄。這是因為,Android系統會檢查NdefMessage的第一條記錄來判斷NFC标簽的MIME類型或URI,這些資訊被用于建立對應應用程式的Intent對象。以下代碼示範了如何建立一個AAR: |
NdefMessage msg = new NdefMessage(
new NdefRecord[] {
...,
NdefRecord.createApplicationRecord("com.example.android.beam")}
1.6 把NDEF消息發射到其他裝置上
Android Beam allows simple peer-to-peer data exchange between two Android-powered devices. The application that wants to beam data to another device must be in the foreground and the device receiving the data must not be locked. When the beaming device comes in close enough contact with a receiving device, the beaming device displays the "Touch to Beam" UI. The user can then choose whether or not to beam the message to the receiving device. | Android Beam允許在兩個Android裝置之間進行簡單的對等資料交換,想要把資料發送給另一個裝置的應用程式必須是在前台,并且接收資料的裝置必須不被鎖定。當發射裝置跟接收裝置的距離足夠近的時候,發射裝置會顯示“Touch to Beam(觸摸發射)”的UI。然後,使用者能夠選擇是否把消息發射給接收裝置。 |
Note: Foreground NDEF pushing was available at API level 10, which provides similar functionality to Android Beam. These APIs have since been deprecated, but are available to support older devices. SeeenableForegroundNdefPush() for more information. | 注意:在API Level 10中可以利用前台的NDEF推送,它提供了與Android Beam類似的功能。這些API已經過時了,但是在一些老舊裝置上還有效。更多的資訊請看enableForegroundNdefPush()。 |
You can enable Android Beam for your application by calling one of the two methods:
| 通過調用下列兩個方法中的任意一個,就能夠為你的應用程式啟用Android Beam: 1. setNdefPushMessage():這個方法把接收到的NdefMessage對象作為一個消息設定給Beam。當兩個裝置足夠近的時候,就會自動的發送消息。 2. setNdefPushMessageCallback():接收包含createNdefMessage()方法的回調,當裝置在發射資料的範圍内時,這個回調方法會被調用。回調會讓你隻在需要的時候建立NDEF消息。 |
An activity can only push one NDEF message at a time, so setNdefPushMessageCallback() takes precedence over setNdefPushMessage() if both are set. To use Android Beam, the following general guidelines must be met:
| 一個Activity一次隻能推送一條NDEF消息,是以如果同時使用了這兩種方法,那麼setNdefPushMessageCallback()方法的優先級要高于setNdefPushMessage()方法。要使用Android Beam,通常必須滿足以下條件: 1. 發射資料的Activity必須是在前台。兩個裝置的螢幕都必須沒有被鎖定; 2. 必須發要發射的資料封裝到一個NdefMessage對象中; 3. 接收發射資料的NFC裝置必須支援com.android.npp NDEF推送協定或是NFC組織的SNEP協定(簡單的NDEF交換協定)。在API Level9(Android2.3)到API Level 13(Android3.2)的裝置上需要com.android.npp協定。在API Level 14(Android4.0)和以後的裝置上,com.android.npp和SNEP都需要。 |
Note: If your activity enables Android Beam and is in the foreground, the standard intent dispatch system is disabled. However, if your activity also enables foreground dispatching, then it can still scan tags that match the intent filters set in the foreground dispatching. | 注意:如果在前台的Activity啟用了Android Beam,那麼标準的Intent排程系統就會被禁用。但是,如果該Activity還啟用了前台排程,那麼在前台排程系統中,它依然能夠掃描到跟Intent過濾器比對的NFC标簽。 |
To enable Android Beam:
| 啟用Android Beam: 1. 建立一個準備推送到另一個裝置上的包含NdefRecord的NdefMessage對象。 2. 調用帶有NdefMessage類型參數的setNdefPushMessage()方法,或者是在Activity的onCreate()方法中調用setNdefPushMessageCallback方法來傳遞實作NfcAdapter.CreateNdefMessageCallback接口的對象。這兩個方法都至少需要一個準備要啟用Android Beam的Activity,以及一個可選的其他的活躍的Activity清單。 通常,如果你的Activity在任何時候都值推送相同的NDEF消息,那麼當兩個裝置在通信範圍内的時候,使用setNdefPushMessage()就可以了。當你的應用程式要關注應用程式的目前内容,并想要根據使用者在你的應用程式中的行為來推送NDEF消息時,就要使用setNdefPushMessageCallback方法。 |
The following sample shows how a simple activity calls NfcAdapter.CreateNdefMessageCallback in theonCreate() method of an activity (see AndroidBeamDemo for the complete sample). This example also has methods to help you create a MIME record: | 下列示例代碼示範了如何在activity的onCreate()方法中調用NfcAdapter.CreateNdefMessageCallback方法(完整的示例請看AndroidBeamDemo)。這個示例中還有幫助建立MIME記錄的方法: |
package com.example.android.beam;
import android.app.Activity;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
import android.nfc.NfcEvent;
import android.os.Bundle;
import android.os.Parcelable;
import android.widget.TextView;
import android.widget.Toast;
import java.nio.charset.Charset;
publicclassBeamextendsActivityimplementsCreateNdefMessageCallback{
NfcAdapter mNfcAdapter;
TextView textView;
@Override
publicvoid onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView textView =(TextView) findViewById(R.id.textView);
// Check for available NFC Adapter
mNfcAdapter =NfcAdapter.getDefaultAdapter(this);
if(mNfcAdapter ==null){
Toast.makeText(this,"NFC is not available",Toast.LENGTH_LONG).show();
finish();
return;
}
// Register callback
mNfcAdapter.setNdefPushMessageCallback(this,this);
}
@Override
publicNdefMessage createNdefMessage(NfcEventevent){
String text =("Beam me up, Android!\n\n"+
"Beam Time: "+System.currentTimeMillis());
NdefMessage msg =newNdefMessage(
newNdefRecord[]{ createMime(
"application/vnd.com.example.android.beam", text.getBytes())
/**
* The Android Application Record (AAR) is commented out. When a device
* receives a push with an AAR in it, the application specified in the AAR
* is guaranteed to run. The AAR overrides the tag dispatch system.
* You can add it back in to guarantee that this
* activity starts when receiving a beamed message. For now, this code
* uses the tag dispatch system.
*/
//,NdefRecord.createApplicationRecord("com.example.android.beam")
});
return msg;
}
@Override
publicvoid onResume(){
super.onResume();
// Check to see that the Activity started due to an Android Beam
if(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())){
processIntent(getIntent());
}
}
@Override
publicvoid onNewIntent(Intent intent){
// onResume gets called after this to handle the intent
setIntent(intent);
}
/**
* Parses the NDEF Message from the intent and prints to the TextView
*/
void processIntent(Intent intent){
textView =(TextView) findViewById(R.id.textView);
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
// only one message sent during the beam
NdefMessage msg =(NdefMessage) rawMsgs[0];
// record 0 contains the MIME type, record 1 is the AAR, if present
textView.setText(newString(msg.getRecords()[0].getPayload()));
}
}
Note that this code comments out an AAR, which you can remove. If you enable the AAR, the application specified in the AAR always receives the Android Beam message. If the application is not present, Google Play is started to download the application. Therefore, the following intent filter is not technically necessary for Android 4.0 devices or later if the AAR is used: | 注意:上例代碼把AAR給注釋掉了,你可以删除它。如果你啟用了AAR,那麼該應用程式就會始終接收在AAR中指定的Android Beam消息。如果該應用程式不存在,Google Play就會啟動下載下傳程式。是以,如果使用AAR,對于Android4.0以後的裝置,下列的Intent過濾器,在技術上不是必須的: |
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/vnd.com.example.android.beam"/>
</intent-filter>
With this intent filter, the com.example.android.beam application now can be started when it scans an NFC tag or receives an Android Beam with an AAR of type com.example.android.beam, or when an NDEF formatted message contains a MIME record of type application/vnd.com.example.android.beam. | 有了這個Intent過濾器,com.example.android.beam應用就能夠在以下情況下被啟動: 1. 掃描到NFC标簽; 2. 接收到com.example.android.beam類型的AAR或NDEF消息中包含一條application/vnd.com.example.android.beam類型的MIME記錄的Android beam的時候。 |
Even though AARs guarantee an application is started or downloaded, intent filters are recommended, because they let you start an Activity of your choice in your application instead of always starting the main Activity within the package specified by an AAR. AARs do not have Activity level granularity. Also, because some Android-powered devices do not support AARs, you should also embed identifying information in the first NDEF record of your NDEF messages and filter for that as well, just in case. SeeCreating Common Types of NDEF records for more information on how to create records. | 即使通過AAR能夠保證了一個應用程式被啟動或下載下傳,但是還是推薦使用Intent過濾器,因為它會讓你選擇啟動應用程式中Activity,而不是總啟動AAR中指定的應用程式包的主Activity。AAR沒有Activity級别的粒度。而且還有一些android裝置不支援AAR,你還應該在NDEF消息的第一條NDEF記錄中嵌入辨別資訊,以及對應的過濾器。 |
2 Advanced NFC
This document describes advanced NFC topics, such as working with various tag technologies, writing to NFC tags, and foreground dispatching, which allows an application in the foreground to handle intents even when other applications filter for the same ones. | 本文介紹一些進階的NFC專題,如多樣的NFC标簽技術、編寫NFC标簽、以及前台排程,前台排程允許在前台的應用程式優先排程Intent事件,即使還有其他的過濾同樣的Intent事件的應用程式存在。 |
2.1 Android所支援的NFC标簽技術
When working with NFC tags and Android-powered devices, the main format you use to read and write data on tags is NDEF. When a device scans a tag with NDEF data, Android provides support in parsing the message and delivering it in an NdefMessage when possible. There are cases, however, when you scan a tag that does not contain NDEF data or when the NDEF data could not be mapped to a MIME type or URI. In these cases, you need to open communication directly with the tag and read and write to it with your own protocol (in raw bytes). Android provides generic support for these use cases with theandroid.nfc.tech package, which is described in Table 1. You can use thegetTechList() method to determine the technologies supported by the tag and create the corresponding TagTechnologyobject with one of classes provided by android.nfc.tech | 在使用NFC标簽和Android裝置來進行工作的時候,使用的讀寫NFC标簽上資料的主要格式是NDEF。當裝置掃描到帶有NDEF的資料時,Android會提供對消息解析的支援,并在可能的時候,會以NdefMessage對象的形式來發送它。但是,有些情況下,裝置掃描到的NFC标簽沒有包含NDEF資料,或者該NDEF資料沒有被映射到MIME類型或URI。在這些情況下,你需要打開跟NFC标簽的通信,并用自己的協定(原始的位元組形式)來讀寫它。Android用android.nfc.tech包提供了對這些情況的一般性支援,這個包在下表1中介紹。你能夠使用getTechList()方法來判斷NFC标簽所支援的的技術,并且用android.nfc.tech提供的一個類來建立對應的TagTechnology對象。 |
Table 1. Supported tag technologies (表1.NFC标簽所支援的技術)
類 | 介紹 |
TagTechnology | 所有的NFC标簽技術類必須實作的接口。 |
NfcA | 提供對NFC-A(ISO 14443-3A)屬性和I/O操作的通路。 |
NfcB | 提供對NFC-B(ISO 14443-3B)屬性和I/O操作的通路。 |
NfcF | 提供對NFC-F(ISO 6319-4)屬性和I/O操作的通路。 |
NfcV | 提供對NFC-V(ISO 15693)屬性和I/O操作的通路。 |
IsoDep | 提供對NFC-A(ISO 14443-4)屬性和I/O操作的通路。 |
Ndef | 提供對NDEF格式的NFC标簽上的NDEF資料和操作的通路。 |
NdefFormatable | 提供了對可以被NDEF格式化的NFC标簽的格式化操作。 |
The following tag technlogies are not required to be supported by Android-powered devices.
Table 2. Optional supported tag technologies (表2.可選的NFC标簽所支援的技術)
類 | 介紹 |
MifareClassic | 如果Android裝置支援MIFARE,那麼它提供了對經典的MIFARE類型标簽屬性和I/O操作的通路。 |
MifareUltralight | 如果Android裝置支援MIFARE,那麼它提供了對超薄的MIFARE類型标簽屬性和I/O操作的通路。 |
2.1.1 NFC标簽和ACTION_TECH_DISCOVERED類型的Intent協同工作
When a device scans a tag that has NDEF data on it, but could not be mapped to a MIME or URI, the tag dispatch system tries to start an activity with the ACTION_TECH_DISCOVEREDintent. TheACTION_TECH_DISCOVERED is also used when a tag with non-NDEF data is scanned. Having this fallback allows you to work with the data on the tag directly if the tag dispatch system could not parse it for you. The basic steps when working with tag technologies are as follows: | 當裝置掃描到帶有NDEF資料的NFC标簽,但卻不能映射到MIME或URI時,NFC标簽排程系統就嘗試使用ACTION_TECH_DISCOVERED類型的Intent來啟動一個Activity。在被掃描到的NFC标簽上沒有NDEF資料時,也會使用ACTION_TECH_DISCOVERED類型的Intent。有了這種回退機制,如果排程系統不能夠幫你解析資料,那麼你就可以直接使用NFC标簽上資料來工作。基本步驟如下: |
| 1. 給你希望處理的NFC标簽指定ACTION_TECH_DISCOVERED類型的Intent過濾器。更多資訊請看“NFC的Intent過濾”。通常,在NDEF消息不能被映射到MIME類型或URI時,或者被掃描到的NFC标簽不包含NDEF資料時,NFC标簽排程系統會嘗試啟動一個ACTION_TECH_DISCOVERED類型的Intent。更多資訊,請看“NFC标簽排程系統”。 2. 應用程式接收到Intent對象時,從該Intent對象中擷取Tag對象: Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); 3. 通過調用android.nfc.tech包中對應類的一個get工廠方法,來擷取一個TagTechnology對象執行個體。在調用get工廠方法之前,通過調用getTechList()方法來枚舉NFC标簽所支援的技術。例如,用下列方法從Tag對象中擷取MifareUltralight對象執行個體: MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)); |
2.1.2 讀寫NFC标簽
Reading and writing to an NFC tag involves obtaining the tag from the intent and opening communication with the tag. You must define your own protocol stack to read and write data to the tag. Keep in mind, however, that you can still read and write NDEF data when working directly with a tag. It is up to you how you want to structure things. The following example shows how to work with a MIFARE Ultralight tag. | 讀寫NFC标簽,要涉及到從Intent對象中擷取标簽,并要打開與标簽的通信。要讀寫NFC标簽資料,你必須要定義自己的協定棧。但是,要記住在直接使用NFC标簽工作時,你依然能夠讀寫NDEF資料。這是你想要如何建構的事情。下例示範了如何使用MIFARE超薄标簽來工作: |
+ View Code
2.2 使用前台排程系統
The foreground dispatch system allows an activity to intercept an intent and claim priority over other activities that handle the same intent. Using this system involves constructing a few data structures for the Android system to be able to send the appropriate intents to your application. To enable the foreground dispatch system: | 前台排程系統允許一個Activity攔截Intent對象,并且聲明該Activity的優先級要比其他的處理相同Intent對象的Activity高。使用這個系統涉及到為Android系統建構一些資料結構,以便能夠把相應的Intent對象發送給你的應用程式,以下是啟用前台排程系統的步驟: |
1 Add the following code in the onCreate() method of your activity:
PendingIntent pendingIntent =PendingIntent.getActivity( this,0,newIntent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0);
IntentFilter ndef =newIntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); try{ ndef.addDataType("* } catch(MalformedMimeTypeException e){ thrownewRuntimeException("fail", e); } intentFiltersArray =newIntentFilter[]{ndef,};
| 1. 在你的Activity的onCreate()方法中添加下列代碼: A. 建立一個PendingIntent對象,以便Android系統能夠在掃描到NFC标簽時,用它來封裝NFC标簽的詳細資訊。 PendingIntent pendingIntent =PendingIntent.getActivity( this,0,newIntent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0); B. 聲明你想要截獲處理的Intent對象的Intent過濾器。前台排程系統會在裝置掃描到NFC标簽時,用聲明的Intent過濾器來檢查接收到的Intent對象。如果比對就會讓你的應用程式來處理這個Intent對象,如果不比對,前台排程系統會回退到Intent排程系統。如果Intent過濾器和技術過濾器的數組指定了null,那麼就說明你要過濾所有的退回到TAG_DISCOVERED類型的Intent對象的标簽。以下代碼會用于處理所有的NDEF_DISCOVERED的MIME類型。隻有在需要的時候才做這種處理: IntentFilter ndef =newIntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); try{ ndef.addDataType("* } catch(MalformedMimeTypeException e){ thrownewRuntimeException("fail", e); } intentFiltersArray =newIntentFilter[]{ndef,}; C. 建立一個應用程式希望處理的NFC标簽技術的數組。調用Object.class.getName()方法來擷取你想要支援的技術的類: techListsArray = new String[][] { new String[] { NfcF.class.getName() } }; |
2 Override the following activity lifecycle callbacks and add logic to enable and disable the foreground dispatch when the activity loses (onPause()) and regains (onResume()) focus.enableForegroundDispatch() must be called from the main thread and only when the activity is in the foreground (calling in onResume() guarantees this). You also need to implement the onNewIntentcallback to process the data from the scanned NFC tag. publicvoid onPause(){ super.onPause(); mAdapter.disableForegroundDispatch(this); } publicvoid onResume(){ super.onResume(); mAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray); } publicvoid onNewIntent(Intent intent){ Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); //do something with tagFromIntent } | 2. 重寫下列Activity生命周期的回調方法,并且添加邏輯在Activity挂起(onPause())和獲得焦點(onResume())時,來啟用和禁用前台排程。enableForegroundDispatch()方法必須在主線程中被調用,并且隻有在該Activity在前台的時候(要保證在onResume()方法中調用這個方法)。你還需要實作onNewIntent回調方法來處理掃描到的NFC标簽的資料: publicvoid onPause(){ super.onPause(); mAdapter.disableForegroundDispatch(this); } publicvoid onResume(){ super.onResume(); mAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray); } publicvoid onNewIntent(Intent intent){ Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); //do something with tagFromIntent } |
See the ForegroundDispatch sample from API Demos for the complete sample | 完整的示例請看API Demo中的ForegroundDispatch |
作者:skyseraph
出處:http://www.cnblogs.com/skyseraph/
Email/GTalk: [email protected]
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。
分類: 【16】Android, 【54】NFC 綠色通道: 好文要頂 關注我 收藏該文 與我聯系
SkySeraph
關注 - 8
粉絲 - 472 +加關注 3 0 (請您對文章做出評價) « 上一篇: 【分享】RSS訂閱技巧及工具和實用RSS連結分享
» 下一篇: 【分享】一款手機真機螢幕同步抓取軟體
posted @ 2013-01-27 19:54 SkySeraph 閱讀( 6270) 評論( 5) 編輯 收藏
評論清單 #1樓 2013-01-27 21:41 KejianLi 翻譯得很好,非常喜歡這樣的形式! 支援(0) 反對(0) #2樓 2013-01-28 09:26 john23.net 感謝分享 支援(0) 反對(0) #3樓 2013-03-18 10:46 zx132797 請問樓主如何實作加密呀? 支援(0) 反對(0) #4樓 [ 樓主] 2013-03-18 14:00 SkySeraph @zx132797
這個加密是指?傳輸内容加密? NFC晶片/協定加密? 還是? 支援(0) 反對(0) #5樓 2013-04-26 23:09 zx132797 不好意思才看到樓主回複,樓主回複神速呀!NFC晶片/協定加密? 忘樓主回複 支援(0) 反對(0) 重新整理評論 重新整理頁面 傳回頂部 注冊使用者登入後才能發表評論,請 登入 或 注冊, 通路網站首頁。 【推薦】50萬行VC++源碼: 大型組态工控、電力仿真CAD與GIS源碼庫
融雲,免費為你的App加入IM功能——讓你的App“聊”起來!!
【活動】刮上代金券,使用再送100元大禮包!
最新IT新聞:
· Docker Hub中超過30%的官方鏡像包含高危漏洞
· A輪估值10億美元的WiFi萬能鑰匙竟然啟動了股權衆籌
· 騰訊滴滴聯合推線下掃碼付車費
· 阿裡影業董事長任光線董事,阿裡、光線進入“蜜月期”?
· 沒有十全十美的技術!攜程事件之後,技術專家們的建議與反思
» 更多新聞... 最新知識庫文章:
· 微服務實戰(一):微服務架構的優勢與不足
· 編寫高品質的代碼——從命名入手
· 領域驅動設計系列(3)有選擇性的使用領域驅動設計
· 專訪Facebook HipHop作者/阿裡研究員趙海平:生物與計算機交織的獨特人生
· 內建架構:對比 Web API 與面向服務的架構和企業應用程式內建
» 更多知識庫文章...
公告
領域:移動開發/智能家居/無線互聯/圖像識别/機器視覺
信念:務實求真
聯系方式(交流合作)
[email protected]
Link: CSDN/Github
檢視詳情
昵稱: SkySeraph
園齡: 4年11個月
粉絲: 472
關注: 8 +加關注
| ||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|---|---|---|---|---|---|
30 | 31 | 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
搜尋
常用連結
- 我的随筆
- 我的評論
- 我的參與
- 最新評論
- 我的标簽
- 更多連結
最新随筆
- 1. 【Android】Eclipse自動編譯NDK/JNI的三種方法
- 2. 【讀書筆記】精益創業實戰
- 3. 【讀書筆記】高效能人士的七個習慣
- 4. 《Android NFC 開發實戰詳解 》簡介+源碼+樣章+勘誤ING
- 5. 【讀書筆記】人人都是産品經理
- 6. 【My Life】寫在年末, 我的2013
- 7. 【Android】ListView中EditText焦點問題
- 8. 【Android】Android 4.2源碼下載下傳(ubuntu 12.10)
- 9. 【分享】一款手機真機螢幕同步抓取軟體
- 10. 【NFC】Android NFC API Reference中英文
随筆分類(220)
- 【00】[Menu](3)
- 【10】[編程語言篇]
- 【11】C/CPP(9)
- 【12】java/c#
- 【13】Objective C
- 【15】[作業系統篇]
- 【16】Android(26)
- 【17】Linux(1)
- 【18】iOS(1)
- 【19】WinPhone
- 【20】[開發工具篇]
- 【21】VS/VC/MFC(22)
- 【22】Eclipse
- 【25】[電子硬體篇]
- 【26】ARM/DSP(8)
- 【27】FPGA/SOPC(3)
- 【28】電子電路/PCB(3)
- 【29】硬體相關(3)
- 【30】[計算機視覺篇]
- 【31】DIP(12)
- 【32】Color ImgSeg(14)
- 【33】OpenCV(11)
- 【34】ML/PR(4)
- 【35】OpenGL
- 【39】Math(1)
- 【40】[流媒體篇](7)
- 【41】SMS
- 【50】[無線篇]
- 【54】NFC(2)
- 【55】[人機互動篇]
- 【56】Kinect & OpenNI
- 【60】[產品篇]
- 【61】TV(1)
- 【62】Phone
- 【70】[Others]
- 【71】面試筆試(6)
- 【73】連結收藏(17)
- 【74】學術科研(8)
- 【75】English Study(13)
- 【76】My Translate
- 【78】7788(11)
- 【80】[CTO]
- 【81】系統架構
- 【82】軟體架構
- 【84】項目管理
- 【85】讀書筆記(3)
- 【86】我的分享(5)
- 【90】[SkySeraph]
- 【91】My Sft(3)
- 【92】My Project(9)
- 【93】我的開源
- 【95】軟體出售(3)
- 【96】My Books(1)
- 【99】Burning Life(10)
随筆檔案(192)
- 2014年9月 (1)
- 2014年8月 (1)
- 2014年4月 (1)
- 2014年3月 (2)
- 2013年12月 (1)
- 2013年4月 (1)
- 2013年2月 (2)
- 2013年1月 (2)
- 2012年12月 (1)
- 2012年6月 (1)
- 2012年5月 (1)
- 2012年4月 (4)
- 2012年3月 (14)
- 2012年2月 (4)
- 2011年12月 (1)
- 2011年11月 (1)
- 2011年10月 (1)
- 2011年9月 (1)
- 2011年8月 (7)
- 2011年7月 (9)
- 2011年6月 (6)
- 2011年5月 (15)
- 2011年4月 (7)
- 2011年3月 (16)
- 2011年2月 (3)
- 2011年1月 (7)
- 2010年12月 (13)
- 2010年11月 (26)
- 2010年10月 (36)
- 2010年9月 (7)
相冊(2)
- SkySeraph(2)
Personal
- Google Profile
- SkySeraph-CSDN
- SkySeraph-GitHub
部落格收藏
積分與排名
- 積分 - 170282
- 排名 - 815
最新評論
- 1. Re:【Android】Eclipse自動編譯NDK/JNI的三種方法
- 謝樓主,還是cygwin 最簡單,另外,使用多種方法會重複編譯。另外cygwin的參數好像不對,看的不大清楚,我的是 --login -c "cd /cygdrive/e/android-ndk-r1......
- --Emilio66
- 2. Re:【圖像算法】圖像特征:GLCM
-
樓主,你好!最近在看GLCM方面的資料,看到了你的這篇部落格,可以把完整的code發我一份學習嗎?
[email protected]
非常感謝!
- --hellowhut
- 3. Re:【圖像算法】彩色圖像分割專題八:基于MeanShift的彩色分割
- 樓主你好,最後一張包含邊緣的圖像是利用查找輪廓的API函數對經過Mean shift算法分割後的圖像進行提取的邊緣然後和原圖像合成嗎?還是直接對原圖進行查找輪廓?
- --冥夜殘月
- 4. Re:【圖像算法】彩色圖像分割專題八:基于MeanShift的彩色分割
- @冥夜殘月運作算法後被修改後的原圖...附注:OpenCV有很多API函數在使用時都會對原圖進行修改,例如查找輪廓相關的API函數...
- --SkySeraph
- 5. Re:【圖像算法】彩色圖像分割專題八:基于MeanShift的彩色分割
- 樓主你好,請問你最後一張包含邊緣的圖像是怎麼生成的?
- --冥夜殘月
閱讀排行榜
- 1. 【筆試面試】75道邏輯推理題及答案(52393)
- 2. 【流媒體】Android 實時視訊采集—Camera預覽采集(30283)
- 3. 【流媒體】H264—MP4格式及在MP4檔案中提取H264的SPS、PPS及碼流(24122)
- 4. 【流媒體】 Android 實時視訊編碼—H.264寫死(23045)
- 5. 【流媒體】Android 實時視訊采集—MediaRecoder錄制(20483)
- 6. 【Android】Android 4.2源碼下載下傳(ubuntu 12.10)(18166)
- 7. 【流媒體】live555—VS2010/VS2013 下live555編譯、使用及測試(16367)
- 8. 【圖像算法】七種常見門檻值分割代碼(Otsu、最大熵、疊代法、自适應閥值、手動、疊代法、基本全局門檻值法)(15776)
- 9. 【流媒體】Android 實時視訊采集/編碼/傳輸/解碼/播放—方案調研(初)(15251)
- 10. 【Android學習專題】多媒體篇:MediaRecorder 實作錄音機(11533)
評論排行榜
- 1. 【圖像算法】圖像特征:三個圖像顯著性區域特征提取方法(61)
- 2. 【思考】一個博士的幾句心聲或牢騷(30)
- 3. 【流媒體】live555—VS2010/VS2013 下live555編譯、使用及測試(22)
- 4. 【圖像算法】圖像特征:GLCM(19)
- 5. 【My Sft】彩色圖像分析軟體V1.0.1.0(16)
推薦排行榜
- 1. 【流媒體】live555—VS2010/VS2013 下live555編譯、使用及測試(10)
- 2. 【流媒體】H264—MP4格式及在MP4檔案中提取H264的SPS、PPS及碼流(10)
- 3. 【My Life】寫在年末, 我的2013(9)
- 4. 【流媒體】Android 實時視訊采集—Camera預覽采集(8)
- 5. 【圖像算法】圖像特征:三個圖像顯著性區域特征提取方法(8)
- 6. 【Android學習專題】控件元件篇:Dialog彙總(7)
- 7. 【圖像算法】七種常見門檻值分割代碼(Otsu、最大熵、疊代法、自适應閥值、手動、疊代法、基本全局門檻值法)(7)
- 8. 【流媒體】 Android 實時視訊編碼—H.264寫死(6)
- 9. Husband的忏悔信(IT攻城獅)(6)
- 10. 【思考】一個博士的幾句心聲或牢騷(6)
Copyright ©2015 SkySeraph
SkySeraph
- 部落格園
- 首頁
- 新随筆
- 聯系
- 訂閱
- 管理
随筆- 192 文章- 0 評論- 441
【NFC】Android NFC API Reference中英文
【NFC】Android NFC API Reference中英文
SkySeraph Jan 25th 2013
Email:[email protected]
0 Near Field Communication
Near Field Communication (NFC) is a set of short-range wireless technologies, typically requiring a distance of 4cm or less to initiate a connection. NFC allows you to share small payloads of data between an NFC tag and an Android-powered device, or between two Android-powered devices. | 近場通信(NFC)是一個短範圍無線技術集合,通常需要4厘米或更短的距離才能初始化連接配接。NFC允許在NFC标簽和Android裝置之間或兩個Android裝置之間共享小的資料的負載。 |
Tags can range in complexity. Simple tags offer just read and write semantics, sometimes with one-time-programmable areas to make the card read-only. More complex tags offer math operations, and have cryptographic hardware to authenticate access to a sector. The most sophisticated tags contain operating environments, allowing complex interactions with code executing on the tag. The data stored in the tag can also be written in a variety of formats, but many of the Android framework APIs are based around a NFC Forum standard called NDEF (NFC Data Exchange Format). | NFC标簽具有複雜的分類。簡單的NFC标簽隻提供讀寫文法,某些時候一次隻能以隻讀的方式讀取卡片的可程式設計區域。複雜一點的NFC标簽提供了數學運算能力,而且有加密的硬體來認證對一個扇區的通路。最複雜的NFC标簽包含了運算環境,允許在标簽上執行複雜的互動代碼。存儲在标簽中的資料也可以用各種格式來編寫,但是大多數的Android架構API都使用基于NDEF(NFC Data Exchange Format)的标準。 |
1 NFC Basic
This document describes the basic NFC tasks you perform in Android. It explains how to send and receive NFC data in the form of NDEF messages and describes the Android framework APIs that support these features. For more advanced topics, including a discussion of working with non-NDEF data, seeAdvanced NFC. There are two major uses cases when working with NDEF data and Android: Reading NDEF data from an NFC tag Beaming NDEF messages from one device to another with Android Beam™ | 本文介紹在Android系通過你所能執行的基本任務。它解釋了如何用NDEF消息格式來發送和接收NFC資料,并且介紹了支援這些功能的Android架構API。有關更進階的話題,包括對非NDEF格式資料的讨論,情況“進階 NFC” NDEF資料和Android一起工作的場景主要有兩個: 1. 從NFC标簽中讀取NDEF資料; 【讀資料】 2. 把NDEF消息從一個裝置發送給另一個裝置。【資料傳遞】 |
Reading NDEF data from an NFC tag is handled with thetag dispatch system, which analyzes discovered NFC tags, appropriately categorizes the data, and starts an application that is interested in the categorized data. An application that wants to handle the scanned NFC tag can declare an intent filter and request to handle the data. | 從NFC标簽中讀取NDEF資料是用标簽排程系統來處理的,它會分析被發現的NFC标簽,對資料進行适當的分類,并啟動對該類資料感興趣的應用程式。想要處理被掃描到NFC标簽的應用程式會聲明一個Intent過濾器,并請求處理資料。 |
The Android Beam™ feature allows a device to push an NDEF message onto another device by physically tapping the devices together. This interaction provides an easier way to send data than other wireless technologies like Bluetooth, because with NFC, no manual device discovery or pairing is required. The connection is automatically started when two devices come into range. Android Beam is available through a set of NFC APIs, so any application can transmit information between devices. For example, the Contacts, Browser, and YouTube applications use Android Beam to share contacts, web pages, and videos with other devices. | Android Beam™ 功能允許裝置把一個NDEF消息推送到實體/硬體上互相監聽的另一個裝置上。這種互動提供了比其他無線技術(如藍牙)更容易的發送資料的方法。因為NFC不需要手動的裝置發現或配對要求,兩個裝置在接近到一定範圍時會自動的連接配接。Android Beam通過一組NFC API來使用,以便應用程式能夠在裝置之間來傳輸資訊。例如,通信錄、浏覽器以及YouTube等應用程式都使用Android Beam來跟其他裝置共享通信錄、網頁和視訊。 |
1.1 NFC标簽排程系統 (The Tag Dispatch System)
Android-powered devices are usually looking for NFC tags when the screen is unlocked, unless NFC is disabled in the device's Settings menu. When an Android-powered device discovers an NFC tag, the desired behavior is to have the most appropriate activity handle the intent without asking the user what application to use. Because devices scan NFC tags at a very short range, it is likely that making users manually select an activity would force them to move the device away from the tag and break the connection. You should develop your activity to only handle the NFC tags that your activity cares about to prevent the Activity Chooser from appearing. | 通常,除非是在裝置的設定菜單中NFC被禁用,否則Android裝置會在非鎖屏的狀态下搜尋NFC。當Android裝置發現NFC标簽時,期望的行為是用最合适的Activity來處理該Intent,而不是詢問使用者使用什麼應用程式。因為裝置隻能在很短的範圍内掃描到NFC标簽,強制的讓使用者手動的選擇一個Activity,會導緻裝置離開NFC标簽,進而中斷該連接配接。你應該開發你自己的Activity來處理你所關心的NFC标簽,進而阻止 選擇器的操作。 |
To help you with this goal, Android provides a special tag dispatch system that analyzes scanned NFC tags, parses them, and tries to locate applications that are interested in the scanned data. It does this by:
| 為了幫助你達到這個目标,Android提供了特殊的标簽排程系統,來分析掃描到的NFC标簽,通過解析資料,在被掃描到的資料中嘗試找到感興趣的應用程式,具體做法如下: 1. 解析NFC标簽并搞清楚标簽中辨別資料負載的MIME類型或URI; 2. 把MIME類型或URI以及資料負載封裝到一個Intent中。 3. 基于Intent來啟動Activity。 |
1.1.1 怎樣把NFC标簽映射到MIME類型和URI (How NFC tags are mapped to MIME types and URIs)
Before you begin writing your NFC applications, it is important to understand the different types of NFC tags, how the tag dispatch system parses NFC tags, and the special work that the tag dispatch system does when it detects an NDEF message. NFC tags come in a wide array of technologies and can also have data written to them in many different ways. Android has the most support for the NDEF standard, which is defined by the NFC Forum. | 開始編寫NFC應用程式之前,重要的是要了解不同類型的NFC标簽、标簽排程系統是如何解析NFC标簽的、以及在檢測到NDEF消息時,标簽排程系統所做的特定的工作等。NFC标簽涉及到廣泛的技術,并且有很多不同的方法向标簽中寫入資料。Android支援由NFC Forum所定義的NDEF标準。 |
NDEF data is encapsulated inside a message (NdefMessage) that contains one or more records (NdefRecord). Each NDEF record must be well-formed according to the specification of the type of record that you want to create. Android also supports other types of tags that do not contain NDEF data, which you can work with by using the classes in theandroid.nfc.tech package. To learn more about these technologies, see the Advanced NFC topic. Working with these other types of tags involves writing your own protocol stack to communicate with the tags, so we recommend using NDEF when possible for ease of development and maximum support for Android-powered devices. | NDEF資料被封裝在一個消息(NdefMessage)中,該消息中包含了一條或多條記錄(NdefRecord)。每個NDEF記錄必須具有良好的你想要建立的記錄類型的規範的格式。Android也支援其他的不包含NDEF資料類型的标簽,你能夠使用android.nfc.tech包中的類來工作。要使用其他類型标簽來工作,涉及到編寫自己的跟該标簽通信的協定棧,是以我們建議你盡可能的使用NDEF,以便減少開發難度,并且最大化的支援Android裝置。 |
Note:To download complete NDEF specifications, go to the NFC Forum Specification Download site and seeCreating common types of NDEF records for examples of how to construct NDEF records. | 注意:要下載下傳完整的NDEF規範,請去“NFC論壇規範下載下傳”網址來下載下傳。 |
Now that you have some background in NFC tags, the following sections describe in more detail how Android handles NDEF formatted tags. When an Android-powered device scans an NFC tag containing NDEF formatted data, it parses the message and tries to figure out the data's MIME type or identifying URI. To do this, the system reads the first NdefRecord inside the NdefMessage to determine how to interpret the entire NDEF message (an NDEF message can have multiple NDEF records). In a well-formed NDEF message, the first NdefRecordcontains the following fields: | 現在,你已經具備了一些NFC标簽的背景知識,接下來要詳細的介紹Android是如何處理NDEF格式的标簽的。當Android裝置掃描到包含NDEF格式資料的NFC标簽時,它會解析該消息,并嘗試搞清楚資料的MIME類型或URI辨別。首先系統會讀取消息(NdefMessage)中的第一條NdefRecord,來判斷如何解釋整個NDEF消息(一個NDEF消息能夠有多條NDEF記錄)。 在格式良好的NDEF消息中,第一條NdefRecord包含以下字段資訊: |
3-bit TNF (Type Name Format) Indicates how to interpret the variable length type field. Valid values are described in described in Table 1. Variable length type Describes the type of the record. If usingTNF_WELL_KNOWN, use this field to specify the Record Type Definition (RTD). Valid RTD values are described in Table 2. Variable length ID A unique identifier for the record. This field is not used often, but if you need to uniquely identify a tag, you can create an ID for it. Variable length payload The actual data payload that you want to read or write. An NDEF message can contain multiple NDEF records, so don't assume the full payload is in the first NDEF record of the NDEF message. | 3-bit TNF(類型名稱格式) 訓示如何解釋可變長度類型字段,在下表1中介紹有效值。 可變長度類型 說明記錄的類型,如果使用TNF_WELL_KNOWN,那麼則使用這個字段來指定記錄的類型定義(RTD)。在下表2中定義了有效的RTD值。 可變長度ID 唯一辨別該記錄。這個字段不經常使用,但是,如果需要唯一的辨別一個标記,那麼就可以為該字段建立一個ID。 可變長度負載 你想讀/寫的實際的資料負載。一個NDEF消息能夠包含多個NDEF記錄,是以不要以為在NDEF消息的第一條NDEF記錄中包含了所有的負載。 |
The tag dispatch system uses the TNF and type fields to try to map a MIME type or URI to the NDEF message. If successful, it encapsulates that information inside of a ACTION_NDEF_DISCOVERED intent along with the actual payload. However, there are cases when the tag dispatch system cannot determine the type of data based on the first NDEF record. This happens when the NDEF data cannot be mapped to a MIME type or URI, or when the NFC tag does not contain NDEF data to begin with. In such cases, aTag object that has information about the tag's technologies and the payload are encapsulated inside of a ACTION_TECH_DISCOVERED intent instead. | 标簽排程系統使用TNF和類型字段來嘗試把MIME類型或URI映射到NDEF消息中。如果成功,它會把資訊跟實際的負載一起封裝到ACTION_NEDF_DISCOVERED類型的Intent中。但是,會有标簽排程系統不能根據第一條NDEF記錄來判斷資料類型的情況,這樣就會有NDEF資料不能被映射到MIME類型或URI,或者是NFC标簽沒有包含NDEF開始資料的情況發生。在這種情況下,就會用一個标簽技術資訊相關的Tag對象和封裝在ACTION_TECH_DISCOVERED類型Intent對象内部的負載來代替。 |
Table 1. describes how the tag dispatch system maps TNF and type fields to MIME types or URIs. It also describes which TNFs cannot be mapped to a MIME type or URI. In these cases, the tag dispatch system falls back toACTION_TECH_DISCOVERED. | 表1. 介紹标簽排程系統映射如何把TNF和類型字段映射到MIME型或URI上。同時也介紹了那種類型的TNF不能被映射到MIME類型或URI上。這種情況下,标簽排程系統會退化到ACTION_TECH_DISCOVERED類型的Intent對象。 |
For example, if the tag dispatch system encounters a record of type TNF_ABSOLUTE_URI, it maps the variable length type field of that record into a URI. The tag dispatch system encapsulates that URI in the data field of an ACTION_NDEF_DISCOVERED intent along with other information about the tag, such as the payload. On the other hand, if it encounters a record of type TNF_UNKNOWN, it creates an intent that encapsulates the tag's technologies instead. | 例如,如果标簽排程系統遇到一個TNF_ABSOLUTE_URI類型的記錄,它會把這個記錄的可變長度類型字段映射到一個URI中。标簽排程系統會把這個URI跟其他相關的标簽的資訊(如資料負載)一起封裝到ACTION_NDEF_DISCOVERED的Intent對象中。在另一方面,如果遇到了TNF_UNKNOWN類型,它會建立一個封裝了标簽技術資訊的Intent對象來代替。 |
表1. 所支援的TNF和它們的映射
類型名稱格式(TNF) | 映射 |
TNF_ABSOLUTE_URI | 基于類型字段的URI |
TNF_EMPTY | 退化到ACTION_TECH_DISCOVERED類型的Intent對象 |
TNF_EXTERNAL_TYPE | 基于類型字段中URN的URI。URN是縮短的格式(<domain_name>:<service_name)被編碼到NDEF類型中。 Android會把這個URN映射成以下格式的URI:vnd.android.nfc://ext/<domain_name>:<service_name> |
TNF_MIME_MEDIA | 基于類型字段的MIME類型 |
TNF_UNCHANGED | 退化到ACTION_TECH_DISCOVERED類型的Intent對象 |
TNF_UNKNOWN | 退化到ACTION_TECH_DISCOVERED類型的Intent對象 |
TNF_WELL_KNOWN | 依賴你在類型字段中設定的記錄類型定義(RTD)的MIME類型或URI |
表2. TNF_WELL_KNOWN所支援的RTD和它們的映射
記錄類型定義(RTD) | 映射 |
RTD_ALTERNATIVE_CARRIER | 退化到ACTION_TECH_DISCOVERED類型的Intent對象 |
RTD_HANDOVER_CARRIER | 退化到ACTION_TECH_DISCOVERED類型的Intent對象 |
RTD_HANDOVER_REQUEST | 退化到ACTION_TECH_DISCOVERED類型的Intent對象 |
RTD_HANDOVER_SELECT | 退化到ACTION_TECH_DISCOVERED類型的Intent對象 |
RTD_SMART_POSTER | 基于負載解析的URI |
RTD_TEXT | text/plain類型的MIME |
RTD_URI | 基于有效負載的URI |
1.1.2 應用程式如何排程NFC标簽(How NFC Tags are Dispatched to Applications)
When the tag dispatch system is done creating an intent that encapsulates the NFC tag and its identifying information, it sends the intent to an interested application that filters for the intent. If more than one application can handle the intent, the Activity Chooser is presented so the user can select the Activity. The tag dispatch system defines three intents, which are listed in order of highest to lowest priority:
| 當标簽排程系統完成對NFC标簽和它的辨別資訊封裝的Intent對象的建立時,它會把該Intent對象發送給感興趣的應用程式。如果有多個應用程式能夠處理該Intent對象,就會顯示Activity選擇器,讓使用者選擇Activity。标簽排程系統定義了三種Intent對象,以下按照由高到低的優先級列出這三種Intent對象: 1. ACTION_NDEF_DISCOVERED: 這種Intent用于啟動包含NDEF負載和已知類型的标簽的Activity。這是最高優先級的Intent,并且标簽排程系統在任何其他Intent之前,都會盡可能的嘗試使用這種類型的Intent來啟動Activity。 2. ACTION_TECH_DISCOVERED: 如果沒有注冊處理ACTION_NDEF_DISCOVERED類型的Intent的Activity,那麼标簽排程系統會嘗試使用這種類型的Intent來啟動應用程式。如果被掃描到的标簽包含了不能被映射到MIME類型或URI的NDEF資料,或者沒有包含NDEF資料,但是是已知的标簽技術,那麼也會直接啟動這種類型的Intent對象(而不是先啟動ACTION_NDEF_DISCOVERED類型的Intent) 3. ACTION_TAB_DISCOVERED: 如果沒有處理ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED類型Intent的Activity,就會啟動這種類型的Intent。 |
The basic way the tag dispatch system works is as follows:
| 标簽排程系統的基本工作方法如下: 1. 用解析NFC标簽時由标簽排程系統建立的Intent對象(ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED)來嘗試啟動Activity; 2. 如果沒有對應的處理Intent的Activity,那麼就會嘗試使用下一個優先級的Intent(ACTION_TECH_DISCOVERED或ACTION_TAG_DISCOVERED)來啟動Activity,直到有對應的應用程式來處理這個Intent,或者是直到标簽排程系統嘗試了所有可能的Intent。 3. 如果沒有應用程式來處理任何類型的Intent,那麼就不做任何事情。 |
Whenever possible, work with NDEF messages and the ACTION_NDEF_DISCOVERED intent, because it is the most specific out of the three. This intent allows you to start your application at a more appropriate time than the other two intents, giving the user a better experience. | 在可能的情況下,都會使用NDEF消息和ACTION_NDEF_DISCOVERED類型的Intent來工作,因為它是這三種Intent中最标準的。這種Intent與其他兩種Intent相比,它會允許你在更加合适的時機來啟動你的應用程式,進而給使用者帶來更好的體驗。 |
圖1. 标簽排程系統 Tag Dispatch System
1.2 在Android的Manifest中申請NFC通路
Before you can access a device's NFC hardware and properly handle NFC intents, declare these items in your AndroidManifest.xml file: | 在通路裝置的NFC硬體和正确的處理NFC的Intent之前,要在AndroidManifest.xml檔案中進行以下聲明: |
1 The NFC <uses-permission> element to access the NFC hardware: <uses-permission android:name="android.permission.NFC" /> 2 The minimum SDK version that your application can support. API level 9 only supports limited tag dispatch via ACTION_TAG_DISCOVERED, and only gives access to NDEF messages via theEXTRA_NDEF_MESSAGES extra. No other tag properties or I/O operations are accessible. API level 10 includes comprehensive reader/writer support as well as foreground NDEF pushing, and API level 14 provides an easier way to push NDEF messages to other devices with Android Beam and extra convenience methods to create NDEF records. <uses-sdk android:minSdkVersion="10"/> 3 The uses-feature element so that your application shows up in Google Play only for devices that have NFC hardware: <uses-feature android:name="android.hardware.nfc" android:required="true" /> | 1. 在<uses-permission>元素中聲明通路NFC硬體: <uses-permission android:name="android.permission.NFC" /> 2. 你的應用程式所支援的最小的SDK版本。API Level 9隻通過ACTION_TAG_DISCOVERED來支援有限的标簽排程,并且隻能通過EXTRA_NDEF_MESSAGES來通路NDEF消息。沒有其他的标簽屬性或I/O操作可用。API Level 10中包含了廣泛的讀寫支援,進而更好的推動了NDEF的應用前景,并且API Leve 14用Android Beam和額外的友善的建立NDEF記錄的方法,向外提供了更容易的把NDEF消息推送給其他裝置的方法。 <uses-sdkandroid:minSdkVersion="10"/> 3. 使用uses-feature元素,在Google Play中,以便你的應用程式能夠隻針對有NFC硬體的裝置來顯示。 <uses-featureandroid:name="android.hardware.nfc"android:required="true"/> |
If your application uses NFC functionality, but that functionality is not crucial to your application, you can omit the uses-feature element and check for NFC avalailbility at runtime by checking to see ifgetDefaultAdapter()is null. | 如果你的應用程式使用了NFC功能,但是相關的功能又不是你的應用程式的關鍵功能,你可以忽略uses-feature元素,并且要在運作時通過調用getDefaultAdapter()方法來檢查NFC是否有效。 |
1.3 過濾NFC的Intent (Filtering for NFC Intents)
To start your application when an NFC tag that you want to handle is scanned, your application can filter for one, two, or all three of the NFC intents in the Android manifest.
| 要在你想要處理被掃描到的NFC标簽時啟動你的應用程式,可以在你的應用程式的Android清單中針對一種、兩種或全部三種類型的NFC的Intent來過濾。
|
Because NFC tag deployments vary and are many times not under your control, this is not always possible, which is why you can fallback to the other two intents when necessary. When you have control over the types of tags and data written, it is recommended that you use NDEF to format your tags. The following sections describe how to filter for each type of intent. | 因為NFC标簽的多樣性,并且很多時候不在你的控制之下,是以在必要的時候你要回退到其他兩種類型的Intent。在你能夠控制标簽的類型和寫入的資料時,我們建議你使用NDEF格式。下文将介紹如何過濾每種類型的Intent對象。 |
1.3.1 ACTION_NDEF_DISCOVERED
To filter for ACTION_NDEF_DISCOVERED intents, declare the intent filter along with the type of data that you want to filter for. The following example filters for ACTION_NDEF_DISCOVERED intents with a MIME type of text/plain: <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain" /> </intent-filter> The following example filters for a URI in the form ofhttp://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_NDEF_DISCOVERED類型的Intent,就要在清單中跟你想要過濾的資料一起來聲明該類型的Intent過濾器。 以下是過濾text/plain類型的MIME的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> 以下示例使用http://developer.android.com/index.html格式的URI來過濾: <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> |
1.3.2 ACTION_TECH_DISCOVERED
If your activity filters for theACTION_TECH_DISCOVERED intent, you must create an XML resource file that specifies the technologies that your activity supports within a tech-list set. Your activity is considered a match if a tech-list set is a subset of the technologies that are supported by the tag, which you can obtain by calling getTechList(). | 如果你的Activity要過濾ACTION_TECH_DISCOVERED類型的Intent,你必須建立一個XML資源檔案,該檔案在tech-list集合中指定你的Activity所支援的技術。如果tech-list集合是标簽所支援的技術的一個子集,那麼你的Activity被認為是比對的。通過調用getTechList()方法來獲得标簽所支援的技術集合。 |
For example, if the tag that is scanned supports MifareClassic, NdefFormatable, and NfcA, your tech-list set must specify all three, two, or one of the technologies (and nothing else) in order for your activity to be matched. | 例如,如果掃描到的标簽支援MifareClassic、NdefFormatable和NfcA,那麼為了跟它們比對,tech-list集合就必須指定所有這三種技術,或者指定其中的兩種或一種。 |
The following sample defines all of the technologies. You can remove the ones that you do not need. Save this file (you can name it anything you wish) in the <project-root>/res/xml folder. | 以下示例定義了所有的相關的技術。你可以根據需要删除其中一些設定。然後把這個檔案儲存到<project-root>/res/xml檔案夾中(你能夠把命名為任何你希望的名字): |
View Code
You can also specify multiple tech-list sets. Each of the tech-list sets is considered independently, and your activity is considered a match if any single tech-list set is a subset of the technologies that are returned bygetTechList(). This provides AND and OR semantics for matching technologies. The following example matches tags that can support the NfcA and Ndef technologies or can support the NfcB and Ndef technologies: | 你也能夠指定多個tech-list集合,每個tech-list集合被認為是獨立的,并且如果任何一個tech-list集合是由getTechList()傳回的技術的子集,那麼你的Activity就被認為是比對的。 下列示例能夠跟支援NfcA和Ndef技術NFC标簽或者跟支援NfcB和Ndef技術的标簽相比對: |
View Code
In your AndroidManifest.xml file, specify the resource file that you just created in the <meta-data> element inside the <activity> element like in the following example: | 在你的AndroidManifest.xml檔案中,要像向下列示例那樣,在<activity>元素内的<meta-data>元素中指定你建立的資源檔案: |
View Code
1.3.3 ACTION_TAG_DISCOVERED
To filter for ACTION_TAG_DISCOVERED use the following intent filter: | 使用下列Intent過濾器來過濾ACTION_TAG_DISCOVERED類型的Intent: |
View Code
1.3.4 從Intent中擷取資訊 (Obtaining information from intents)
If an activity starts because of an NFC intent, you can obtain information about the scanned NFC tag from the intent. Intents can contain the following extras depending on the tag that was scanned: | 如果因為NFC的Intent而啟動一個Activity,那麼你就能夠從Intent中擷取被掃描到的NFC标簽的相關資訊。根據被掃描到的标簽,Intent對象能夠以下額外的資訊: |
EXTRA_TAG (required): A Tag object representing the scanned tag. EXTRA_NDEF_MESSAGES (optional): An array of NDEF messages parsed from the tag. This extra is mandatory onintents. {@link android.nfc.NfcAdapter#EXTRA_ID (optional): The low-level ID of the tag. | 1. EXTRA_TAG(必須的):它是一個代表了被掃描到的标簽的Tag對象; 2. EXTRA_NDEF_MESSAGES(可選):它是一個解析來自标簽中的NDEF消息的數組。這個附加資訊是強制在Intent對象上的; 3. {@link android.nfc.NfcAdapter#EXTRA_ID(可選):标簽的低級ID。 |
To obtain these extras, check to see if your activity was launched with one of the NFC intents to ensure that a tag was scanned, and then obtain the extras out of the intent. The following example checks for theACTION_NDEF_DISCOVEREDintent and gets the NDEF messages from an intent extra. | 要擷取這些附加資訊,就要確定你的Activity是被掃描到的NFC的Intent對象啟動的,然後才能獲得Intent之外的附加資訊。 下例檢查ACTION_NDEF_DISCOVERED類型的Intent,并從Intent對象的附加資訊中擷取NDEF消息。 |
View Code
Alternatively, you can obtain a Tag object from the intent, which will contain the payload and allow you to enumerate the tag's technologies: Tag tag= intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); | 此外,你還能夠從Intent對象中獲得一個Tag對象,該對象包含了資料負載,并允許你列舉标簽的技術: Tag tag= intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); |
1.4 建立通用的NDEF記錄類型 (Creating Common Types of NDEF Records)
This section describes how to create common types of NDEF records to help you when writing to NFC tags or sending data with Android Beam. Starting with Android 4.0 (API level 14), thecreateUri() method is available to help you create URI records automatically. Starting in Android 4.1 (API level 16), createExternal()and createMime() are available to help you create MIME and external type NDEF records. Use these helper methods whenever possible to avoid mistakes when manually creating NDEF records. This section also describes how to create the corresponding intent filter for the record. All of these NDEF record examples should be in the first NDEF record of the NDEF message that you are writing to a tag or beaming. | 本節介紹如何建立通用的NDEF記錄類型,以便幫助你向NFC标簽寫入或用Android Beam發送資料。 從Android4.0(API Level14)開始,可以用createUri()方法來幫助你自動的建立URI記錄。 從Android4.1(API Level 16)開始,可以用createExternal()和createMime()方法來幫助你建立MIME和外部類型的NDEF記錄。 使用這些輔助方法會盡可能的避免手動建立NDEF記錄的錯誤。 本節還要介紹如何建立NDEF記錄對應的Intent過濾器。所有的這些寫入或發送到NFC标簽的NDEF記錄例子都應該是NDEF消息的第一條記錄。 |
1.4.1 TNF_ABSOLUTE_URI
Note: We recommend that you use the RTD_URI type instead of TNF_ABSOLUTE_URI, because it is more efficient. | 注意:我們推薦你使用RTD_URI類型,而不是TNF_ABSOLUTE_URI, 因為它更高效。 |
You can create a TNF_ABSOLUTE_URI NDEF record in the following way: | 用下列方法建立一個TNF_ABSOLUTE_URI類型的NDEF記錄: |
NdefRecord uriRecord = new NdefRecord( NdefRecord.TNF_ABSOLUTE_URI ,"http://developer.android.com/index.html".getBytes(Charset.forName("US-ASCII")),new byte[0], new byte[0]);
The intent filter for the previous NDEF record would look like this: | 對應的Intent過濾器如下: |
<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>
1.4.2 TNF_MIME_MEDIA
You can create a TNF_MIME_MEDIA NDEF record in the following ways. Using the createMime() method: | 使用下列方法建立TNF_MIME_MEDIA類型的NDEF記錄。 使用createMime()方法: |
NdefRecord mimeRecord = NdefRecord.createMime("application/vnd.com.example.android.beam","Beam me up, Android".getBytes(Charset.forName("US-ASCII")));
Creating the NdefRecord manually: | 手動的建立NdefRecord: |
NdefRecord mimeRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA ,"application/vnd.com.example.android.beam".getBytes(Charset.forName("US-ASCII")),
new byte[0], "Beam me up, Android!".getBytes(Charset.forName("US-ASCII")));
The intent filter for the previous NDEF records would look like this: | 對應的Intent過濾器如下: |
View Code
1.4.3 TNF_WELL_KNOWN和RTD_TEXT
You can create a TNF_WELL_KNOWN NDEF record in the following way: public NdefRecord createTextRecord(String payload, Locale locale, boolean encodeInUtf8) { byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII")); Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16"); byte[] textBytes = payload.getBytes(utfEncoding); int utfBit = encodeInUtf8 ? 0 : (1 << 7); char status = (char) (utfBit + langBytes.length); byte[] data = new byte[1 + langBytes.length + textBytes.length]; data[0] = (byte) status; System.arraycopy(langBytes, 0, data, 1, langBytes.length); System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length); NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data); return record; } | 用下列方法建立TNF_WELL_KNOWN類型的NDEF記錄: public NdefRecord createTextRecord(String payload, Locale locale, boolean encodeInUtf8) { byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII")); Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16"); byte[] textBytes = payload.getBytes(utfEncoding); int utfBit = encodeInUtf8 ? 0 : (1 << 7); char status = (char) (utfBit + langBytes.length); byte[] data = new byte[1 + langBytes.length + textBytes.length]; data[0] = (byte) status; System.arraycopy(langBytes, 0, data, 1, langBytes.length); System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length); NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data); return record; } |
the intent filter would look like this: <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> | 對應的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> |
1.4.4 TNF_WELL_KNOW和RTD_URI
You can create a TNF_WELL_KNOWN NDEF record in the following ways. Using the createUri(String) method: NdefRecord rtdUriRecord1=NdefRecord.createUri("http://example.com"); | 用下列方法建立TNF_WELL_KNOWN類型的NDEF記錄。 使用createUri(String)方法: NdefRecord rtdUriRecord1=NdefRecord.createUri("http://example.com"); |
Using the createUri(Uri) method: Uri uri = new Uri("http://example.com"); NdefRecord rtdUriRecord2 = NdefRecord.createUri(uri); | 使用createUri(Uri)方法: Uri uri = new Uri("http://example.com"); NdefRecord rtdUriRecord2 = NdefRecord.createUri(uri); |
Creating the NdefRecord manually: byte[] uriField = "example.com".getBytes(Charset.forName("US-ASCII")); byte[] payload = new byte[uriField.length + 1]; //add 1 for the URI Prefix byte payload[0] = 0x01; //prefixeshttp://www. to the URI System.arraycopy(uriField, 0, payload, 1, uriField.length); //appends URI to payload NdefRecord rtdUriRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload); | 手動的建立NdefRecord: byte[] uriField = "example.com".getBytes(Charset.forName("US-ASCII")); byte[] payload = new byte[uriField.length + 1]; //add 1 for the URI Prefix byte payload[0] = 0x01; //prefixeshttp://www. to the URI System.arraycopy(uriField, 0, payload, 1, uriField.length); //appends URI to payload NdefRecord rtdUriRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload); |
The intent filter for the previous NDEF records would look like this: <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="http" android:host="example.com" android:pathPrefix="" /> </intent-filter> | 對應的Intent過濾器如下: <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="http" android:host="example.com" android:pathPrefix="" /> </intent-filter> |
1.4.5 TNF_EXTERNAL_TYPE
You can create a TNF_EXTERNAL_TYPE NDEF record in the following ways: Using the createExternal() method: | 使用下列方法建立TNF_EXTERNAL_TYPE類型的記錄。 使用createExternal()方法: |
byte[] payload; //assign to your data
String domain = "com.example"; //usually your app's package name
String type = "externalType";
NdefRecord extRecord = NdefRecord.createExternal(domain, type, payload);
Creating the NdefRecord manually: | 手動的建立NdefRecord: |
byte[] payload;
...
NdefRecord extRecord = new NdefRecord(
NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType", new byte[0], payload);
The intent filter for the previous NDEF records would look like this: | 對應的Intent過濾器如下: |
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="vnd.android.nfc"
android:host="ext"
android:pathPrefix="/com.example:externalType"/>
</intent-filter>
Use TNF_EXTERNAL_TYPE for more generic NFC tag deployments to better support both Android-powered and non-Android-powered devices. | 使用更加一般化的TNF_EXTERNAL_TYPE類型NFC部署,以便更好的支援Android裝置和非Android裝置。 |
Note: URNs for TNF_EXTERNAL_TYPE have a canonical format of:urn:nfc:ext:example.com:externalType, however the NFC Forum RTD specification declares that the urn:nfc:ext: portion of the URN must be ommitted from the NDEF record. So all you need to provide is the domain (example.com in the example) and type (externalType in the example) separated by a colon. When dispatching TNF_EXTERNAL_TYPE, Android converts the urn:nfc:ext:example.com:externalType URN to avnd.android.nfc://ext/example.com:externalType URI, which is what the intent filter in the example declares. | 注意:TNF_EXTERNAL_TYPE類型的URN包含以下格式: urn:nfc:ext:example.com.externalType,但是,NFC論壇的RTD規範聲明,URN的urn:nfc:ext:部分在NDEF記錄中必須忽略。是以你需要提供的所有資訊是用“:”号把域名(示例中的example.com)和類型(示例中的externalType)分離開。在排程TNF_EXTERNAL_TYPE類型的記錄時,Android會把urn:nfc:ext:example.com:externalType的URN轉換成vnd.android.nfc://ext/example.com:externalType的URI,它是在示例中聲明的Intent過濾器。 |
1.5 Android應用程式記錄(Android Application Record---AAR)
Introduced in Android 4.0 (API level 14), an Android Application Record (AAR) provides a stronger certainty that your application is started when an NFC tag is scanned. An AAR has the package name of an application embedded inside an NDEF record. You can add an AAR to any NDEF record of your NDEF message, because Android searches the entire NDEF message for AARs. If it finds an AAR, it starts the application based on the package name inside the AAR. If the application is not present on the device, Google Play is launched to download the application. | 在Android4.0(API Level 14)中引入的Android應用程式記錄(AAR),提供了較強的在掃描到NFC标簽時,啟動應用程式的确定性。AAR有嵌入到NDEF記錄内部的應用程式的包名。你能夠把一個AAR添加到你的NDEF消息的任何記錄中,因為Android會針對AAR來搜尋整個NDEF消息。如果它找到一個AAR,它就會基于AAR内部的包名來啟動應用程式。如果該應用程式不在目前的裝置上,會啟動Google Play來下載下傳對應的應用程式。 |
AARs are useful if you want to prevent other applications from filtering for the same intent and potentially handling specific tags that you have deployed. AARs are only supported at the application level, because of the package name constraint, and not at the Activity level as with intent filtering. If you want to handle an intent at the Activity level, use intent filters. If a tag contains an AAR, the tag dispatch system dispatches in the following manner: | 如果你想要防止其他的應用對相同的Intent的過濾并潛在的處理你部署的特定的NFC标簽,那麼AAR是有用的。AAR僅在應用程式級被支援,因為包名的限制,并不能在Activity級别來過濾Intent。如果你想要在Activity級處理Intent,請使用Intent過濾器。 如果NFC标簽中包含了AAR,則NFC标簽排程系統會按照下列方式來排程: |
| 1. 通常,嘗試使用Intent過濾器來啟動一個Activity。如果跟該Intent比對的Activity也跟AAR比對,那麼就啟動該Activity。 2. 如果跟Intent隊形的Activity跟AAR不比對,或者是有多個Activity能夠處理該Intent,或者是沒有能夠處理該Intent的Activity存在,那麼就啟動由AAR指定的應用程式。 3. 如果沒有跟該AAR對應的應用程式,那麼就會啟動Google Play來小組基于該AAR的應用程式。 |
Note: You can override AARs and the intent dispatch system with the foreground dispatch system, which allows a foreground activity to have priority when an NFC tag is discovered. With this method, the activity must be in the foreground to override AARs and the intent dispatch system. | 注意:你能夠用前台排程系統來重寫AAR和Intent排程系統,在NFC标簽被發現時。它允許優先使用前台的Activity。用這種方法,Activity必須是在前台來重寫AAR和Intent排程系統。 |
If you still want to filter for scanned tags that do not contain an AAR, you can declare intent filters as normal. This is useful if your application is interested in other tags that do not contain an AAR. For example, maybe you want to guarantee that your application handles proprietary tags that you deploy as well as general tags deployed by third parties. Keep in mind that AARs are specific to Android 4.0 devices or later, so when deploying tags, you most likely want to use a combination of AARs and MIME types/URIs to support the widest range of devices. In addition, when you deploy NFC tags, think about how you want to write your NFC tags to enable support for the most devices (Android-powered and other devices). You can do this by defining a relatively unique MIME type or URI to make it easier for applications to distinguish. | 如果你依然想要過濾掃描到的沒有包含AAR的NFC标簽,通常,你能夠聲明Intent過濾器。如果你的應用程式對不包含AAR的其他NFC标簽感興趣,這種做法是有用的。例如,你可能想要保證你的應用程式處理你部署的專用NFC标簽,以及由第三方部署的普通的NFC标簽。要記住AAR是在Android4.0以後才指定的,是以部署NFC标簽時,你很可能希望使用能夠廣泛支援AAR和MIME類型/URI的是裝置。另外,在你部署NFC标簽時,還要想如何編寫你的NFC标簽,以便讓大多數裝置(Android裝置和其他裝置)支援。同過定義相對唯一的MIME類型或URI,讓應用程式更容易的區分,就可以做到這一點。 |
Android provides a simple API to create an AAR,createApplicationRecord(). All you need to do is embed the AAR anywhere in your NdefMessage. You do not want to use the first record of yourNdefMessage, unless the AAR is the only record in the NdefMessage. This is because the Android system checks the first record of an NdefMessage to determine the MIME type or URI of the tag, which is used to create an intent for applications to filter. The following code shows you how to create an AAR: | Android提供了簡單的建立AAR的API:createApplicationRecord()。你需要做的所有工作就是把AAR嵌入到你的NdefMessage中。除非AAR是NdefMessage中的唯一記錄,否則不要把使用NdefMessage的第一條記錄。這是因為,Android系統會檢查NdefMessage的第一條記錄來判斷NFC标簽的MIME類型或URI,這些資訊被用于建立對應應用程式的Intent對象。以下代碼示範了如何建立一個AAR: |
NdefMessage msg = new NdefMessage(
new NdefRecord[] {
...,
NdefRecord.createApplicationRecord("com.example.android.beam")}
1.6 把NDEF消息發射到其他裝置上
Android Beam allows simple peer-to-peer data exchange between two Android-powered devices. The application that wants to beam data to another device must be in the foreground and the device receiving the data must not be locked. When the beaming device comes in close enough contact with a receiving device, the beaming device displays the "Touch to Beam" UI. The user can then choose whether or not to beam the message to the receiving device. | Android Beam允許在兩個Android裝置之間進行簡單的對等資料交換,想要把資料發送給另一個裝置的應用程式必須是在前台,并且接收資料的裝置必須不被鎖定。當發射裝置跟接收裝置的距離足夠近的時候,發射裝置會顯示“Touch to Beam(觸摸發射)”的UI。然後,使用者能夠選擇是否把消息發射給接收裝置。 |
Note: Foreground NDEF pushing was available at API level 10, which provides similar functionality to Android Beam. These APIs have since been deprecated, but are available to support older devices. SeeenableForegroundNdefPush() for more information. | 注意:在API Level 10中可以利用前台的NDEF推送,它提供了與Android Beam類似的功能。這些API已經過時了,但是在一些老舊裝置上還有效。更多的資訊請看enableForegroundNdefPush()。 |
You can enable Android Beam for your application by calling one of the two methods:
| 通過調用下列兩個方法中的任意一個,就能夠為你的應用程式啟用Android Beam: 1. setNdefPushMessage():這個方法把接收到的NdefMessage對象作為一個消息設定給Beam。當兩個裝置足夠近的時候,就會自動的發送消息。 2. setNdefPushMessageCallback():接收包含createNdefMessage()方法的回調,當裝置在發射資料的範圍内時,這個回調方法會被調用。回調會讓你隻在需要的時候建立NDEF消息。 |
An activity can only push one NDEF message at a time, so setNdefPushMessageCallback() takes precedence over setNdefPushMessage() if both are set. To use Android Beam, the following general guidelines must be met:
| 一個Activity一次隻能推送一條NDEF消息,是以如果同時使用了這兩種方法,那麼setNdefPushMessageCallback()方法的優先級要高于setNdefPushMessage()方法。要使用Android Beam,通常必須滿足以下條件: 1. 發射資料的Activity必須是在前台。兩個裝置的螢幕都必須沒有被鎖定; 2. 必須發要發射的資料封裝到一個NdefMessage對象中; 3. 接收發射資料的NFC裝置必須支援com.android.npp NDEF推送協定或是NFC組織的SNEP協定(簡單的NDEF交換協定)。在API Level9(Android2.3)到API Level 13(Android3.2)的裝置上需要com.android.npp協定。在API Level 14(Android4.0)和以後的裝置上,com.android.npp和SNEP都需要。 |
Note: If your activity enables Android Beam and is in the foreground, the standard intent dispatch system is disabled. However, if your activity also enables foreground dispatching, then it can still scan tags that match the intent filters set in the foreground dispatching. | 注意:如果在前台的Activity啟用了Android Beam,那麼标準的Intent排程系統就會被禁用。但是,如果該Activity還啟用了前台排程,那麼在前台排程系統中,它依然能夠掃描到跟Intent過濾器比對的NFC标簽。 |
To enable Android Beam:
| 啟用Android Beam: 1. 建立一個準備推送到另一個裝置上的包含NdefRecord的NdefMessage對象。 2. 調用帶有NdefMessage類型參數的setNdefPushMessage()方法,或者是在Activity的onCreate()方法中調用setNdefPushMessageCallback方法來傳遞實作NfcAdapter.CreateNdefMessageCallback接口的對象。這兩個方法都至少需要一個準備要啟用Android Beam的Activity,以及一個可選的其他的活躍的Activity清單。 通常,如果你的Activity在任何時候都值推送相同的NDEF消息,那麼當兩個裝置在通信範圍内的時候,使用setNdefPushMessage()就可以了。當你的應用程式要關注應用程式的目前内容,并想要根據使用者在你的應用程式中的行為來推送NDEF消息時,就要使用setNdefPushMessageCallback方法。 |
The following sample shows how a simple activity calls NfcAdapter.CreateNdefMessageCallback in theonCreate() method of an activity (see AndroidBeamDemo for the complete sample). This example also has methods to help you create a MIME record: | 下列示例代碼示範了如何在activity的onCreate()方法中調用NfcAdapter.CreateNdefMessageCallback方法(完整的示例請看AndroidBeamDemo)。這個示例中還有幫助建立MIME記錄的方法: |
package com.example.android.beam;
import android.app.Activity;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
import android.nfc.NfcEvent;
import android.os.Bundle;
import android.os.Parcelable;
import android.widget.TextView;
import android.widget.Toast;
import java.nio.charset.Charset;
publicclassBeamextendsActivityimplementsCreateNdefMessageCallback{
NfcAdapter mNfcAdapter;
TextView textView;
@Override
publicvoid onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView textView =(TextView) findViewById(R.id.textView);
// Check for available NFC Adapter
mNfcAdapter =NfcAdapter.getDefaultAdapter(this);
if(mNfcAdapter ==null){
Toast.makeText(this,"NFC is not available",Toast.LENGTH_LONG).show();
finish();
return;
}
// Register callback
mNfcAdapter.setNdefPushMessageCallback(this,this);
}
@Override
publicNdefMessage createNdefMessage(NfcEventevent){
String text =("Beam me up, Android!\n\n"+
"Beam Time: "+System.currentTimeMillis());
NdefMessage msg =newNdefMessage(
newNdefRecord[]{ createMime(
"application/vnd.com.example.android.beam", text.getBytes())
/**
* The Android Application Record (AAR) is commented out. When a device
* receives a push with an AAR in it, the application specified in the AAR
* is guaranteed to run. The AAR overrides the tag dispatch system.
* You can add it back in to guarantee that this
* activity starts when receiving a beamed message. For now, this code
* uses the tag dispatch system.
*/
//,NdefRecord.createApplicationRecord("com.example.android.beam")
});
return msg;
}
@Override
publicvoid onResume(){
super.onResume();
// Check to see that the Activity started due to an Android Beam
if(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())){
processIntent(getIntent());
}
}
@Override
publicvoid onNewIntent(Intent intent){
// onResume gets called after this to handle the intent
setIntent(intent);
}
/**
* Parses the NDEF Message from the intent and prints to the TextView
*/
void processIntent(Intent intent){
textView =(TextView) findViewById(R.id.textView);
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
// only one message sent during the beam
NdefMessage msg =(NdefMessage) rawMsgs[0];
// record 0 contains the MIME type, record 1 is the AAR, if present
textView.setText(newString(msg.getRecords()[0].getPayload()));
}
}
Note that this code comments out an AAR, which you can remove. If you enable the AAR, the application specified in the AAR always receives the Android Beam message. If the application is not present, Google Play is started to download the application. Therefore, the following intent filter is not technically necessary for Android 4.0 devices or later if the AAR is used: | 注意:上例代碼把AAR給注釋掉了,你可以删除它。如果你啟用了AAR,那麼該應用程式就會始終接收在AAR中指定的Android Beam消息。如果該應用程式不存在,Google Play就會啟動下載下傳程式。是以,如果使用AAR,對于Android4.0以後的裝置,下列的Intent過濾器,在技術上不是必須的: |
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/vnd.com.example.android.beam"/>
</intent-filter>
With this intent filter, the com.example.android.beam application now can be started when it scans an NFC tag or receives an Android Beam with an AAR of type com.example.android.beam, or when an NDEF formatted message contains a MIME record of type application/vnd.com.example.android.beam. | 有了這個Intent過濾器,com.example.android.beam應用就能夠在以下情況下被啟動: 1. 掃描到NFC标簽; 2. 接收到com.example.android.beam類型的AAR或NDEF消息中包含一條application/vnd.com.example.android.beam類型的MIME記錄的Android beam的時候。 |
Even though AARs guarantee an application is started or downloaded, intent filters are recommended, because they let you start an Activity of your choice in your application instead of always starting the main Activity within the package specified by an AAR. AARs do not have Activity level granularity. Also, because some Android-powered devices do not support AARs, you should also embed identifying information in the first NDEF record of your NDEF messages and filter for that as well, just in case. SeeCreating Common Types of NDEF records for more information on how to create records. | 即使通過AAR能夠保證了一個應用程式被啟動或下載下傳,但是還是推薦使用Intent過濾器,因為它會讓你選擇啟動應用程式中Activity,而不是總啟動AAR中指定的應用程式包的主Activity。AAR沒有Activity級别的粒度。而且還有一些android裝置不支援AAR,你還應該在NDEF消息的第一條NDEF記錄中嵌入辨別資訊,以及對應的過濾器。 |
2 Advanced NFC
This document describes advanced NFC topics, such as working with various tag technologies, writing to NFC tags, and foreground dispatching, which allows an application in the foreground to handle intents even when other applications filter for the same ones. | 本文介紹一些進階的NFC專題,如多樣的NFC标簽技術、編寫NFC标簽、以及前台排程,前台排程允許在前台的應用程式優先排程Intent事件,即使還有其他的過濾同樣的Intent事件的應用程式存在。 |
2.1 Android所支援的NFC标簽技術
When working with NFC tags and Android-powered devices, the main format you use to read and write data on tags is NDEF. When a device scans a tag with NDEF data, Android provides support in parsing the message and delivering it in an NdefMessage when possible. There are cases, however, when you scan a tag that does not contain NDEF data or when the NDEF data could not be mapped to a MIME type or URI. In these cases, you need to open communication directly with the tag and read and write to it with your own protocol (in raw bytes). Android provides generic support for these use cases with theandroid.nfc.tech package, which is described in Table 1. You can use thegetTechList() method to determine the technologies supported by the tag and create the corresponding TagTechnologyobject with one of classes provided by android.nfc.tech | 在使用NFC标簽和Android裝置來進行工作的時候,使用的讀寫NFC标簽上資料的主要格式是NDEF。當裝置掃描到帶有NDEF的資料時,Android會提供對消息解析的支援,并在可能的時候,會以NdefMessage對象的形式來發送它。但是,有些情況下,裝置掃描到的NFC标簽沒有包含NDEF資料,或者該NDEF資料沒有被映射到MIME類型或URI。在這些情況下,你需要打開跟NFC标簽的通信,并用自己的協定(原始的位元組形式)來讀寫它。Android用android.nfc.tech包提供了對這些情況的一般性支援,這個包在下表1中介紹。你能夠使用getTechList()方法來判斷NFC标簽所支援的的技術,并且用android.nfc.tech提供的一個類來建立對應的TagTechnology對象。 |
Table 1. Supported tag technologies (表1.NFC标簽所支援的技術)
類 | 介紹 |
TagTechnology | 所有的NFC标簽技術類必須實作的接口。 |
NfcA | 提供對NFC-A(ISO 14443-3A)屬性和I/O操作的通路。 |
NfcB | 提供對NFC-B(ISO 14443-3B)屬性和I/O操作的通路。 |
NfcF | 提供對NFC-F(ISO 6319-4)屬性和I/O操作的通路。 |
NfcV | 提供對NFC-V(ISO 15693)屬性和I/O操作的通路。 |
IsoDep | 提供對NFC-A(ISO 14443-4)屬性和I/O操作的通路。 |
Ndef | 提供對NDEF格式的NFC标簽上的NDEF資料和操作的通路。 |
NdefFormatable | 提供了對可以被NDEF格式化的NFC标簽的格式化操作。 |
The following tag technlogies are not required to be supported by Android-powered devices.
Table 2. Optional supported tag technologies (表2.可選的NFC标簽所支援的技術)
類 | 介紹 |
MifareClassic | 如果Android裝置支援MIFARE,那麼它提供了對經典的MIFARE類型标簽屬性和I/O操作的通路。 |
MifareUltralight | 如果Android裝置支援MIFARE,那麼它提供了對超薄的MIFARE類型标簽屬性和I/O操作的通路。 |
2.1.1 NFC标簽和ACTION_TECH_DISCOVERED類型的Intent協同工作
When a device scans a tag that has NDEF data on it, but could not be mapped to a MIME or URI, the tag dispatch system tries to start an activity with the ACTION_TECH_DISCOVEREDintent. TheACTION_TECH_DISCOVERED is also used when a tag with non-NDEF data is scanned. Having this fallback allows you to work with the data on the tag directly if the tag dispatch system could not parse it for you. The basic steps when working with tag technologies are as follows: | 當裝置掃描到帶有NDEF資料的NFC标簽,但卻不能映射到MIME或URI時,NFC标簽排程系統就嘗試使用ACTION_TECH_DISCOVERED類型的Intent來啟動一個Activity。在被掃描到的NFC标簽上沒有NDEF資料時,也會使用ACTION_TECH_DISCOVERED類型的Intent。有了這種回退機制,如果排程系統不能夠幫你解析資料,那麼你就可以直接使用NFC标簽上資料來工作。基本步驟如下: |
| 1. 給你希望處理的NFC标簽指定ACTION_TECH_DISCOVERED類型的Intent過濾器。更多資訊請看“NFC的Intent過濾”。通常,在NDEF消息不能被映射到MIME類型或URI時,或者被掃描到的NFC标簽不包含NDEF資料時,NFC标簽排程系統會嘗試啟動一個ACTION_TECH_DISCOVERED類型的Intent。更多資訊,請看“NFC标簽排程系統”。 2. 應用程式接收到Intent對象時,從該Intent對象中擷取Tag對象: Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); 3. 通過調用android.nfc.tech包中對應類的一個get工廠方法,來擷取一個TagTechnology對象執行個體。在調用get工廠方法之前,通過調用getTechList()方法來枚舉NFC标簽所支援的技術。例如,用下列方法從Tag對象中擷取MifareUltralight對象執行個體: MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)); |
2.1.2 讀寫NFC标簽
Reading and writing to an NFC tag involves obtaining the tag from the intent and opening communication with the tag. You must define your own protocol stack to read and write data to the tag. Keep in mind, however, that you can still read and write NDEF data when working directly with a tag. It is up to you how you want to structure things. The following example shows how to work with a MIFARE Ultralight tag. | 讀寫NFC标簽,要涉及到從Intent對象中擷取标簽,并要打開與标簽的通信。要讀寫NFC标簽資料,你必須要定義自己的協定棧。但是,要記住在直接使用NFC标簽工作時,你依然能夠讀寫NDEF資料。這是你想要如何建構的事情。下例示範了如何使用MIFARE超薄标簽來工作: |
+ View Code
2.2 使用前台排程系統
The foreground dispatch system allows an activity to intercept an intent and claim priority over other activities that handle the same intent. Using this system involves constructing a few data structures for the Android system to be able to send the appropriate intents to your application. To enable the foreground dispatch system: | 前台排程系統允許一個Activity攔截Intent對象,并且聲明該Activity的優先級要比其他的處理相同Intent對象的Activity高。使用這個系統涉及到為Android系統建構一些資料結構,以便能夠把相應的Intent對象發送給你的應用程式,以下是啟用前台排程系統的步驟: |
1 Add the following code in the onCreate() method of your activity:
PendingIntent pendingIntent =PendingIntent.getActivity( this,0,newIntent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0);
IntentFilter ndef =newIntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); try{ ndef.addDataType("* } catch(MalformedMimeTypeException e){ thrownewRuntimeException("fail", e); } intentFiltersArray =newIntentFilter[]{ndef,};
| 1. 在你的Activity的onCreate()方法中添加下列代碼: A. 建立一個PendingIntent對象,以便Android系統能夠在掃描到NFC标簽時,用它來封裝NFC标簽的詳細資訊。 PendingIntent pendingIntent =PendingIntent.getActivity( this,0,newIntent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0); B. 聲明你想要截獲處理的Intent對象的Intent過濾器。前台排程系統會在裝置掃描到NFC标簽時,用聲明的Intent過濾器來檢查接收到的Intent對象。如果比對就會讓你的應用程式來處理這個Intent對象,如果不比對,前台排程系統會回退到Intent排程系統。如果Intent過濾器和技術過濾器的數組指定了null,那麼就說明你要過濾所有的退回到TAG_DISCOVERED類型的Intent對象的标簽。以下代碼會用于處理所有的NDEF_DISCOVERED的MIME類型。隻有在需要的時候才做這種處理: IntentFilter ndef =newIntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); try{ ndef.addDataType("* } catch(MalformedMimeTypeException e){ thrownewRuntimeException("fail", e); } intentFiltersArray =newIntentFilter[]{ndef,}; C. 建立一個應用程式希望處理的NFC标簽技術的數組。調用Object.class.getName()方法來擷取你想要支援的技術的類: techListsArray = new String[][] { new String[] { NfcF.class.getName() } }; |
2 Override the following activity lifecycle callbacks and add logic to enable and disable the foreground dispatch when the activity loses (onPause()) and regains (onResume()) focus.enableForegroundDispatch() must be called from the main thread and only when the activity is in the foreground (calling in onResume() guarantees this). You also need to implement the onNewIntentcallback to process the data from the scanned NFC tag. publicvoid onPause(){ super.onPause(); mAdapter.disableForegroundDispatch(this); } publicvoid onResume(){ super.onResume(); mAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray); } publicvoid onNewIntent(Intent intent){ Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); //do something with tagFromIntent } | 2. 重寫下列Activity生命周期的回調方法,并且添加邏輯在Activity挂起(onPause())和獲得焦點(onResume())時,來啟用和禁用前台排程。enableForegroundDispatch()方法必須在主線程中被調用,并且隻有在該Activity在前台的時候(要保證在onResume()方法中調用這個方法)。你還需要實作onNewIntent回調方法來處理掃描到的NFC标簽的資料: publicvoid onPause(){ super.onPause(); mAdapter.disableForegroundDispatch(this); } publicvoid onResume(){ super.onResume(); mAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray); } publicvoid onNewIntent(Intent intent){ Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); //do something with tagFromIntent } |
See the ForegroundDispatch sample from API Demos for the complete sample | 完整的示例請看API Demo中的ForegroundDispatch |
作者:skyseraph
出處:http://www.cnblogs.com/skyseraph/
Email/GTalk: [email protected]
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。
分類: 【16】Android, 【54】NFC 綠色通道: 好文要頂 關注我 收藏該文 與我聯系
SkySeraph
關注 - 8
粉絲 - 472 +加關注 3 0 (請您對文章做出評價) « 上一篇: 【分享】RSS訂閱技巧及工具和實用RSS連結分享
» 下一篇: 【分享】一款手機真機螢幕同步抓取軟體
posted @ 2013-01-27 19:54 SkySeraph 閱讀( 6270) 評論( 5) 編輯 收藏
評論清單 #1樓 2013-01-27 21:41 KejianLi 翻譯得很好,非常喜歡這樣的形式! 支援(0) 反對(0) #2樓 2013-01-28 09:26 john23.net 感謝分享 支援(0) 反對(0) #3樓 2013-03-18 10:46 zx132797 請問樓主如何實作加密呀? 支援(0) 反對(0) #4樓 [ 樓主] 2013-03-18 14:00 SkySeraph @zx132797
這個加密是指?傳輸内容加密? NFC晶片/協定加密? 還是? 支援(0) 反對(0) #5樓 2013-04-26 23:09 zx132797 不好意思才看到樓主回複,樓主回複神速呀!NFC晶片/協定加密? 忘樓主回複 支援(0) 反對(0) 重新整理評論 重新整理頁面 傳回頂部 注冊使用者登入後才能發表評論,請 登入 或 注冊, 通路網站首頁。 【推薦】50萬行VC++源碼: 大型組态工控、電力仿真CAD與GIS源碼庫
融雲,免費為你的App加入IM功能——讓你的App“聊”起來!!
【活動】刮上代金券,使用再送100元大禮包!
最新IT新聞:
· Docker Hub中超過30%的官方鏡像包含高危漏洞
· A輪估值10億美元的WiFi萬能鑰匙竟然啟動了股權衆籌
· 騰訊滴滴聯合推線下掃碼付車費
· 阿裡影業董事長任光線董事,阿裡、光線進入“蜜月期”?
· 沒有十全十美的技術!攜程事件之後,技術專家們的建議與反思
» 更多新聞... 最新知識庫文章:
· 微服務實戰(一):微服務架構的優勢與不足
· 編寫高品質的代碼——從命名入手
· 領域驅動設計系列(3)有選擇性的使用領域驅動設計
· 專訪Facebook HipHop作者/阿裡研究員趙海平:生物與計算機交織的獨特人生
· 內建架構:對比 Web API 與面向服務的架構和企業應用程式內建
» 更多知識庫文章...
公告
領域:移動開發/智能家居/無線互聯/圖像識别/機器視覺
信念:務實求真
聯系方式(交流合作)
[email protected]
Link: CSDN/Github
檢視詳情
昵稱: SkySeraph
園齡: 4年11個月
粉絲: 472
關注: 8 +加關注
| ||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|---|---|---|---|---|---|
30 | 31 | 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
搜尋
常用連結
- 我的随筆
- 我的評論
- 我的參與
- 最新評論
- 我的标簽
- 更多連結
最新随筆
- 1. 【Android】Eclipse自動編譯NDK/JNI的三種方法
- 2. 【讀書筆記】精益創業實戰
- 3. 【讀書筆記】高效能人士的七個習慣
- 4. 《Android NFC 開發實戰詳解 》簡介+源碼+樣章+勘誤ING
- 5. 【讀書筆記】人人都是産品經理
- 6. 【My Life】寫在年末, 我的2013
- 7. 【Android】ListView中EditText焦點問題
- 8. 【Android】Android 4.2源碼下載下傳(ubuntu 12.10)
- 9. 【分享】一款手機真機螢幕同步抓取軟體
- 10. 【NFC】Android NFC API Reference中英文
随筆分類(220)
- 【00】[Menu](3)
- 【10】[編程語言篇]
- 【11】C/CPP(9)
- 【12】java/c#
- 【13】Objective C
- 【15】[作業系統篇]
- 【16】Android(26)
- 【17】Linux(1)
- 【18】iOS(1)
- 【19】WinPhone
- 【20】[開發工具篇]
- 【21】VS/VC/MFC(22)
- 【22】Eclipse
- 【25】[電子硬體篇]
- 【26】ARM/DSP(8)
- 【27】FPGA/SOPC(3)
- 【28】電子電路/PCB(3)
- 【29】硬體相關(3)
- 【30】[計算機視覺篇]
- 【31】DIP(12)
- 【32】Color ImgSeg(14)
- 【33】OpenCV(11)
- 【34】ML/PR(4)
- 【35】OpenGL
- 【39】Math(1)
- 【40】[流媒體篇](7)
- 【41】SMS
- 【50】[無線篇]
- 【54】NFC(2)
- 【55】[人機互動篇]
- 【56】Kinect & OpenNI
- 【60】[產品篇]
- 【61】TV(1)
- 【62】Phone
- 【70】[Others]
- 【71】面試筆試(6)
- 【73】連結收藏(17)
- 【74】學術科研(8)
- 【75】English Study(13)
- 【76】My Translate
- 【78】7788(11)
- 【80】[CTO]
- 【81】系統架構
- 【82】軟體架構
- 【84】項目管理
- 【85】讀書筆記(3)
- 【86】我的分享(5)
- 【90】[SkySeraph]
- 【91】My Sft(3)
- 【92】My Project(9)
- 【93】我的開源
- 【95】軟體出售(3)
- 【96】My Books(1)
- 【99】Burning Life(10)
随筆檔案(192)
- 2014年9月 (1)
- 2014年8月 (1)
- 2014年4月 (1)
- 2014年3月 (2)
- 2013年12月 (1)
- 2013年4月 (1)
- 2013年2月 (2)
- 2013年1月 (2)
- 2012年12月 (1)
- 2012年6月 (1)
- 2012年5月 (1)
- 2012年4月 (4)
- 2012年3月 (14)
- 2012年2月 (4)
- 2011年12月 (1)
- 2011年11月 (1)
- 2011年10月 (1)
- 2011年9月 (1)
- 2011年8月 (7)
- 2011年7月 (9)
- 2011年6月 (6)
- 2011年5月 (15)
- 2011年4月 (7)
- 2011年3月 (16)
- 2011年2月 (3)
- 2011年1月 (7)
- 2010年12月 (13)
- 2010年11月 (26)
- 2010年10月 (36)
- 2010年9月 (7)
相冊(2)
- SkySeraph(2)
Personal
- Google Profile
- SkySeraph-CSDN
- SkySeraph-GitHub
部落格收藏
積分與排名
- 積分 - 170282
- 排名 - 815
最新評論
- 1. Re:【Android】Eclipse自動編譯NDK/JNI的三種方法
- 謝樓主,還是cygwin 最簡單,另外,使用多種方法會重複編譯。另外cygwin的參數好像不對,看的不大清楚,我的是 --login -c "cd /cygdrive/e/android-ndk-r1......
- --Emilio66
- 2. Re:【圖像算法】圖像特征:GLCM
-
樓主,你好!最近在看GLCM方面的資料,看到了你的這篇部落格,可以把完整的code發我一份學習嗎?
[email protected]
非常感謝!
- --hellowhut
- 3. Re:【圖像算法】彩色圖像分割專題八:基于MeanShift的彩色分割
- 樓主你好,最後一張包含邊緣的圖像是利用查找輪廓的API函數對經過Mean shift算法分割後的圖像進行提取的邊緣然後和原圖像合成嗎?還是直接對原圖進行查找輪廓?
- --冥夜殘月
- 4. Re:【圖像算法】彩色圖像分割專題八:基于MeanShift的彩色分割
- @冥夜殘月運作算法後被修改後的原圖...附注:OpenCV有很多API函數在使用時都會對原圖進行修改,例如查找輪廓相關的API函數...
- --SkySeraph
- 5. Re:【圖像算法】彩色圖像分割專題八:基于MeanShift的彩色分割
- 樓主你好,請問你最後一張包含邊緣的圖像是怎麼生成的?
- --冥夜殘月
閱讀排行榜
- 1. 【筆試面試】75道邏輯推理題及答案(52393)
- 2. 【流媒體】Android 實時視訊采集—Camera預覽采集(30283)
- 3. 【流媒體】H264—MP4格式及在MP4檔案中提取H264的SPS、PPS及碼流(24122)
- 4. 【流媒體】 Android 實時視訊編碼—H.264寫死(23045)
- 5. 【流媒體】Android 實時視訊采集—MediaRecoder錄制(20483)
- 6. 【Android】Android 4.2源碼下載下傳(ubuntu 12.10)(18166)
- 7. 【流媒體】live555—VS2010/VS2013 下live555編譯、使用及測試(16367)
- 8. 【圖像算法】七種常見門檻值分割代碼(Otsu、最大熵、疊代法、自适應閥值、手動、疊代法、基本全局門檻值法)(15776)
- 9. 【流媒體】Android 實時視訊采集/編碼/傳輸/解碼/播放—方案調研(初)(15251)
- 10. 【Android學習專題】多媒體篇:MediaRecorder 實作錄音機(11533)
評論排行榜
- 1. 【圖像算法】圖像特征:三個圖像顯著性區域特征提取方法(61)
- 2. 【思考】一個博士的幾句心聲或牢騷(30)
- 3. 【流媒體】live555—VS2010/VS2013 下live555編譯、使用及測試(22)
- 4. 【圖像算法】圖像特征:GLCM(19)
- 5. 【My Sft】彩色圖像分析軟體V1.0.1.0(16)
推薦排行榜
- 1. 【流媒體】live555—VS2010/VS2013 下live555編譯、使用及測試(10)
- 2. 【流媒體】H264—MP4格式及在MP4檔案中提取H264的SPS、PPS及碼流(10)
- 3. 【My Life】寫在年末, 我的2013(9)
- 4. 【流媒體】Android 實時視訊采集—Camera預覽采集(8)
- 5. 【圖像算法】圖像特征:三個圖像顯著性區域特征提取方法(8)
- 6. 【Android學習專題】控件元件篇:Dialog彙總(7)
- 7. 【圖像算法】七種常見門檻值分割代碼(Otsu、最大熵、疊代法、自适應閥值、手動、疊代法、基本全局門檻值法)(7)
- 8. 【流媒體】 Android 實時視訊編碼—H.264寫死(6)
- 9. Husband的忏悔信(IT攻城獅)(6)
- 10. 【思考】一個博士的幾句心聲或牢騷(6)
Copyright ©2015 SkySeraph