本文档介绍了Android中运行基本任务NFC。

它说明了怎样在NDEF消息的形式发送和接收数据的NFC并介绍了支持这些功能的Andr​​oid框架的API。

对于更高级的主题。包含与非NDEF数据工作的讨论。请參阅高级NFC。




没有与NDEF数据和Android时两个主要用例:


从NFC标签读取NDEF数据
从一台设备喜气洋洋NDEF消息到还有一个通过Android Beam™
从NFC标签读取NDEF数据与标签调度系统,当中分析发现NFC标签处理,适当地进行分类的数据,并启动一个应用程序。是感兴趣的分类数据。想要来处理扫描NFC标签的应用程序能够声明意图过滤器,并要求来处理数据。




而Android梁™功能同意设备通过物理窃听设备一起推的NDEF消息到还有一个设备。这样的互动提供了发送比其他无线技术,如蓝牙数据更简单的方法。由于NFC,无需手动装置发现或配对。当两个设备进入通信范围内的连接会自己主动启动。 Android Beam功能可通过一组NFC的API,所以不论什么应用都能够传输设备之间的信息。

比如。联系人。浏览器和YouTube应用程序使用Android Beam的共享联系人,网页,并与其他设备的视频。


标签调度系统


Android设备一般是寻找NFC标签的时候。屏幕解锁。除非NFC在设备的设置菜单禁用。当一个Android设备发现一个NFC标签,期望的行为是有最合适的处理活动的意图不问使用什么应用程序的用户。因为设备在非常短的范围扫描NFC标签,非常可能使用户手动选择的活动将迫使他们移动设备从标签路程,断开连接。你应该开发自己的活动,仅仅处理了您的活动在乎防止活动选配出现的NFC标签。


为了帮助您完毕这个目标。Android提供了一个特殊的标签调度系统,能够分析扫描NFC标签,解析它们。并试图找到感兴趣的扫描数据的应用程序。

它通过:


解析NFC标签和搞清楚MIME类型或一个URI标识代码中的数据有效载荷。
封装MIME类型或URI和有效载荷送入意图。

前两个步骤怎么NFC标签被映射到MIME类型和URI描写叙述。


開始基于所述意图的活性。这是在如​​何NFC标签被分派到应用程序描写叙述。
怎样NFC标签被映射到MIME类型和URI


你開始写你的NFC应用之前。必须了解不同类型的NFC标签是非常重要的,标签调度系统怎样解析NFC标签和特殊的工作,当它检測到NDEF消息的标记调度系统一样。 NFC标签来在广泛的技术和还能够有很多不同的方式写入到当中的数据。机器人具实用于NDEF标准,它是由NFC论坛所定义的最支持。


NDEF数据被封装的消息(NdefMessage),当中包括一个或多个记录(NdefRecord)的内部。

每一个NDEF记录必须依据您要创建的记录类型的规格良好的。 Android版还支持其它类型的标签不包括NDEF的数据,你能够通过在android.nfc.tech包中的类工作。要了解很多其它有关这些技术。请參见高级NFC主题。

这些其它类型的标签工作包括编写你自己的协议栈与标签进行通信,因此,我们建议使用NDEF在可能的情况。便于开发和最大支持Android的供电设备。


注意:要下载完整NDEF的规格,去NFC论坛规范下载站点,看看怎样构建NDEF记录的样例创建常见类型的NDEF记录。




如今。你有NFC标签的背景,以下的章节具体描写叙述了Android的怎样处理NDEF格式化的标签。当一个Android设备扫描包括NDEF格式的数据的NFC标签。它解析该消息并试图找出数据的MIME类型或标识的URI。要做到这一点。系统读取NdefMessage内的第一NdefRecord以确定怎样解释整个NDEF消息(一个NDEF消息能够有多个NDEF记录)。

在一个结构良好的NDEF消息,第一NdefRecord包括以下字段:


3位肿瘤坏死因子(类型名称格式)
指示怎样解释可变长度类型字段。有效值在表1中描写叙述了描写叙述。


可变长度类型
描写叙述了记录的类型。假设使用TNF_WELL_KNOWN。使用此字段指定记录类型定义(RTD)。

有效RTD值在表2中描写叙述。


可变长度ID
的唯一标识备案。此字段不常常使用。但假设您须要唯一标识标签,你能够为它创建一个ID。
可变长度的有效载荷
要读取或写入的实际数据的有效载荷。一个NDEF消息能够包括多个NDEF记录,所以不承担所有有效载荷在NDEF消息的第一NDEF纪录。


标签调度系统使用肿瘤坏死因子和类型字段来尝试映射MIME类型或URI的NDEF消息。假设成功,它封装与实际载荷沿ACTION_NDEF_DISCOVERED意图的内部信息。

只是。也有当标签调度系统不能确定数据的基础上,第一个NDEF记录中的类型的情况。这样的情况发生在NDEF数据不能被映射到一个MIME类型或URI。或当NFC标签不包括NDEF数据開始。在这样的情况下。具有关于标签的技术和有效载荷信息,标签对象封装一个ACTION_TECH_DISCOVERED意图,而不是内部。


表1描写叙述了标签调度系统怎样TNF和类型字段映射到MIME类型或URI的。

它也描写叙述了TNFs不能被映射到一个MIME类型或URI。

在这些情况下。标签调度系统回落到ACTION_TECH_DISCOVERED。


比如,假设标签调度系统遇到类型TNF_ABSOLUTE_URI的记录,它映射该记录到URI的可变长度类型字段。标签调度系统封装该URI在ACTION_NDEF_DISCOVERED意图的数据字段有关的标签的其它信息,比如有效载荷沿。在还有一方面,假设遇到类型TNF_UNKNOWN的记录,它会创建一个封装标签的技术,而不是意图。


表1.支持TNFs及其映射
类型名称格式(TNF)映射
基于该类型字段TNF_ABSOLUTE_URI URI。


TNF_EMPTY回落到ACTION_TECH_DISCOVERED。
基于类型字段瓮TNF_EXTERNAL_TYPE URI。骨灰盒被编码到NDEF类型字段的缩写形式:<域名>:<服务>。 Android在形式映射给URI:vnd.android.nfc:// EXT / <域名>:<服务>。


基于该类型字段TNF_MIME_MEDIA MIME类型。


第一条记录TNF_UNCHANGED无效的。所以回落到ACTION_TECH_DISCOVERED。
TNF_UNKNOWN回落到ACTION_TECH_DISCOVERED。
TNF_WELL_KNOWN MIME类型或URI取决于记录类型定义(RTD),您在类型字段设置。见表2.可用的RTD及其映射的很多其它信息。
为TNF_WELL_KNOWN及其映射表2.受支持的RTD
记录类型定义(RTD)映射
RTD_ALTERNATIVE_CARRIER回落到ACTION_TECH_DISCOVERED。


RTD_HANDOVER_CARRIER回落到ACTION_TECH_DISCOVERED。


RTD_HANDOVER_REQUEST回落到ACTION_TECH_DISCOVERED。


RTD_HANDOVER_SELECT回落到ACTION_TECH_DISCOVERED。


基于解析有效载荷RTD_SMART_POSTER URI。
RTD_TEXT MIME类型的文本/平原。
基于有效载荷RTD_URI URI。


怎样NFC标签被分派到应用程序


当标签调度系统做创建封装NFC标签和识别信息的意图。它发出的意图。对于意图过滤感兴趣的应用程序。假设有多个应用程序能够处理的意图。提出活动选配,以便用户能够选择的活动。标签调度系统定义了三个意图,这是在最高的顺序列出来最低优先级:


ACTION_NDEF_DISCOVERED:此意图是用来启动一个活动时,它包括一个NDEF净荷标签的扫描和是一个公认的类型。这是最高优先级的意图,而且标签调度系统尝试尽可能不论什么其它意图,之前启动这一意图的活动。
ACTION_TECH_DISCOVERED:假设没有活动登记办理ACTION_NDEF_DISCOVERED意图,标签调度系统试图启动与此意向的应用程序。此意向也直接启动(不启动ACTION_NDEF_DISCOVERED第一),假设被扫描的标签包括无法映射到MIME类型或URI NDEF数据,或者假设标签不包括NDEF数据,可是是一个已知的标签技术。
ACTION_TAG_DISCOVERED:假设没有活动处理ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED意图这意图開始。
标签调度系统工作的基本方法例如以下:


尝试启动与由标签调度系统解析NFC标签(不管是ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED)时创建的意图的活动。
假设这一意图没有活动过滤器,尝试启动下一个优先级最低的意图(不管是ACTION_TECH_DISCOVERED或ACTION_TAG_DISCOVERED)的活动,直到意图或直至标签调度系统中的应用程序过滤器尝试全部可能的目的。

假设没有应用程序筛选不论什么意图的,什么也不做。



仅仅要有可能,以NDEF消息和ACTION_NDEF_DISCOVERED意图工作,由于它是最特定出的三个。

此意向。您能够在比其它两个意图更适当的时间启动应用程序,给用户更好的体验。


请求在Android清单NFC訪问


在能够訪问设备的NFC硬件。妥善处理NFC意图,声明在AndroidManifest.xml文件下面项目:


该NFC<使用许可权>元素訪问NFC硬件:

<uses-permission android:name="android.permission.NFC" />
最低SDK版本号。你的应用程序能够支持。 API级9仅仅支持通过ACTION_TAG_DISCOVERED有限标签调度。并仅仅给出了通过额外的NDEF邮件中多余的訪问NDEF消息。没有其它标签属性或I / O操作都能够訪问。 API级别10包含全面的读/写支持,以及前景NDEF推搡,和API级14提供了一个更简单的方法来推动NDEF消息,Android Beam功能和额外的便利方法的其它设备来创建NDEF记录。


<uses-sdk android:minSdkVersion="10"/>
用途特征元素所以仅仅有您的应用程序在谷歌显示出来玩的有NFC硬件设备:

<uses-feature android:name="android.hardware.nfc" android:required="true" />
假设应用程序使用NFC功能,但该功能是不是你的应用是至关重要的,你能够省略的用途,特征元素,并检查是否getDefaultAdapter()是空在执行时检查NFC avalailbility。
滤波NFC意图
当你要处理的NFC标签被扫描启动应用程序,应用程序能够过滤一,二。或在Android清单全部三个NFC意图的。

可是。你通常要过滤为您的应用程序启动时的最大控制ACTION_NDEF_DISCOVERED意图。该ACTION_TECH_DISCOVERED目的是ACTION_NDEF_DISCOVERED回退时ACTION_NDEF_DISCOVERED或没有应用程序过滤器时。有效载荷不NDEF。

滤波ACTION_TAG_DISCOVERED通常过于笼统的类别进行过滤的。很多应用程序将用于ACTION_NDEF_DISCOVERED或行动TECH_DISCOVERED过滤ACTION_TAG_DISCOVERED之前。让您的应用程序启动的概率非常低。 ACTION_TAG_DISCOVERED仅作为应用程序的最后手段在没有其它应用程序安装处理ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVEREDintent的情况下进行过滤。
由于NFC标签部署各不同样。是不是你的控制之下了非常多次。这并不总是可能的,这就是为什么你能够在必要时回退到其它两个意图。当你有过的类型标签和写入的数据控制。建议您使用NDEF格式化您的代码。以下的章节描写叙述了怎样为每种类型的意图进行筛选。
ACTION_NDEF_DISCOVERED
若要筛选ACTION_NDEF_DISCOVERED意图,与您要筛选的数据类型以及声明的意图过滤器。

对于ACTION_NDEF_DISCOVERED意图用MIME类型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>
以下的样例在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>
ACTION TECH_DISCOVERED
假设在你的行动活动的过滤TECH_DISCOVERED意图,你必须创建一个指定的活动支持高科技列表集内的技术的XML资源文件。

您的活动被觉得是一个匹配,假设高科技列表集是由标签支持的技术,它能够通过调用getTechList获得()的一个子集。
比如,假设被扫描的标签支持MifareClassic,NdefFormatable和NFCA,你的技术列表设置必须按顺序指定全部三。二,或技术(没有别的)之中的一个进行匹配您的活动。


以下的演示样例定义了全部的技术。您能够删除不须要的人。

保存该文件(你能够将其命名为不论什么你愿意的话)在<项目根文件夹>/ RES / XML的文件夹中。


<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.IsoDep</tech>
        <tech>android.nfc.tech.NfcA</tech>
        <tech>android.nfc.tech.NfcB</tech>
        <tech>android.nfc.tech.NfcF</tech>
        <tech>android.nfc.tech.NfcV</tech>
        <tech>android.nfc.tech.Ndef</tech>
        <tech>android.nfc.tech.NdefFormatable</tech>
        <tech>android.nfc.tech.MifareClassic</tech>
        <tech>android.nfc.tech.MifareUltralight</tech>
    </tech-list>
</resources>
您也能够指定多个高科技列表集。每一个高科技列表套独立考虑。你的行为被觉得是一个比赛,假设不论什么一个高科技列表集是由getTechList()返回的技术的一个子集。

这提供AND和OR语义匹配技术。以下的样例相匹配。能够支持NFCA和NDEF技术或能够支持NFC和NDEF技术代码:

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

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.NfcB</tech>
        <tech>android.nfc.tech.Ndef</tech>
    </tech-list>
</resources>
在AndroidManifest.xml文件指定<活动>元素中就像在以下的样例中的元素。你仅仅是在<元数据>创建的资源文件:

<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>
有关与标签技术和动作TECH_DISCOVERED意图,请參阅使用高级NFC文件里支持的标签技术的很多其它信息。
ACTION_TAG_DISCOVERED
为了筛选ACTION_TAG_DISCOVERED使用下面意图过滤器

<intent-filter>
    <action android:name="android.nfc.action.TAG_DISCOVERED"/>
</intent-filter>
从意向获取信息


假设活动開始。由于NFC的意图,能够获取有关从意图扫描NFC标签的信息。意图能够包括取决于被扫描标签以下的演员:


EXTRA_TAG(必需):代表扫描标签的标签对象。
EXTRA_NDEF_MESSAGES(可选):从标签解析NDEF消息的数组。这个额外是ACTION_NDEF_DISCOVERED意图强制性的。
EXTRA_ID(可选):标签的低级别的ID。


要获得这些额外检查,看看你的活力与NFC意图之中的一个推出,以确保标签被扫描,然后获得额外出来的意图。对于ACTION_NDEF_DISCOVERED意图以下的样例检查。并会从一个意图额外的NDEF消息。

public void onResume() {
    super.onResume();
    ...
    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
        Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
        if (rawMsgs != null) {
            msgs = new NdefMessage[rawMsgs.length];
            for (int i = 0; i < rawMsgs.length; i++) {
                msgs[i] = (NdefMessage) rawMsgs[i];
            }
        }
    }
    //process the msgs array
}
另外。您也能够从意向。当中将包括有效载荷。并同意您列举标记的技术的Tag对象:

Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
创建NDEF记录的常见类型
本节将介绍怎样创建常见类型的NDEF记录。以帮助您写入NFC标签或Android Beam功能发送数据时。採用Android4.0(API等级14),该createUri()方法能够帮助你自己主动创建URI记录開始。

在搭载Android 4.1(API等级16),createExternal()和createMime()启动可帮助您创建MIME和外置型NDEF记录。使用这些辅助方法尽可能避免失误手动创建NDEF记录时。


本节还介绍了怎样创建备案对应的意图过滤器。全部这些NDEF记录的样例应该是你正在写标签或喜气洋洋的NDEF消息的第一NDEF纪录。


BUILD_ABSOLUTE_URI
注意:我们建议您使用RTD_URI类型。而不是TNF_ABSOLUTE_URI。由于它是更有效的。
您能够在下面方式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]);
前一个NDEF记录的意图过滤器是这种:

<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>
TNF MIME媒体
您能够在通过下面方式TNF MIME媒体NDEF记录:
使用createMime()方法:

NdefRecord mimeRecord = NdefRecord.createMime("application/vnd.com.example.android.beam",
    "Beam me up, Android".getBytes(Charset.forName("US-ASCII")));
手动创建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")));
前一个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与RTD_TEXT
您能够在下面方式TNF众所周知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; }

意图过滤器是这种:

<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与RTD_URI
您能够在通过下面方式TNF众所周知NDEF记录:

使用createUri(String)方法:

NdefRecord rtdUriRecord1 = NdefRecord.createUri("http://example.com");
使用创建的URI(URI)的方法:

Uri uri = new Uri("http://example.com");
NdefRecord rtdUriRecord2 = NdefRecord.createUri(uri);
手动创建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;                                      //prefixes http://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);
前一个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
您能够在通过下面方式TNF外置式NDEF记录:
使用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);
手动创建NdefRecord:

byte[] payload;
...
NdefRecord extRecord = new NdefRecord(
    NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType", new byte[0], payload);
前一个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>
使用很多其它通用的NFC标签部署TNF_EXTERNAL_TYPE,以更好地支持Android的供电和非Android设备。


注:TNF_EXTERNAL_TYPE的URN有一个规范的格式:金塔:NFC:分机:example.com:externalType,可是NFC论坛RTD规范声明金塔:N​​FC:EXT:瓮的部分必须从NDEF记录中ommitted。因此。全部你须要提供是用冒号隔开(在本例中example.com)域和类型(externalType中的样例)。 NFC:分机:example.com:当调度TNF_EXTERNAL_TYPE,Android的骨灰盒转换externalType URN到vnd.android.nfc://ext/example.com:externalType URI,这是在这个样例的意图过滤器声明。


Android应用程序记录


在Android 4.0的(API级别14)推出一个Android应用程序记录(AAR)提供了一个更强的确定性。当一个NFC标签被扫描应用程序已启动。一个AAR具有内嵌在NDEF记录中的应用程序的包名。您能够加入一个AAR您NDEF消息的不论什么NDEF纪录。由于Android的搜索整个NDEF消息AARS。

假设找到一个AAR。它開始基础上,AAR内的包名的应用程序。假设应用程序是不存在的设备上,谷歌播放启动下载应用程序。


假设你想防止其它应用程序过滤同样的意图和潜在的处理已部署特定的标签奥尔斯是实用的。奥尔斯仅仅支持在应用层面。由于包名的约束,而不是在活动水平意图过滤。

假设你想在活动层次来处理意图,使用意图过滤器。


假设一个标签包括一个AAR。标签调度系统调度的方式例如以下:


尝试使用一个意图过滤器正常启动的活动。假设意图相匹配的活动的AAR也匹配。启动活动。
假设,对于意图不匹配AAR过滤活动,假设多个活动能够处理的意图。或者假设没有活动处理的意图,启动由AAR的指定的应用程序。
假设没有应用程序能够与AAR開始。去谷歌Play下载基于AAR的应用程序。


注意:您能够覆盖AARS和前景调度系统,它同意当一个NFC标签被发现前景活动具有优先权的意图调度系统。用这样的方法,活动必须在前台覆盖AARS和意图调度系统。


假设您仍然要筛选不包括AAR扫描标签,你能够正常声明意图过滤器。假设您的应用程序感兴趣的是不包括AAR等标签,这很实用。

比如。或许你要保证你的应用程序处理您部署专用标记以及由第三方部署的一般标签。请记住,奥尔斯详细到Android 4.0设备或更高版本号。所以在部署时的标签,你最有可能要使用奥尔斯和MIME类型/的URI的组合,支持设备的范围最广。此外。当您部署NFC标签,想想你想怎么写你的NFC标签。以便在大多数设备(Android平台和其它设备)的支持。您能够通过定义一个相对独特的MIME类型或URI,使其更easy为应用程序来区分做到这一点。




Android提供了一个简单的API来创建一个AAR,createApplicationRecord()。全部你须要做的是在你随时随地NdefMessage嵌入AAR。你不想用你的NdefMessage的第一个记录,除非AAR是在NdefMessage的唯一记录。

这是由于Android系统检查的NdefMessage的第一条记录。从而确定标签。这是用于创建应用程序过滤意图的MIME类型或URI。以下的代码演示怎样创建一个AAR:

NdefMessage msg = new NdefMessage(
        new NdefRecord[] {
            ...,
            NdefRecord.createApplicationRecord("com.example.android.beam")}
喜气洋洋NDEF消息给其他设备


Android Beam功能同意两款Android供电设备之间的简单对等网络的数据交换。一个想要束数据到还有一设备的应用程序必须是在前台和设备收到该数据不能被锁定。当喜气洋洋设备自带与接收设备足够近的接触。灿烂的设备显示“触摸到梁”UI。然后。用户能够选择是否要光束的消息到接收装置。




注:前台NDEF推是可在API级别10,它提供了类似的功能用于Android Beam。

这些API有不被提倡,但可用于支持老设备。

有关很多其它信息,请參见enableForegroundNdefPush()。


您能够通过调用两种方法之中的一个启用Android Beam功能为您的应用:


setNdefPushMessage():接受一个NdefMessage设置作为消息到光束。自己主动光束当两个设备都足够接近该消息。
setNdefPushMessageCallback():接受包括createNdefMessage()当设备处于范围束数据到被调用的回调。回调可让您仅仅创建NDEF消息。假设必要。
活动仅能够一次推1 NDEF消息,所以setNdefPushMessageCallback()优先于setNdefPushMessage()假设两者都设置。

要使用Android Beam功能。以下的一般准则必须满足:


这喜气洋洋的数据的行为必须是在前台。这两款器件必须有自己的屏幕解锁。
你必须封装您在NdefMessage对象喜气洋洋的数据。


正在接收横梁数据必须支持com.android.npp NDEF推送协议或NFC论坛的SNEP(简单NDEF交换协议)NFC设备。该com.android.npp协议须要在API 9级设备(Android 2.3的)到API等级13(Android 3.2的)。 com.android.npp和SNEP都须要在API级别14(Android 4.0版本号)及更高版本号。


注意:假设您的活动使Android Beam功能。并在前台,标准的意图调度系统被禁用。

可是,假设你的活动也使前景调度,那么它仍然能够扫描匹配在前台调度设置意图过滤器标签。


要启用Android Beam功能:


创建包括要推到其它设备NdefRecords的NdefMessage。
呼叫setNdefPushMessage()与NdefMessage或致电setNdefPushMessageCallback传递一个NfcAdapter.CreateNdefMessageCallback对象在活动的onCreate()方法。

这些方法要求要启用Android Beam功能,与其它活动的可选列表。以激活沿至少一个活动。
普通情况下,通常使用setNdefPushMessage(),假设你的活动仅仅须要在不论什么时候都推同样NDEF消息。当两个设备在范围内进行通信。

您能够使用setNdefPushMessageCallback当你的应用程序关心应用程序的当前上下文,并希望推动这取决于用户在应用程序中做一个NDEF消息。
以下的演示样例显示了一个简单的活动在活动的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;


public class Beam extends Activity implements CreateNdefMessageCallback {
    NfcAdapter mNfcAdapter;
    TextView textView;

    @Override
    public void 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
    public NdefMessage createNdefMessage(NfcEvent event) {
        String text = ("Beam me up, Android!\n\n" +
                "Beam 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;
    }

    @Override
    public void 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
    public void 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(new String(msg.getRecords()[0].getPayload()));
    }
}
请注意。此代码凝视出一个AAR。你能够删除。

假设启用了AIR。在AAR指定的应用程序总是收到Android Beam的消息。假设应用程序不存在,谷歌播放開始下载应用程序。

因此,假设使用的AAR下面意图过滤器是不适合的Android4.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>
有了这个意图过滤器中,com.example.android.beam应用程序如今能够在扫描NFC标签或接收到的Android梁式com.example.android.beam的AAR,或当NDEF格式的消息包括一个開始类型应用程序/ vnd.com.example.android.beam的MIME纪录。




即使AARS保证应用程序启动或下载,推荐意图过滤器,由于他们让你在你的应用程序启动您所选择的活动。而不是总是在启动由AAR指定的包内的主要活动。

AARS没有活动水平的粒度。

同一时候。由于一些Android设备不支持奥尔斯。你也应该嵌入识别您的NDEF消息的第一NDEF记录和过滤器的信息,以及,以防万一。

请參阅有关怎样创建记录的具体信息创建的NDEF记录的常见类型。