译自 https://developer.android.google.cn/guide/topics/connectivity/nfc/nfc.html

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, see Advanced NFC.

该文档描述了你可以在Android设备上执行的NFC的基本操作。它揭示了在NDEF(NFC Data Exchange Format,NFC数据交换格式)信息上如何发送和接受NFC数据,并且描述了支持该特性的Android 框架应用程序接口。更高级的主题包括无NDEF数据通信,请参阅“Advanced 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标签中读取NDEF数据
  • 使用Android Beam™技术将NDEF信息从一个设备发送到另一个设备

Reading NDEF data from an NFC tag is handled with the tag 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标签,它可以声明一个意图过滤器来要求操作该数据。

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,手动的设备发现和配对操作都是不必要的。当两设备靠近到一定距离时,连接会自动启动。

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.

当屏幕没有被锁定时,Android设备通常都在寻找NFC标签,除非在设备的设置菜单中NFC被关闭。当Android设备发现NFC标签时,期望的行为是最合适的activity来处理该意图而不是询问用户该使用哪一个应用。应为设备在一个非常短的距离内扫描到NFC标签,如果让用户手动去选择activity,非常可能会导致他们将设备远离该标签并且终止连接。你应该研发你的activity让它成为NFC标签的唯一处理者,同时避免activity选择器的出现。

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:

  1. Parsing the NFC tag and figuring out the MIME type or a URI that identifies the data payload in the tag.
  2. Encapsulating the MIME type or URI and the payload into an intent. These first two steps are described in How NFC tags are mapped to MIME types and URIs.
  3. Starts an activity based on the intent. This is described in How NFC Tags are Dispatched to Applications.

为了帮助你实现这一目标,Android提供了一个特殊的标签调度系统,他可以分析扫描到的NFC标签,并解析它们,然后尝试去定位对扫描到的数据感兴趣的应用。通过如下方式来实现它:

  1. 解析NFC标签,并计算出MIME(Multipurpose Internet Mail Extensions,多用途因特网邮件扩充)类型,或者标签中指明数据载荷的URI(Uniform Resource Identifier,统一资源标识符)。
  2. 将MIME类型或者URI和它的载荷封装进一个意图。这两个步骤描述了NFC标签如何映射到MIME类型和URI的。
  3. 基于该意图启动一个acitivty。它描述了NFC标签是如何分发给应用程序的。

How NFC tags are mapped to MIME types and URIs

(译:NFC标签是怎么被映射到MIME类型和URI的)

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支持的NDEF标准是由NFC论坛所定义的。

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 the android.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记录都必须依据NDEF记录类型说明书具有良好的格式。Android也支持其它类型的不包含NDEF数据的标签,你可以使用的这些类都在android.nfc.tech包中。想要学习更多关于这些的技术,可以查看“Advanced NFC条目”。使用这些其它类型的标签涉及到要写你自己的协议栈来和这些标签进行通信,因此我们推荐使用NDEF,来减少开发难度并且并且最大化地支持Android设备。

Note: To download complete NDEF specifications, go to the NFC Forum Specification Download site and see Creating common types of NDEF records for examples of how to construct NDEF records.

注意:要下载完整的NDEF规范,请去“NFC Forum Specification”网址来下载,如何构造NDEF记录的例子请参考Creating common types of NDEF records 。

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 NdefRecord contains the following fields:

  • 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 using TNF_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.

现在你已经具备了一些NFC标签的背景知识了,接下来的章节会更详尽地介绍Android如何处理NDEF格式的标签。当Android设备扫描到一个包含NDEF格式数据的NFC的标签时,它会解析该信息并且尝试计算出数据的MIME类型或者标识的URI。为了做这个,系统读取NdfMessage内部的第一个NdfRecord来决定如何解释整个NDEF信息(一个NDEF信息可以有多个NEDF记录)。在一个格式良好的NDEF信息中,首个NdefRecord包含如下域:

  • 3-比特 TNF (Type Name Format,类型名格式)
    指示如何翻译变长类型域。Table 1 中描述了合法的值。
  • 变长类型
    描述了该记录的类型。如果TNF的格式良好,就可以使用它来指明记录类型定义(RTD,Record Type Definition)。Table 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, a Tag object that has information about the tag’s technologies and the payload are encapsulated inside of a ACTION_TECH_DISCOVERED intent instead.

标签调度系统使用TNF和类型域来映射NDEF信息的MIME类型或者URI。如果成功,它就会将数据连同实际载荷一起封装在ACTION_NDEF_DISCOVERED意图中。然而,有时候标签调度系统根据NDEF的首个记录也决定不了数据的类型。这种情况发生在NDEF数据无法映射到MIME类型或URI上时,或者当NFC标签的起始处不包含NDEF数据。在这种情况下,取而代之的,一个带有标签技术信息和载荷的标签对象就会被封装到 ACTION_TECH_DISCOVERED 意图中。

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 to ACTION_TECH_DISCOVERED.

表1 描述了标签调度系统如何将TNF和类型域映射到MIME类型或者URIs。它也描述了那些TNF不能映射到MIME类型或URI的情况。这种情况下,标签调度系统回退到 ACTION_TECH_DISCOVERED。

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意图的数据域中,就比如载荷。另一方面,如果遇到了TNF_UNKNOWN类型的记录,它就会创建一个封装了该标签技术的意图来代替。

Table 1. Supported TNFs and their mappings
(译:支持的TNF和它们的映射)

Type Name Format(TNF) Value Mapping
TNF_ABSOLUTE_URI 3 URI based on the type field.
TNF_EMPTY 0 Falls back to ACTION_TECH_DISCOVERED.
TNF_EXTERNAL_TYPE 4 URI based on the URN(Uniform Resource Name) in the type field. The URN is encoded into the NDEF type field in a shortened form: <domain_name>:<service_name>. Android maps this to a URI in the form: vnd.android.nfc://ext/<domain_name>:<service_name>.

译:URI由类型域的统一资源名称URN(Uniform Resource Name)决定。URN以一个简短的形式被编进NDEF类型域:<domain_name>:<service_name>.Android将它用这种形式映射到URI:vnd.android.nfc://ext/<domain_name>:<service_name>.

TNF_MIME_MEDIA 2 MIME type based on the type field.
TNF_UNCHANGED 6 Invalid in the first record, so falls back to ACTION_TECH_DISCOVERED.
TNF_UNKNOWN 5 Falls back to ACTION_TECH_DISCOVERED.
TNF_WELL_KNOWN 1 MIME type or URI depending on the Record Type Definition (RTD), which you set in the type field. See Table 2. for more information on available RTDs and their mappings.

译:MIME类型或者URI由记录类型定义RTD(Record Type Defination)决定,你可以在类型域设置它们。更多关于RTD的可用信息和它们的映射请参看表2.

Table 2. Supported RTDs for TNF_WELL_KNOWN and their mappings
(译:TNF_WELL_KNOWN 支持的RTD及它们的映射)

Record Type Definition(RTD) Value Mapping
RTD_ALTERNATIVE_CAARIER
译:代替的载体
{0x61, 0x63}// “ac” Falls back to ACTION_TECH_DISCOVERED.
RTD_HANDOVER_CAARIER
译:切换载波
{0x48, 0x63};// “Hc” Falls back to ACTION_TECH_DISCOVERED.
RTD_HANDOVER_REQUEST
译:切换请求
{0x48, 0x72};// “Hr” Falls back to ACTION_TECH_DISCOVERED.
RTD_HANDOVER_SELECT
译:切换选择
{0x48, 0x73};// “Hs” Falls back to ACTION_TECH_DISCOVERED.
RTD_SMART_POSTER
译:智能海报
{0x53, 0x70};// “Sp” URI based on parsing the payload
译:URI由解析后的载荷决定
RTD_TEXT {0x54}// “T” MIME type of text/plain.
RTD_URI {0x55}// “U” URI based on payload.

How NFC Tags are Dispatched to Applications

(译:NFC标签是如何被分发到应用程序的)

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:

  1. ACTION_NDEF_DISCOVERED: This intent is used to start an Activity when a tag that contains an NDEF payload is scanned and is of a recognized type. This is the highest priority intent, and the tag dispatch system tries to start an Activity with this intent before any other intent, whenever possible.
  2. ACTION_TECH_DISCOVERED: If no activities register to handle the ACTION_NDEF_DISCOVERED intent, the tag dispatch system tries to start an application with this intent. This intent is also directly started (without starting ACTION_NDEF_DISCOVERED first) if the tag that is scanned contains NDEF data that cannot be mapped to a MIME type or URI, or if the tag does not contain NDEF data but is of a known tag technology.
  3. ACTION_TAG_DISCOVERED: This intent is started if no activities handle the ACTION_NDEF_DISCOVERED or ACTION_TECH_DISCOVERED intents.

当标签调度系统创建完一个封装了NFC标签和它的标识信息的意图之后,就会将该意图送到该意图送到过滤了改意图并对它感兴趣的应用程序中。如果不止一个应用能处理该意图,Activity选择器就会出现,让用户可以选择对应的Activity。标签调度系统定义了三种意图,它们按优先级从高到低排序如下。

  1. ACTION_NDEF_DISCOVERED:该意图是当检测到一个包含NDEF载荷和可识别的类型的标签时,用来启动Activiy的。它是最高优先级的意图,并且标签调度系统会尽可能使用该意图而不是其它意图来启动Activity。
  2. ACTION_TECH_DISCOVERED:如果没有任何activities可以处理ACTION_NDEF_DISCOVERED意图,标签调度系统就会尝试用该意图启动Activity。如果标签包含不能被映射到MIME类型或者URI的NDEF数据,或者标签不包含NDEF数据但是包含一个已知的标签技术,该意图就可以直接被启动(不用先启动ACTION_NDEF_DISCOVERED)。
  3. ACTION_TAG_DISCOVERED:如果没有任何activities可以处理 ACTION_NDEF_DISCOVERED 或者 ACTION_TECH_DISCOVERED,就会启动该意图。

The basic way the tag dispatch system works is as follows:

  1. Try to start an Activity with the intent that was created by the tag dispatch system when parsing the NFC tag (either ACTION_NDEF_DISCOVERED or ACTION_TECH_DISCOVERED).
  2. If no activities filter for that intent, try to start an Activity with the next lowest priority intent (either ACTION_TECH_DISCOVERED or ACTION_TAG_DISCOVERED) until an application filters for the intent or until the tag dispatch system tries all possible intents.
  3. If no applications filter for any of the intents, do nothing.

标签调度系统的基本工作方式如下:

  1. 当解析到NFC标签时,尝试使用由标签调度系统创建的意图启动Activity。
  2. 如果没有activities过滤了该意图,尝试用一个带有比它低一级的意图(ACTION_TECH_DISCOVERED 或 ACTION_TAG_DISCOVERED)去启动Activity,直到一个应用程序过滤器定义了该意图或者标签调度系统尝试了所有可能的意图。
  3. 如果没有应用程序过滤器定义了这些意图,那么什么也不做。


Figure 1. Tag Dispatch System
(译:图1. 标签调度系统)

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意图,因为它是三个里面最明确的。该意图比起其它两个意图,允许在更合适的时机启动你的应用,并且提供一个更好的用户体验。

Requesting NFC Access in the Android Manifest

(在Android的清单中声明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意图之前,将下列项声明在你的AndroidManifest.xml文件中:

  • The NFC <uses-permission> element to access the NFC hardware:

NFC的<uses-permission>元素是用来访问NFC固件的。

<uses-permission android:name="android.permission.NFC" />
  • 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 the EXTRA_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.

你的应用可以支持的最小SDK版本:API 9级别仅支持受限的标签分发器通过ACTION_TAG_DISCOVERED,和EXTRA_NDEF_MESSAGES附加项来访问NDEF信息。没有其它可访问的tag属性或I/O操作。API 10级别包含了广泛的读/写器支持,也更好的推动了NDEF的前景,并且API 14提供了更简单的方式通过Android Beam技术将NDEF信息推送到其它设备和额外的创建NDEF记录的简便方法。

<uses-sdk android:minSdkVersion="10"/>
  • The uses-feature element so that your application shows up in Google Play only for devices that have NFC hardware:

uses-feature元素可以让你的应用在Google Play上只针对带有NFC硬件的设备才会显示:

<uses-feature android: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 if getDefaultAdapter() is null.

如果你的应用使用NFC的功能,但是这些功能对于你的应用来说并不重要,你就可以忽略uses-feature元素,并且在运行时通过判断getDefaultAdapter()是否为null来校验NFC的可见性。

Filtering for 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. However, you usually want to filter for the ACTION_NDEF_DISCOVERED intent for the most control of when your application starts. The ACTION_TECH_DISCOVERED intent is a fallback for ACTION_NDEF_DISCOVERED when no applications filter for ACTION_NDEF_DISCOVERED or for when the payload is not NDEF. Filtering for ACTION_TAG_DISCOVERED is usually too general of a category to filter on. Many applications will filter for ACTION_NDEF_DISCOVERED or ACTION_TECH_DISCOVERED before ACTION_TAG_DISCOVERED, so your application has a low probability of starting. ACTION_TAG_DISCOVERED is only available as a last resort for applications to filter for in the cases where no other applications are installed to handle the ACTION_NDEF_DISCOVERED or ACTION_TECH_DISCOVERED intent.

你的Android应用程序的清单中可以过滤一种,两种,或所有的三种NFC意图,这样当你想要处理的NFC标签被扫描到的时候,它就会启动你的应用程序。然而,当你的应用启动时,你通常想要通过过滤 ACTION_NDEF_DISCOVERED 来获取最大的控制权。当没有应用过滤ACTION_NDEF_DISCOVERED 或者它的载荷不是NDEF格式时,ACTION_TECH_DISCOVERED 会作为 ACTION_NDEF_DISCOVERED的回退机制。ACTION_TAG_DISCOVERED 作为过滤目录也很常见。大部分应用在过滤 ACTION_TAG_DISCOVERED 之前都会过滤 ACTION_NDEF_DISCOVERED 或 ACTION_TECH_DISCOVERED,因此你的应用很少有机会启动。ACTION_TAG_DISCOVERED 只有在万不得已的情况下才会被使用,这种情况是没有其它任何安装的应用程序能够处理ACTION_NDEF_DISCOVERED 或者 ACTION_TECH_DISCOVERED 意图。

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标签部署的多样化并且大部分情况下不在你的控制范围之内,事情并不总是这样的,这就是为什么必要时,你需要回退到其它两类意图。当你能控制标签的类型和数据的写入时,推荐你使用NDEF来格式化你的标签。下面几节描述了如何筛选每个类型的意图。

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:

要过滤 ACTION_NDEF_DISCOVERED 意图,声明该意图和你想要过滤的数据类型。下面的例子过滤了 ACTION_NDEF_DISCOVERED 意图和一个text/plain的MIME类型:

<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 of http://developer.android.com/index.html.

下面的例子使用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:mimeType="http"android:host="developer.android.com"android:pathPrefix="/index.html" />
</intent-filter>

ACTION_TECH_DISCOVERED

If your activity filters for the ACTION_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 意图,你就必须创建一个XML资源文件,在一个tech-list集合中声明你的activity支持的技术。如果tech-list集合是标签支持的技术的子集,你的activity就会被当成是一个匹配项,你可以通过调用 Tag.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 集合必须声明所有的这三个,或两个,或其中一个(并且没有别的)来让你的activity匹配该意图。

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文件夹下保存该文件(你可以随意的命名该文件)。

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"><tech-list><tech>android.nfc.tech.IsoDep</tech><tech>android.nfc.tech.NfcA</tech><tech>android.nfc.tech.NfcB</tech><tech>android.nfc.tech.NFcF</tech><tech>android.nfc.tech.NfcV</tech><tech>android.nfc.tech.Nfef</tech><tech>android.nfc.tech.NdefFormatable</tech><tech>android.nfc.tech.MifareClassic</tech><tech>android.nfc.tech.MifareUltralight</tech></tech-list>
</resources>

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 by getTechList(). 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技术或者支持NfcB和Ndef技术的标签的匹配项。

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"><tech-list><tech>android.nfc.tech.NfcA</tech><tech>android.nfc.tech.Ndef</tech></tech-list>
</resources><resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"><tech-list><tech>android.nfc.tech.NfcB</tech><tech>android.nfc.tech.Ndef</tech></tech-list>
</resources>

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>元素,就像下面这个例子:

<activity ...>
...
<intent-filter><action android:name="android.nfc.action.TECH_DISCOVERED" />
</intent-filter><meta-data android:name="android.nfc.action.TECH_DISCOVERED"android:resource="@xml/nfc_tech_filter" />
...
</activity>

For more information about working with tag technologies and the ACTION_TECH_DISCOVERED intent, see Working with Supported Tag Technologies in the Advanced NFC document.

更多关于标签技术的工作原理和 ACTION_TECH_DISCOVERED 意图的信息,参考《高级NFC文档》的“Working with Supported Tag Technologies”。

ACTION_TAG_DISCOVERED

To filter for ACTION_TAG_DISCOVERED use the following intent filter:

使用下面的意图过滤器来过滤 ACTION_TAG_DISCOVERED:

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

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:

  • 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 on ACTION_NDEF_DISCOVERED intents.
  • EXTRA_ID (optional): The low-level ID of the tag.

如果activity由于NFC意图启动了,你可以从该意图中获得扫描到的NFC标签信息。根据扫描到的标签,意图包含如下附加项:

  • EXTRA_TAG(必须的):标签对象代表了扫描到的标签。
  • EXTRA_NDEF_MESSAGES(可选的):NDEF信息数组从标签中被解析出来。该附加项在ACTION_NDEF_DISCOVERED意图中是强制被添加的。
  • 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 the ACTION_NDEF_DISCOVERED intent and gets the NDEF messages from an intent extra.

为了获得这些附加项,查看你的activity启动时是否带有NFC意图以确保有标签被扫描到,然后从该意图中获取额外项。下面的例子检查了ACTION_NDEF_DISCOVERED意图并且从意图的附加项中获取了NDEF信息。

@Override
protected void onNewIntent(Intent intent) {super.onNewIntent(intent);...if (intent != null && NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {Parcelable[] rawMessages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);if (rawMessages != null) {NdefMessage[] messages = new NdefMessage[rawMessages.length];for (int i=0; i<rawMessages.length; i++) {messages[i] = (NdefMessage) rawMessages[i];}//Process the messages array....}}
}

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);

Creating Common Types of NDEF Records

(译:创建NDEF记录通用类型)

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), the createUri() 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.

该章节描述了如何创建NDEF记录的通用类型来帮助你使用Android Beam写入到NFC标签或者发送数据。从Android 4.0(API 等级 14)开始,可以使用 createUri() 方法来帮助你自动创建URI记录。从Android 4.1(API 等级 16)开始,可以使用 createExternal() 和 createMime() 方法来帮助你创建MIME和外部类型的NDEF记录。当手动创建NDEF记录时,尽可能使用这些帮助方法来避免错误。

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记录的例子都必须定义在NDEF信息的第一个NDEF记录中,你可以将它们写入到标签或用来传送。

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]);

ASCII字符集本来就是美国人发明的,前面添加一个“US-”也没什么关系,表示的是同一个字符集。

NdefRecord的构造函数源码如下:

/** ...* @param tnf  a 3-bit TNF constant* @param type byte array, containing zero to 255 bytes, or null* @param id   byte array, containing zero to 255 bytes, or null* @param payload byte array, containing zero to (2 ** 32 - 1) bytes, or null* @throws IllegalArugmentException if a valid record cannot be created*/
public NdefRecord(short tnf, byte[] type, byte[] id, byte[] payload) { ... }

The intent filter for the previous NDEF record would look like this:

上面的NDEF记录的意图过滤器就像这样:

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

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")));

NdefRecord.createMime 函数源码如下:

/** ...* @param mimeType a valid MIME type* @param mimeData MIME data as bytes* @return an NDEF Record containing the MIME-typed data* @throws IllegalArugmentException if the mimeType is empty or invalid*/
public static NdefRecord createMime(String mimeType, byte[] mimeData) { ... }
  • 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:

上面的NDEF记录的意图过滤器就像这样:

<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>

TNF_WELL_KNOWN with RTD_TEXT

You can create a TNF_WELL_KNOWN NDEF record in the following way:

你可以用如下方法创建一个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>

TNF_WELL_KNOWN with RTD_URI

You can create a TNF_WELL_KNOWN NDEF record in the following ways:

你可以使用下面的方式创建一个TNF_WELL_KNOWN 类型的NDEF记录。

  • Using the createUri(String) method:

使用createUri(String)方法:

NdefRecord rtdUriRecord1 = NdefRecord.createUri("http://example.com");
  • Using the createUri(Uri) method:

使用createUri(Uri)方法:

Uri uri = new Uri("http://example.com");
NdefRecord rtdUriRecord2 = NdefRecord.createUri(uri);
  • Creating the NdefRecord manually:

手动创建NdefRecord:

byte[] uriField = "example.com".getBytes(Charset.forName("US-ASCII"));
byte[] payload = new byte[1 + uriField.length]; //add 1 for the URI Prefix
payload[0] = 0x01;  //prefixes http://www. to the URI
System.arraycopy(uriField, 0, payload, 1, uriField.length); //appends URI to payload
NdefRecord rtdUriRecord3 = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI,new byte[0],payload);

注意:官网上在payload[0]前面多加了一个byte(记于 2016-12-28)。

->The intent filter for the previous NDEF records would look like this:
-上面的NDEF记录的意图过滤器就像这样:

<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>

TNF_EXTERNAL_TYPE

You can create a TNF_EXTERNAL_TYPE NDEF record in the following ways:

你可以用如下方式创建一个 TNF_EXTERNAL_TYPE 类型的 NDEF 记录:

  • Using the createExternal() method:
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);

使用 createExternal() 方法:

  • 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:

上面的NDEF记录的意图过滤器就像这样:

<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 a vnd.android.nfc://ext/example.com:externalType URI, which is what the intent filter in the example declares.

注意:TNF_EXTERNAL_TYPE 的 URN(Uniform Resource Name,统一资源名称) 有一个标准的格式:urn: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,这就是例子中声明的意图过滤器。

Android Application Records

(译:Android应用程序记录)

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.

在Android 4.0(API 等级 14)中有介绍,安卓应用程序记录器(AAR)提供了一种更强的确定方式,能让你的应用程序在扫描到NFC标签时启动。AAR将应用程序的包名嵌入到NDEF记录中。你可以将一个AAR添加到你的NDEF信息中的任何一个NDEF记录中,因为Android会搜索整个NDEF信息来寻找AARs。如果它发现一个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.

如果你想要防止其它应用程序过滤相同的意图和可能处理你开发的指定标签,此时AARs就会对你有所帮助。AARs仅提供应用程序级别的支持,因为包名的约束,而不是Activity级别针对意图过滤器的。如果你想要以Activity级别来处理意图,请使用意图过滤器。

If a tag contains an AAR, the tag dispatch system dispatches in the following manner:

  1. Try to start an Activity using an intent filter as normal. If the Activity that matches the intent also matches the AAR, start the Activity.
  2. If the Activity that filters for the intent does not match the AAR, if multiple Activities can handle the intent, or if no Activity handles the intent, start the application specified by the AAR.
  3. If no application can start with the AAR, go to Google Play to download the application based on the AAR.

如果一个标签包含AAR,标签调度系统就会按如下方式来分发:

  1. 使用意图过滤器来正常的启动一个Activity。如果Activity符合该意图,也符合AAR,就启动该Activity。
  2. 如果Activity过滤了改意图但是不匹配该AAR,如果多个Activities可以处理该意图,或者没有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.

注意:你可以用前台调度系统来覆盖AARs和意图调度系统,它允许当NFC标签被发现时某一个前台的activity具有相应的权限。使用该方法,activity必须在前台以覆盖AARs和意图调度系统。

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,你通常可以声明意图过滤器。如果你的应用对其它不包含AAR的标签感兴趣的话,这是非常有用的。例如,你可能想保证你的应用处理你开发的专有标签以及第三方部署的简单标签。记住AAR在Android 4.0或者之后的设备才能指定,因此当开发标签时,你最有可能希望结合AARs和MIME类型/URIs来支持最广泛的设备。另外,当你开发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 your NdefMessage, 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 提供了一个简单的API来创建AAR,createApplicationRecord().你所需要做的只是将AAR嵌入到你的NdefMessage中。你可能不想使用你的NdefMessage中的第一个记录,除非NdefMessage中就只有AAR记录。这是因为Android系统会校验NdefMessage中的第一个记录来决定标签的MIME类型或URI,它会用来创建一个能被应用程序过滤的意图。下面的代码向你展示了如何创建一个AAR:

NdefMessage msg = NdefMessage(new NdefRecord[] {...,NdefRecord.createApplicationRecord("com.example.android.beam");});

Beaming NDEF Messages to Other Devices

(译:将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设备之间简单的点到点的数据交换。想要传输数据到其它设备的应用程序必须在前台,并且接收数据的设备不能被锁。当发送数据的设备与接收数据的设备靠的足够近时,用于发送数据的设备上回显示“触摸开始传输”的UI(User Interface,用户界面)。然后用户可以选择是否要发送信息给接收的设备。

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. See enableForegroundNdefPush() for more information.

注意:前台的NDEF推送只有在API 等级 10 才能用,它提供了与Android Beam 相似的功能。这些API 已经过时,但却为旧的设备提供支持。参阅enableForegroundNdefPush() 来获取更多相关信息。

You can enable Android Beam for your application by calling one of the two methods:

  • setNdefPushMessage(): Accepts an NdefMessage to set as the message to beam. Automatically beams the message when two devices are in close enough proximity.
  • setNdefPushMessageCallback(): Accepts a callback that contains a createNdefMessage() which is called when a device is in range to beam data to. The callback lets you create the NDEF message only when necessary.

你的应用程序可以通过调用一个或两个方法来启动Android Beam。

  • setNdefPushMessage():接受一个NdefMessage,并将其设置为传输信息。当两设备靠的足够近时会自动传输该信息。
  • 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:

  • The activity that is beaming the data must be in the foreground. Both devices must have their screens unlocked.
  • You must encapsulate the data that you are beaming in an NdefMessage object.
  • The NFC device that is receiving the beamed data must support the com.android.npp NDEF push protocol or NFC Forum’s SNEP (Simple NDEF Exchange Protocol). The com.android.npp protocol is required for devices on API level 9 (Android 2.3) to API level 13 (Android 3.2). com.android.npp and SNEP are both required on API level 14 (Android 4.0) and later.

一个activity可以每次只推送一个NDEF信息,因此如果两者都设置的话,setNdefPushMessageCallback() 比 setNdefPushMessage() 具有更高的优先权。要想使用Android Beam,就必须遵循下列的通用准则:

  • 要发送数据的activity必须在前台。两设备的屏幕都不能锁。
  • 你必须将你要发送的数据封装到NdefMessage对象中。
  • 接收发送的数据的NFC设备必须支持com.android.npp类型的NDEF推送协议或NFC论坛的SNEP(Simple NDEF Exchange Protocol,简单NDEF传输协议)。对于API等级在9(Android 2.3)到13(Android 3.2)之间的设备需要com.android.npp 协议。API等级在14(Android 4.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,并且它在前台,标准的意图调度系统就会被禁用。然而,如果你的activity也启用了前台调度,那么它就依然可以扫描那些符合在前端调度中定义的意图过滤器的标签。

To enable Android Beam:

  1. Create an NdefMessage that contains the NdefRecords that you want to push onto the other device.
  2. Call setNdefPushMessage() with a NdefMessage or call setNdefPushMessageCallback passing in a NfcAdapter.CreateNdefMessageCallback object in the onCreate() method of your activity. These methods require at least one activity that you want to enable with Android Beam, along with an optional list of other activities to activate.

In general, you normally use setNdefPushMessage() if your Activity only needs to push the same NDEF message at all times, when two devices are in range to communicate. You use setNdefPushMessageCallback when your application cares about the current context of the application and wants to push an NDEF message depending on what the user is doing in your application.

启用Android Beam:

  1. 创建一个包含你想要推送到其它设备的NdefRecords的NdefMessage。
  2. 调用一个带NdefMessage参数的setNdefPushMessage()或者在你的activity的onCreate()方法中通过NfcAdapter.CreateNdefMessageCallback对象调用setNdefPushMessageCallback。这些方法需要至少一个你想要用来启用Android Beam的activity,带着一个可选的待激活的其它activities列表。

通常情况下,当两设备在可通讯的范围内时,如果你的Activity每次只需要推送相同的NDEF信息,一般会使用setNdefPushMessage()。当你的应用程序关心当前的上下文并且想要根据用户在应用程序上的操作来推送NDEF信息时,使用setNdefPushMessageCallback。

The following sample shows how a simple activity calls NfcAdapter.CreateNdefMessageCallback in the onCreate() method of an activity (see AndroidBeamDemo for the complete sample). This example also has methods to help you create a MIME record:

下面的例子演示了一个简单的activity(查看AndroidBeamDemo来获取完整的用例)在onCreate()方法中,如何调用NfcAdapter.CreateNdefMessageCallback。这个简单的例子也有一些方法来帮助你创建一个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;public class Beam extends Activity implements CreateNdefMessageCallback {NfcAdapter mNfcAdapter;TextView textView;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);TextView textView = (TextView) findViewById(R.id.textView);// Check for available NFC AdaptermNfcAdapter = NfcAdapter.getDefaultAdapter(this);if (mNfcAdapter == null) {Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();finish();return;}// Register callbackmNfcAdapter.setNdefPushMessageCallback(this, this);}@Overridepublic void onResume() {super.onResume();// Check to see that the Activity started due to an Android Beamif (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {processIntent(getIntent());}}@Overridepublic void onNewIntent(Intent intent) {// onResume gets called after this to handle the intentsetIntent(intent);}@Overridepublic NdefMessage createNdefMessage(NfcEvent event) {String text = ("Beam me up, Android!\n\nBeam Time: " + System.currentTimeMillis());NdefMessage msg = new NdefMessage(new NdefRecord[] { 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;}/*** 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 beamNdefMessage msg = (NdefMessage) rawMsgs[0];// record 0 contains the MIME type, record 1 is the AAR, if presenttextView.setText(new String(msg.getRecords()[0].getPayload()));}
}

createMime(String)方法见TNF_MIME_MEDIA,总共有2种

public NdefRecord createMime(String mime, byte[] data) {return NdefRecord.createMime(mime, data);
}

public NdefRecord createMime(String mime) {return new NdefRecord(NdefRecord.TNF_MIME_MEDIA,mime.getBytes(Charset.forName("US-ASCII")),new byte[0], data));
}

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的话,在Android 4.0或之后的设备上,下面的意图过滤器在技术上是不必要的。

<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.

使用该过滤器,当扫描到一个NFC标签或者接收到一个AAR类型为com.example.android.beam的Android Beamm或者NDEF格式的信息包含一个application/vnd.com.example.android.beam类型的MIME记录时,包名为com.example.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. See Creating Common Types of NDEF records for more information on how to create records.

即使AARs保证了应用程序会被启动或下载,意图过滤器也被推荐使用,因为他们可以让你启动你选中的应用程序中的某个Activity而不是启动AAR中指定的包名的MainActivity。AARs没有Activity级别的粒度。并且,因为某些Android设备不支持AARs,你同时应该在你的NDEF信息的第一个NDEF记录中嵌入标识信息,并且也过滤它以防万一。参阅“Creating Common Types of NDEF records”来获取更多关于如何创建记录的方法。

Android NFC Basics相关推荐

  1. NFC Basics(基本NFC)——翻译自developer.android.com

    NFC Basics 关于收发NDEF格式的消息,以及相关的api. 非NDEFdata以及其它更深入技术请參见Advanced NFC. 在android端使用NDEF有两种情况: - 从标签读取N ...

  2. Android NFC开发实战详解

    Android NFC开发实战详解 Android开发实战详解NFC国内第一本AndroidNFC开发书籍带你开启AndroidNFC开发的神秘之旅大综合案例帮助读者快速进入实战角色:WiFi快速连接 ...

  3. Android NFC 开发实例

    http://blog.csdn.net/pku_android/article/details/7430788 类: Android应用开发系列教程 Android应用开发技巧2012-04-06 ...

  4. c语言读写nfc,Android NFC M1卡读写芯片卡读写(CPU卡读写)(RFID读写)

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/sgn5200/article/deta ...

  5. android nfc(一)

    2019独角兽企业重金招聘Python工程师标准>>> 转载自 http://blog.sina.com.cn/s/blog_67d95f4001011uiv.html 啥是NFC你 ...

  6. Android NFC开发

    由于工作关系,需要做智能卡(JavaCard Applet)和Android NFC方面的开发. NFC主要有3种模式:读卡器模式, 卡模拟模式, 点到点模式. 本文主要参考了Android官方Car ...

  7. Android NFC读取电子标签

    2019独角兽企业重金招聘Python工程师标准>>> NFC,什么是NFC?想必大家都听过,就是近场通信,接下来我想给大家展示一个简单的demo, 这个demo是我在公司工作中开发 ...

  8. android nfc ndef mifareclassic,Android NFC开发-实践篇

    Android NFC开发-实践篇 https://blog..net/_GYG/article/details/72899417 在Android NFC开发-理论篇中,我们了解了在Android中 ...

  9. Android NFC开发-实践篇

    Android NFC开发-实践篇 在Android NFC开发-理论篇中,我们了解了在Android中开发NFC的一些理论知识,这篇我们继续应用我们上一篇学到的知识,实现对NDEF格式标签和Mifa ...

最新文章

  1. centos7下ip转发的配置
  2. php一点通,编程一点通app-编程一点通官方版下载v1.0.1-七度网
  3. Vue+ElementUI+SpringMVC实现图片上传和回显
  4. 安装与设置Visual SVN
  5. iar编译工程的map怎么看使用flash大小_ESP8266_08基于flash的数据掉电保护
  6. openEuler 高校开发者大赛报名启动!广阔天地,码出不凡
  7. SPSS多元线性回归及逐步回归学习笔记
  8. 《华为基本法》读书笔记
  9. FIR versus IIR Butterworth Chebyshev Bessel Filter
  10. 微信怎么关闭微信朋友圈及点赞提醒通知?
  11. Balanced Sequence
  12. .NET 高级架构师0003 架构师之路(2)---架构师的职责
  13. 《通关!游戏设计之道》给游戏编个故事
  14. Unity PC打包后日志查看
  15. 值得感谢的10位顶级游戏制作人
  16. USB摄像头测试网址
  17. 好用的街机模拟器-WinKawaks提供下载
  18. Linux_Wget
  19. 【java之汉字转拼音】
  20. 盖茨基金会:全球至少要到2108年才能实现性别平等,比期望晚了三代人 | 美通社头条...

热门文章

  1. 搜狗浏览器的8点个人体会
  2. delphi mysql 图片_Delphi实现在数据库中存取图像
  3. 分享一道算法面试题和它的三种解法
  4. 计算机二维辅助设计课程设计的目的,计算机辅助设计(园林专业)教案12-13-1.doc...
  5. [全程建模]《软件工程之全程建模实现》第二版精装封面
  6. linux远程无法连接能ping通,能ping通服务器,但是不能ssh远程登录为什么?
  7. 启用apache,发现80端口被占用【已解决】
  8. C++特性nullptr
  9. linux最新分区方案,中移互联网java开发面经
  10. 玩转 RTC时钟库 DS3231