Android API Guides---NFC Basics

本文档介绍了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)的活动,直到意图或直至标签调度系统中的应用程序过滤器尝试所有可能的目的。

如果没有应用程序筛选任何意图的,什么也不做。


Android API Guides---NFC Basics_第1张图片

只要有可能,以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,使其更容易为应用程序来区分做到这一点。


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记录的常见类型。

你可能感兴趣的:(java,android,api,sdk,NFC,basics)