NFC 基础

文章来源:NFC Basics,此文章是google 官方对NFC的简介。

       本文档介绍了基本的NFC任务在Android上。它说明了如何发送和接收的NDEF消息的形式数据,并介绍支持这些功能的框架API。对于更高级内容,包括非NDEF数据的讨论,请参阅高级NFC
在Android使用NDEF数据,有两个主要的用途:
       ● 阅读NDEF数据从一个NFC标签
       ● 传送NDEF信息从一个设备到另一个支持Android Beam的设备
       标签的调度系统处理从一个NFC标签读取NDEF数据,它分析发现的NFC标签,适当的数据进行分类,并针对不同的数据启动一个应用程序。要处理的扫描NFC标签的应用程序可以声明一个意图过滤器,并要求处理的数据。
        Andr​​oid Beam功能,允许一台设备推送NDEF消息另一台设备上通过两台设备物理接触在一起。这种相互作用提供了一个比其它无线技术简单的方法来发送数据,如蓝牙,因为有了NFC,手动发现设备或配对不是必需的。两个设备进入范围时,连接自动启动。Android Beam 也成为了一种可能可通过NFC 的一系列API,因此,任何应用都可以在设备之间传输信息。例如:联系人,浏览器和YouTube应用程序使用Android Beam与其他设备共享联系人,网页和视频。

标签调度系统

        Android设备通常是在屏幕解锁的时候扫描NFC标签,除非NFC功能在设置菜单中被禁用。当Android 设备发现了一个NFC标签,启动最适当的activity处理intent,而不需要询问用户使用什么应用程序处理。因为设备扫描NFC标签在很短的范围内,让用户手动选择的活动很有可能将迫使他们从标签上移动设备,进而断开连接。应该开发activity处理NFC标签,activity以防止activity选择出现。
        为实现这个目标,Android提供了一个特殊的标签调度系统来分析扫描NFC标签并解析它们,并试图在扫描数据中找到对应的的应用程序。这是通过:
        1. 解析NFC标签和搞清楚的MIME类型或在标签中用于标识一个数据URI。
        2. 封装MIME类型或URI和有效载荷到Intent。前两个步骤在下面的”NFC标签是如何映射到MIME类型和URI“中有介绍。
        3. 基于Intent启动activity。这部分具体描述在” 如何NFC标签被分派到应用“。

NFC标签是如何映射到MIME类型和URI

        在开始写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)
        指示如何解析variable length type区域。有效值像在表1中描述的。
Variable length type
         描述记录类型。如果使用TNF_WELL_KNOWN,使用此字段指定记录类型定义(RTD)。有效的RTD值描述在表2中。
Variable length ID
         记录的唯一标识符。此字段不经常使用,但如果需要唯一识别的标签,你可以为其创建一个ID。
Variable length payload
         这个是要读取或写入的实际数据负载。NDEF消息可以包含多个NDEF记录,所以不要以为全部负载就是在第一NDEF创纪录的NDEF消息。
         标签调度系统使用TNF和类型字段试图去映射的MIME类型或URI的NDEF消息。如果成功的话,它封装了内部信息的实际有效载荷的ACTION_NDEF_DISCOVERED intent。然而,也会发生标签调度系统不能基于第一NDEF记录的数据确定类型。发生这种情况时,NDEF数据不能被映射到一个MIME类型或URI,或当NFC标签不包含NDEF数据做为开始。在这种情况下,标签的对象,该对象具有标记的技术和有效载荷的信息,封装一个成ACTION_TECH_DISCOVERED intent。

        表1。介绍了标签调度系统如何根据TNF和类型字段映射到MIME类型或URIs。也说明了哪些TNFs不能被映射到MIME类型或URI。在这种情况下,标签调度系统回到 ACTION_TECH_DISCOVERED的。

        例如,如果标签调度系统遇到一个类型TNF_ABSOLUTE_URI纪录,该记录的可变长度类型字段映射到一个URI。标签调度系统将该URI封装成ACTION_NDEF_DISCOVERED的Intent,并携带关于标签的其他信息,如负载。另一方面,如果它遇到的的记录类型TNF_UNKNOWN,它创建封装标签技术的Intnet。

表1    支持TNFs和它们的映射

类型名称格式(TNF) 映射
TNF_ABSOLUTE_URI                        基于URI的基础类型字段
TNF_EMPTY 回到  ACTION_TECH_DISCOVERED 
TNF_EXTERNAL_TYPE 在类型字段中基于URN的URI。URN被编码成NDEF类型缩写形式:<domain_name>:<service_name>Android映射成URI的形式: vnd.android.nfc ://ext/ <domain_name>: <service_name>。 
TNF_MIME_MEDIA 基于类型字段MIME字段。
TNF_UNCHANGED 无效的第一条记录中,因此回落到 ACTION_TECH_DISCOVERED的
TNF_UNKNOWN 回到 ACTION_TECH_DISCOVERED 
TNF_WELL_KNOWN 根据记录类型定义(RTD),在类型字段设置MIME类型或URI。RTD和映射的更多信息,请参阅表2

表2  支持RTD为TNF_WELL_KNOWN及其映射

记录类型定义(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类型为text / plain
RTD_URI 基于有效载荷URI。

NFC标签分发到应用

        标签调度系统创建一个intent,intent封装了NFC标签和它的识别信息,调度系统发送给对应的应用程序,它是依据intent的过滤器。如果有一个以上的应用程序可以处理这个intent,activity选择器就会出现,使用户可以选择的activity。标签调度系统定义了三个意向,按照最高优先级到最低优先级的顺序:
       1. ACTION_NDEF_DISCOVERED:当包含NDEF有效载荷或是一个公认的类型的NFC tag被扫描到时,这个Intent用来启动一个activity。这是最高优先级的intent,标签调度系统尝试用这个intent启动一个activity,早于任何其他的intent。
        2. ACTION_TECH_DISCOVERED:如果没有activity处理ACTION_NDEF_DISCOVERED  intent,标签调度系统尝试使用这个intent启动应用程序。如果被扫描tag包含NDEF的数据不能被映射到一个MIME类型或URI,或者tag不包含NDEF数据,但是是一个已知的标签技术,在这两种情况下,此intent也可以直接启动(首先没有启动ACTION_NDEF_DISCOVERED)。
        3. ACTION_TAG_DISCOVERED:在没有activity处理ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED的 intent时,此intent才会被启用。

标签调度系统的工作原理,基本方法如下:
        1.  用intent启动一个activity,此intent是由标签调度系统解析NFC的tag所创建的(ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED)。
        2.  如果activity过滤器没有过滤那个intent,就要用下一个低优先级的的intent(ACTION_TECH_DISCOVERED或ACTION_TAG_DISCOVERED)启动activity,直到应用程序过滤器找到相应的intent,或者标签调度系统尝试所有可能的intent。
        3. 如果应用程序不针对任何的intent过滤,那就do nothing。


        只要有可能,都会用NDEF 消息和ACTION_NDEF_DISCOVERED 来工作,因为它是三个Intent中最突出使用的。ACTION_NDEF_DISCOVERED 可以比其他的两个intent能在更合适的时间启动应用,给了用户很好的体验。

AndroidManifest NFC访问的请求

在访问NFC硬件设备和妥善处理NFCintent之前,需要在AndroidManifest.xml文件做如下动作

●访问NFC硬件的权限

<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消息到其他设备和额外便捷的方法创建NDEF记录。

<uses-sdk android:minSdkVersion="10"/>
●uses-feature可以使应用在google Play仅向支持NFC的功能的设备显示

<uses-feature android:name="android.hardware.nfc" android:required="true" />
      如果应用程序使用NFC功能,但该功能并不重要对于应用程序来说,那就可以省略uses-feature元素,并在运行时检查NFC的可用性,看看getDefaultAdapter() 是否为null。

NFC Intent 过滤

        为了要处理扫描的NFC标签而启动应用程序,应用程可以过滤一个,两个或全部三个NFC intent,在Android manifest 中配置。然而,通常希望控制应用程序启动时过滤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。
        由于NFC标签部署有所不同,很多时候不是你的控制之下,这并不总是可能的,这就是为什么在必要时可以回退到其他两个意图。当你有类型的标签和数据写入的控制权,它是建议使用的NDEF格式化标签。以下各节描述了每种intent如何过滤。

ACTION_NDEF_DISCOVERED

          为了过滤ACTION_NDEF_DISCOVERED,声明intent过滤器要过滤的数据类型。下面的例子是过滤器 过滤MIME类型text / plain的ACTION_NDEF_DISCOVERED:

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:mimeType="text/plain" />
</intent-filter>
          下面的示例过滤器中的URI的形式 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

        如果activityx想过滤ACTION_TECH_DISCOVERED,你必须创建含有activity支持tag的tech-list列表XML资源文件。如果tech-list列表的一个子集的技术可以被tag所支持的话,则activity被认为是匹配的,你可以得到通过调用getTechList()获取到tech-list列表 。例如,如果扫描到的tag支持MifareClassic的,NdefFormatable,NfcA,tech-list列表必须指定所有三个,两个或技术中的一个(还可以有其他的),以便匹配activity。
        下面的示例定义的所有技术。你可以删除你不需要的那些。将此文件保存在<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.Ndef</tech>
        <tech>android.nfc.tech.NdefFormatable</tech>
        <tech>android.nfc.tech.MifareClassic</tech>
        <tech>android.nfc.tech.MifareUltralight</tech>
    </tech-list>
</resources>
        还可以定义多重的tech-list列表,他们被认为是独立的。如果任何单一的tech-list列表中技术作为getTechList()返回集合的子集,那activity被认为是匹配的。这提供了AND和OR 匹配技术。下面的例子匹配的标签,可以支持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>
           在AndroidManifest.xml文件中,指定刚刚创建资源文件到的<meta-data>元素,它是<activity> 元素的子元素,下面的例子:
<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>

           关于tag技术和ACTION_TECH_DISCOVERED协作更多信息,请参阅高级NFC文档。

ACTION_TAG_DISCOVERED

要过滤ACTION_TAG_DISCOVERED使用下面的intent过滤器:

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

从意图获取信息

        如果一项活动开始因为NFC的intent,从intent可以得到扫描到的NFC标签的信息。intent包含依附在tag上以下额外的信息:
        ● EXTRA_TAG(必需的):标签对象代表扫描标签。
        ● EXTRA_NDEF_MESSAGES(可选):解析tag获取的NDEF消息数组。这额外的意图是强制性的。
        ● {android.nfc.NfcAdapter#EXTRA_ID(可选):低级别的ID标签。
         要获得这些额外检查,看是否活动推出的与NFC意图之一,以确保标签被扫描,然后获取额外的意图。下面的例子检查的ACTION_NDEF_DISCOVERED 意图,并得到意向额外的NDEF消息。






未完待续

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值