Android NFC 学习笔记

NFC(Near Field Communication) 近距离无线通讯技术。
可以用于NFC标签与Android设备 或 两台Android设备间进行小型数据交换、访问内容与服务等。

NFC的工作模式:由于NFC通信总是由一个发起者和一个接收者组成,发起者会主动发送电磁场,可以为被动接收者提供电源,其基本原理和收音机类似。正是由于被动式接收者可以通过发起者提供电源,因此接收者可以有非常简单的形式。NFC功能的工作模式可概括为三种:

  • 读卡器模式:该模式的本质为通过支持NFC的电子设备从带有NFC芯片的标签、物品等媒介中读写信息。NFC标签工作原理为:其不需要外部供电,当支持NFC的设备向标签读写数据时,支持NFC的设备会发送某种磁场,该磁场会主动向NFC标签供电,从而顺利完成读写工作。

  • 点对点模式:该模式是用于不同NFC设备之间进行数据交换,其有效距离一般不能超过4厘米,传输建立速度与传输速率比红外和蓝牙技术快很多。该模式下NFC进行传输时,通常还会使用到androidBeam技术进行传输数据,当使用androidBeam传输数据的两部设备不再限于4厘米之内。

  • 仿真卡模式。 其本质为将支持NFC功能的电子设备,如NFC手机,当作借书卡、公交卡、银行卡、门禁卡等IC卡使用。其实现的基本原理是将IC卡中信息凭证封装成数据包并存储在支持NFC的设备中。此外除了支持NFC的设备,刷电子设备处还需要NFC射频器,通过接收NFC射频器发送的信号与一系列验证之后,电子设备将IC卡中相应信息传入射频器中,最终从射频器传输到射频器所连接的电脑终端,完成相应处理操作。

NDEF

  • NDEF:进行NFC操作时可以使用 NDEF 消息格式来发送和接收NFC数据。一条NDEF消息(NdefMessage),可能具有多条NDEF记录(NdefRecord)。当 Android 设备扫描包含 NDEF 格式数据的 NFC 标签时,它会解析该消息并尝试确定数据的 MIME 类型 或 起标识作用的 URI。为此,系统需要读取记录头(NdefMessage 中的第一条 NdefRecord),以确定如何解读整个 NDEF 消息。

NDEF记录格式如下

image.png

字节[0]

TNF : 类型名称格式字段。取值如下图:

image.png

IL:ID长度字段

IL标志指示ID长度字段是否存在。如果将其设置为0,则ID长度字段将在记录中省略。

SR:短记录位

如果PAYLOAD LENGTH字段为1字节(8位/ 0-255)或更小,则SR标志设置为1。这允许更紧凑的记录。

CF:块标志

CF标志指示这是第一个记录块还是中间记录块。

ME:消息结束

ME标志指示这是否是消息中的最后一条记录。

MB:消息开始

MB标志指示这是否是NDEF消息的开始。

列举两个解析例子如下:

照NDEF消息格式来解析下列Hex串

D1 02 1F 53 70 91 01 0E 54 02 

65 6E 68 65 6C 6C 6F 20 77 6F 

72 6C 64 51 01 09 55 01 73 69 

6E 61 2E 63 6F 6D

解析过程:

Byte 0: D1

    0xD1 = 11010001B,对应的标志位如下:

    MB(Message Begin) = 1,说明这是首记录

    ME(Message End) = 1,说明这是末记录(说明消息只有一个记录)

    CF(Chunk Flag) = 0,说明记录未被切块

    SR(Short Record) = 1,说明这是短记录,PAYLOAD_LENGTH 占1字节

    IL(ID_LENGTH field is present) = 0,说明没有 ID_LENGTH 和 ID 域

    TNF(Type Name Format) = 1,说明TYPE类型是 NFC Forum well-known type [NFC RTD]

image.png

因为SR=1且IL=0,所以NDEF记录可简化为如下结构

image.png

Byte 1: 02

    TYPE_LENGTH = 2,TYPE域长度为2

Byte 2: 1F

    PAYLOAD_LENGTH = 0x1F,Payload域长度为31

Byte 3-4: 53 70

    TYPE = "Sp",因为TYPE域长度为2,所以此处TYPE取2个字节

此后全是PAYLOAD域的内容,因为TYPE="Sp",所以需要使用智能海报的记录类型(Smart Poster Record Type Definition)来解析。智能海报的记录类型其实也是一个NDEF消息。NDEF记录的PAYLOAD域可以存放任何东西,包括嵌套NDEF消息。

智能海报的内容可以包括标题、URI、动作、图标、大小、类型等记录,其中URI记录是必须有的,其他的可选,次序无所谓。

   1)现在将智能海报的内容贴过来,如下

    91 01 0E 54 02 65 6E 68 65 6C 

    6C 6F 20 77 6F 72 6C 64 51 01 

    09 55 01 73 69 6E 61 2E 63 6F 

    6D

开始解析智能海报

Byte 0: 91

    0x91 = 10010001B,对应的标志位如下:

    MB = 1,说明这是首记录

    ME = 0,说明后面还有记录

    CF = 0,说明记录未被切块

    SR = 1,说明这是短记录,PAYLOAD_LENGTH 占1字节

    IL = 0,说明没有 ID_LENGTH 和 ID 域

    TNF = 1,说明TYPE类型是 NFC Forum well-known type

Byte 1: 01 TYPE_LENGTH = 1,TYPE域长度为1

Byte 2: 0E  PAYLOAD_LENGTH = 0x0E,Payload域长度为14

Byte 3: 54 TYPE = "T",说明是文本记录类型,适用“Text Record Type Definition”

Byte 4-17: 02 65 6E 68 65 6C 6C 6F 20 77 6F 72 6C 64  这是文本记录的内容

下面对“02 65 6E 68 65 6C 6C 6F 20 77 6F 72 6C 64”按照下面文本记录格式解码。

image.png

image.png

0x02 = 0 0 000010 B 语言长度及编码格式

000010 LANA 长度为2

0 = RFU

0 = UTF-8

LANA = 65 6E = en = US-ASCII

再按照US-ASCII 解析 68 65 6C 6C 6F 20 77 6F 72 6C 64 = hello world

至此,对海报内容的第一条NDEF记录解码完成,接下来是对剩余内容解码。

“51 01 09 55 01 73 69 6E 61 2E 63 6F 6D”,同样也是按照NDEF记录来解码。

Byte 0: 51

    0x91 = 01010001B,对应的标志位如下:

    MB = 0,说明这不是首记录

    ME = 1,说明这是末记录

    CF = 0,说明记录未被切块

    SR = 1,说明这是短记录,PAYLOAD_LENGTH 占1字节

    IL = 0,说明没有 ID_LENGTH 和 ID 域

    TNF = 1,说明TYPE类型是 NFC Forum well-known type

Byte 1: 01 TYPE_LENGTH = 1,TYPE域长度为1

Byte 2: 09 PAYLOAD_LENGTH = 0x09,Payload域长度为9

Byte 3: 55 TYPE = "U",说明是URI记录类型,适用“URI Record Type Definition”

Byte 4-12:  01 73 69 6E 61 2E 63 6F 6D 这是URI记录的内容

URI记录内容格式如下:

image.png

image.png

image.png

image.png

Byte 0: 01 由上表可知,对应的协议是 http://www

73 69 6E 61 2E 63 6F 6D 转 UTF-8string = sina.com

至此解析完毕

NFC标签调度与解析

当标签调度系统创建完用于封装 NFC 标签及其标识信息的 Intent 后,它会将该 Intent 发送给感兴趣的应用,由这些应用对其进行过滤。如果有多个应用可处理该 Intent,系统会显示 Activity 选择器,供用户选择要使用的 Activity。标签调度系统定义了三种 Intent,按优先级从高到低列出如下:

  1. ACTION_NDEF_DISCOVERED:如果扫描到包含 NDEF 负载的标签,并且可识别其类型,则使用此 Intent 启动 Activity。这是优先级最高的 Intent,标签调度系统会尽可能尝试使用此 Intent 启动 Activity,在行不通时才会尝试使用其他 Intent。 适用于使用NDEF 格式的情况。
  2. ACTION_TECH_DISCOVERED:如果没有登记要处理 ACTION_NDEF_DISCOVERED Intent 的 Activity,则标签调度系统会尝试使用此 Intent 来启动应用。此外,如果扫描到的标签包含无法映射到 MIME 类型或 URI 的 NDEF 数据,或者该标签不包含 NDEF 数据,但它使用了已知的标签技术,那么也会直接启动此 Intent。 适用于使用自定义标签数据格式的情况
  3. ACTION_TAG_DISCOVERED:如果没有处理 ACTION_NDEF_DISCOVERED 或者 ACTION_TECH_DISCOVERED Intent 的 Activity,则使用此 Intent 启动 Activity。

实现NFC的基本步骤

1.添加权限 您必须先在 AndroidManifest.xml 文件中声明以下内容,然后才能访问设备的 NFC 硬件并正确处理 NFC Intent:

<uses-permission android:name="android.permission.NFC" />
<uses-sdk android:minSdkVersion="10"/>
//声明只有带NFC的手机才可以下载
<uses-feature android:name="android.hardware.nfc" android:required="true" />

复制代码

进行intent-filter过滤器声明

以下示例展示了如何过滤 MIME 类型为 text/plain 的 ACTION_NDEF_DISCOVERED Intent:

  <intent-filter>
        <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain" />
    </intent-filter>
    
复制代码

以下示例展示了如何过滤采用 https://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 Intent:

<activity
    android:name=".mvp.activity.NfcActivity"
    android:launchMode="singleTask"
    android:screenOrientation="portrait">
    <meta-data
        android:name="android.nfc.action.TECH_DISCOVERED"
        android:resource="@xml/nfc_tech_filter" />
</activity>



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

复制代码

参考文档
blog.csdn.net/qq_41522183… www.blogjava.net/ZouYonghui/…

Guess you like

Origin juejin.im/post/7075257574131499038