码迷,mamicode.com
首页 > 其他好文 > 详细

Google NFC Basics (谷歌官网NFC翻译)

时间:2015-06-02 18:09:17      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:android

原文地址:http://developer.android.com/guide/topics/connectivity/nfc/nfc.html  



NFC Basics

本文档介绍了Android中执行基本任务NFC。它说明了如何发送和接收数据的NFC在NDEF消息的形式,并介绍了支持这些功能的Andr??oid框架的API。
对于更高级的话题,包括与非NDEF数据工作的讨论,请参阅高级NFC。

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


[PS: NFC数据交换格式,NFC组织约定的NFC tag中的数据格式。 NDEF这是google参考nfc论坛而提出和支持的格式,

他是轻量级的紧凑的二进制格式,可带有URL、vCard和NFC定义的各种数据类型]


1.从NFC标签读取NDEF数据

2.发送NDEF消息从一个设备到另一个设备,通过Android Beam?方式

从NFC标签读取NDEF数据与标签调度系统,其中分析发现NFC标签处理,适当地进行分类的数据,
并启动一个应用程序,他是一种有趣的分类数据。想要来处理扫描NFC标签的应用程序可以声明意图过滤器,并要求来处理数据。
而Android Beam?功能允许设备通过物理窃听设备,共同推动一个NDEF消息到另一个设备。
这种互动提供了一个更简单的方法来发送比其它无线技术,如蓝牙的数据,因为与NFC,无需手动设备发现或配对是必需的。
当两个设备进入范围的连接自动启动。 Android Beam 可通过一套NFC的API,所以任何应用程序都可以传输设备之间的信息。

例如,联系人,浏览器,和YouTube应用程序使用的Andr??oid梁共享联系人,网页,以及与其他设备的视频。


The Tag Dispatch System


Android平台的设备通常寻找NFC标签,当屏幕解锁,除非在NFC设备的设置菜单被禁用。
当一个Android设备发现一个NFC标签,要求用户使用合理的应用程序处理,期望行为中有最合适的Activity来处理这个意图
因为设备扫描NFC标签在非常短的范围内,它很可能是让用户手动选择的Activity将迫使他们移离标签的设备和断开连接。
你应该发展自己的Activity,只处理NFC标签,你的活动关心,以防止Activity选择器出现。


为了帮助您完成此目标,Android提供了特殊的标记调度系统,分析扫描NFC标签,解析它们,并试图找到感兴趣的扫描数据的应用程序。
它通过:
1.解析NFC标签,并找出MIME类型或一个URI标识标签中的数据有效标识。
2.封装MIME类型或URI和有效标识送入意图。前两个步骤如何NFC标签被映射到MIME类型和URI描述。
开始基于所述意图的活性。这是在如??何NFC标签被分派到应用程序描述。


How NFC tags are mapped to MIME types and URIs


在你开始写你的NFC应用之前,了解不同类型的NFC标签是非常重要的,标签调度系统如何解析NFC标签,
以及特殊的工作,它检测到NDEF消息当标签调度系统一样。 NFC标签进来的技术范围广泛,
也可以有许多写入方式和许多写入不同种类的数据。Android 具有用于NDEF标准,它是由NFC论坛定义的支持最多。


在你开始写你的NFC应用之前,了解不同类型的NFC标签是非常重要的,标签调度系统如何解析NFC标签,
以及特殊的工作,它检测到NDEF消息当标签调度系统一样。 NFC标签进来的技术范围广泛,
也可以有许多写入方式和许多写入不同种类的数据。Android 具有用于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-bit TNF (Type Name Format)

标识如何解释变长型字段。有效值在 _表1_   中描述的描述。(做的超链接如果你打不开 请尝试翻墙)


Variable length type

  描述了记录的类型。如果使用TNF_WELL_KNOWN,使用此字段指定记录类型定义(RTD)。有效RTD值在_表2_中描述。


Variable length ID

   为了记录一个唯一的标识符。此字段不经常使用,但如果您需要唯一标识一个标签,你可以为它创建一个ID。

Variable length payload

  要读取或写入的实际数据的有效负荷。一个NDEF消息可以包含多个NDEF记录,所以不承担全部有效负荷在NDEF消息的第一个NDEF记录中。

  {  因为还没有进入实际开发所以不大理解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.}

 标签调度系统使用TNF和类型字段来试图映射一个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的记录,它创建一个封装标签的技术,而不是意图。


How NFC Tags are Dispatched to Applications

当标签调度系统完成创建封装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意图。


标签调度系统的工作原理基本方法如下:


1.试图启动与由标签调度系统解析NFC标签(或者ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED)时创建的意图的活动。
2.如果没有Activity 的意图拦截器拦截,尝试启动下一个优先级最低的意图(无论是ACTION_TECH_DISCOVERED或ACTION_TAG_DISCOVERED)的活动,直到意图或直至标签调度系统中的应用程序过滤器会尝试所有可能的意图。
3.如果没有应用程序过滤任何的意图的,什么也不做。

技术分享




在任何可能的时候,都会接收的NDEF消息和ACTION_NDEF_DISCOVERED意图,因为它是最特定的三个。

此意向,您可以启动应用程序在一个比较合适的时间比其他两个目的,给用户带来更好的体验。


Requesting NFC Access in the Android Manifest

在可以访问设备的NFC硬件和妥善处理NFC的意图,在申报这些项目的


AndroidManifest.xml file:

  • The NFC <uses-permission> element to access the NFC hardware:
    <uses-permission android:name="android.permission.NFC" />

最小的SDK版本,应用程序可以支持。

 API级别9只支持通过ACTION_TAG_DISCOVERED有限标签调度,只有通过提供额外的EXTRA_NDEF_MESSAGES访问NDEF消息。

没有其他标签属性或I/ O操作都可以访问。

 API级别10包括全面的读/写支持,以及前景NDEF推,和API级别14提供了一种简单的方法来推动NDEF消息给其他设备与Android梁和更加方便的方法来创建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 android:name="android.hardware.nfc" android:required="true" />


如果你的应用程序使用NFC功能,但这些功能不是你的应用的关键,你可以省略的用途,功能元素,通过检查,看检查NFC avalailbility在运行时。


getDefaultAdapter() is null.


Filtering for NFC Intents



要启动应用程序要处理一个NFC标签被扫描时,您的应用程序可以过滤一个,两个,或在Android清单所有三个NFC意图的。

然而,你通常要为ACTION_NDEF_DISCOVERED意图的大多数控制在应用程序启动的筛选。

该ACTION_TECH_DISCOVERED目的是回退ACTION_NDEF_DISCOVERED时没有应用程序过滤器ACTION_NDEF_DISCOVERED或当负载不NDEF。

过滤ACTION_TAG_DISCOVERED通常过于笼统的类别筛选。许多应用程序将用于过滤或ACTION_NDEF_DISCOVERED前ACTION_TAG_DISCOVERED ACTION_TECH_DISCOVERED,让你的应用有启动的概率很低。 

ACTION_TAG_DISCOVERED只能作为最后手段的应用,在没有其他应用程序安装处理ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVEREDintent的情况下进行过滤。


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

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

ACTION_TECH_DISCOVERED

如果在ACTION_TECH_DISCOVERED意图您的活动过滤器,你必须创建一个指定的活动支持高新技术列表集内的技术XML资源文件。你的活动被视为匹配,如果一个技术列表设置是一组由标签支持的技术,它可以通过调用getTechList获得()的一个子集。


例如,如果被扫描的标签支持MifareClassic,NdefFormatable和NFCA,你的技术列表设置必须按顺序指定所有三,二,或技术(没有别的),一个为您的活动进行匹配。

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.

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

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 集被认为是独立的,和你的activity 如果任何单一的tech-list将是由gettechlist()技术被认为是一个匹配的子集。这提供了与和或语义匹配技术。下面的例子匹配可以支持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:

<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>
有关使用标签技术和ACTION_TECH_DISCOVERED意图的更多信息,请参见使用高级NFC文档中支持的标签技术。

ACTION_TAG_DISCOVERED

To filter for ACTION_TAG_DISCOVERED use the following intent filter:

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

Obtaining information from intents

如果Activity开始,因为一个NFC的意图,你可以获取有关从意图扫描NFC标签的信息。意图可以包含具体取决于所扫描的标签下面的演员:

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


要获得这些额外的,请检查你的活动是与NFC意图之一,推出以确保标签被扫描,然后获得额外出意图。下面的例子将检查


ACTION_NDEF_DISCOVERED intent and gets the NDEF messages from an intent extra.

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
}

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记录的常见类型写入NFC标签或Android Beam发送数据时,以帮助您。

开始采用Android4.0(API级别14),该createUri()方法可帮助您自动创建URI记录。

在开始的Android4.1(API等级16),createExternal()和createMime()可以帮助您创建MIME和外部类型的NDEF记录。

使用这些辅助方法尽可能避免在手动创建NDEF记录错误。


本节还介绍了如何创建相应的意图过滤器备案。所有的这些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 :

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

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

Using the createMime() method:

NdefRecord mimeRecord = NdefRecord.createMime("application/vnd.com.example.android.beam",
    "Beam me up, Android".getBytes(Charset.forName("US-ASCII")));

Creating the NdefRecord manually:

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

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:

Using the createUri(String) method:

NdefRecord rtdUriRecord1 = NdefRecord.createUri("http://example.com");

Using the createUri(Uri) method:

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

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>

TNF_EXTERNAL_TYPE

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

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

Creating the NdefRecord manually:

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


使用TNF_EXTERNAL_TYPE更多的通用NFC标签的部署,以更好地支持Android系统和非Android手机。

注:URNs TNF_EXTERNAL_TYPE有一个规范的格式:金塔:NFC:EXT:example.com:externalType,

             但是NFC论坛RTD规范声明金塔:NFC:EXT:瓮的部分必须从NDEF记录中ommitted。

             因此,所有你需要提供是用冒号分隔域(example.com的例子)和式(externalType中的例子)。 

             NFC:EXT:example.com:当调度TNF_EXTERNAL_TYPE,

             Android converts the urn:nfc:ext:example.com:externalType URN到vnd.android.nfc://ext/example.com:externalType URI,这就是本例中的意图过滤器声明。



Android Application Records



在Android 4.0的(API级别14)推出一个Android应用程序记录(AAR)提供了更强的肯定,您的应用程序启动一个NFC标签被扫描时。
一个AAR有嵌入式的NDEF记录中的应用程序的包名。您可以添加一个AAR您NDEF消息的任何NDEF纪录,由于Android搜索整个NDEF消息AARS。
如果找到一个AAR,它启动的基础上AAR里面的包名的应用程序。如果应用程序是不存在的设备上,谷歌Play是推出下载应用程序。


如果你想防止其他应用程序过滤功能相同的意图和潜在的处理已部署特定的标AARs 是有用的。AARs 只支持在应用层面,因为包名的约束,而不是在活动水平与意图过滤。
如果你想处理一个意图在活动水平,使用意图过滤器。


如果一个标签包含一个AAR,标签调度系统调度以下列方式:


尝试使用一个意图过滤器正常启动的活动。如果意图相匹配的活动也符合AAR,启动活动。
如果该过滤器的目的不符AAR的活动,如果多个活动可以处理的意图,或者如果没有活动处理的意图,开始由AAR的指定的应用程序。
如果没有应用程序可以与AAR开始,去谷歌发挥下载基于AAR的应用

注意:您可以覆盖AARS和意图调度系统与前台调度系统,它允许前台活动有优先权时,NFC标签被发现。用这种方法,活动必须在前台覆盖AARS和意图调度系统。



如果您仍然要为那些不包含AAR扫描标签筛选,你可以声明意图过滤器正常。如果您的应用程序感兴趣的是不包含AAR等标签,这非常有用。

例如,也许你想保证你的应用程序处理您部署专用标记以及部署的第三方通用标签。

请记住,AARS具体到Android4.0设备或更高版本,所以在部署时的标签,您很可能希望使用AARS和MIME类型/ URI的组合,以支持最广泛的设备。

此外,当你部署NFC标签,想想你想怎么写你的NFC标签,以便在大多数设备(Android平台和其他设备)的支持。

您可以通过定义一个相对独特的MIME类型或URI,使其更容易对应用进行区分做到这一点。


Android提供了一个简单的API来创建一个AAR,createApplicationRecord()。所有你需要做的任何地方嵌入AAR在NdefMessage。

你不想用你的NdefMessage的第一条记录,除非AAR是在NdefMessage的唯一记录。

这是因为Android系统会检查NdefMessage的第一条记录,以确定MIME类型的标签,这是用来创建一个意图应用过滤或URI。下面的代码演示如何创建一个AAR:



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


Beaming NDEF Messages to Other Devices


最后一段我相信大家更喜欢看原文! (我不会说我已经懒得再看了...)

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.

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.

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

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.

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.

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

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:

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

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:

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

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.



相信大家看完后对NFC一定会有一定的初步了解 ~ 


哎。累死了 一下午啊!





Google NFC Basics (谷歌官网NFC翻译)

标签:android

原文地址:http://blog.csdn.net/u010962482/article/details/46328869

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!