上篇文章介绍了接入式USB硬件的简单使用,接下来将介绍不依赖物理连接的硬件通信了。本文的重点是近距离通信的硬件NFC。

NFC硬件

应用程序中可以通过NFC硬件读取或发送指定协议的技术实现,在Android10.0之前甚至可以封装大段的NDEF数据。另外,Android系统基于NFC的特性,结合移动设备的安全元件,构建了一层HCE架构,从而应用于安全级别较高的公交卡刷卡或付款交易等操作。

权限声明

要想使用NFC硬件的相关功能,必须要声明权限,在应用程序的清单文件中声明<uses-permission />标签,其中的android:name属性值为android.permission.NFC

当然,为了强调应用程序需要运行在支持NFC硬件的设备上,也可以在应用程序的清单文件中声明<uses-feature />标签,其中的android:name属性值为android.hardware.nfc

使用流程

由于NFC硬件是在近距离接触后即可触发,所以首先要在应用程序中确定触发NFC连接后要响应的界面Activity。在清单文件注册的<activity></activity>标签内部,增加意图过滤<intent-filter></intent-filter>标签,并在该标签内部添加<action />标签,并指定android:name属性值分别为android.nfc.action.NDEF_DISCOVERED作为NDEF数据传输行为、android.nfc.action.TECH_DISCOVERED作为技术标签行为或android.nfc.action.TAG_DISCOVERED作为普通行为。

上边指定的意图行为有三种方式,但是在连接NFC硬件后,系统将按照上述顺序优先启动对应的界面Activity。另外针对上述三种不同的意图行为,还要在清单文件下分别追加相应的配置。

在通过上述三种方式收到Intent意图启动的界面Activity中,可以通过getIntent()获取启动传入的Intent意图对象。在该对象中,可以接收其他NFC硬件输入的标签及相关内容。

默认功能

针对action值为android.nfc.action.TAG_DISCOVERED的配置,由于是优先级最低的意图行为,因此在上面两种意图行为及配置未调起时,就会调用该意图行为绑定的界面Activity。因此该意图行为下不需要其他的配置参数。

在启动的界面Activity中,调用Intent对象的getParcelableExtra(String name)方法,传入参数 name 值为NfcAdapter.EXTRA_TAG="android.nfc.extra.TAG",得到android.nfc.TagNFC标签类型的对象,该对象中记录了标签的基本信息。

NDEF数据传输功能

针对action值为android.nfc.action.NDEF_DISCOVERED的配置,还要声明要传输的数据类型。同样在意图过滤的<intent-filter></intent-filter>标签内部,添加<data />标签。可支持传输的数据类型可以使用的表示方式,包括 MIME TYPE 类型的结构,和 URI 结构,二选一皆可。在<data />标签中使用android:mimeType属性,可以设置 MIME TYPE 结构的数据类型,通常如属性值为text/plain的文本类型。另外,在<data />标签中使用android:schemeandroid:hostandroid:pathPrefix三个属性同时标注URI内容。

在启动的界面Activity中,调用Intent对象的getParcelableArrayExtra(String name)方法,传入参数 name 值为NfcAdapter.EXTRA_NDEF_MESSAGES="android.nfc.extra.NDEF_MESSAGES",得到Parcelable[]数组可以分别强转为android.nfc.NdefMessage用以保存消息内容的类型对象数组。当使用android.nfc.action.NDEF_DISCOVERED意图行为过滤的NFC硬件启动后,可通过该方法获取NDEF消息内容。

在应用程序内可以自定义NDEF消息体内容并发送。借助android.nfc.NdefRecordNFC记录类。在该类中有多个静态方法,包括createExternal(String domain, String type, byte[] data)创建有携带数据的NFC记录对象;createMime(String mimeType, byte[] mimeData)创建MIME类型的NFC记录对象;createTextRecord(String languageCode, String text)创建短文本内容的NFC记录对象;createUri (Uri uri)创建Uri类型的NFC记录对象等。

在创建NdefRecord对象之后,可以作为参数传入NdefMessageNFC消息类的构造方法中,从而创建NdefMessage对象,将该对象作为参数,传入NdefAdapter对象的setNdefPushMessage(NdefMessage message, Activity activity, Activity... activities)方法中,这样在当前参数 activity 中将会一直发送参数 message 中的内容。

从Android10.0即API级别29开始,NFC功能的NDEF消息传输功能就被废弃了,因此其相关功能方法在以后的版本中也将不再支持。

标签技术功能

针对action值为android.nfc.action.TECH_DISCOVERED的配置,还要通过资源文件声明要依赖的技术集。资源文件的声明是在注册的<activity></activity>标签内部,添加<meta-data />标签,同样设置其属性android:name值为android.nfc.action.TECH_DISCOVERED,更别忘了设置属性android:resource,其值为保存在 res/xml 目录下的资源文件。而资源文件的定义,是在 res/xml 路径下,定义 xml 格式的资源文件,在该文件中使用<tech-list></tech-list>标签作为最外层的集合,在该标签中包含了一堆使用<tech>标签定义的可支持技术。这些技术的定义均实现了android.nfc.tech.TagTechnology标签技术接口,在各种实现类中定义了相应技术的常量值。

在启动的界面Activity中,同样可以调用Intent对象的getParcelableExtra(String name)方法,传入参数 name 值为[NfcAdapter.EXTRA_TAG]得到TAGNFC标签类的对象。

另外可以通过其getTechList()方法,获取通过意图行为android.nfc.action.TECH_DISCOVERED启动的NFC硬件中所使用技术列表。其中系统支持的技术类型均实现了android.nfc.tech.TagTechnology标签技术接口。

在得到的TagNFC标签类的对象后,可以遵循相关技术类型对标签进行读写操作。对实现了TagTechnology接口的具体技术类中,可以调用静态方法get(Tag tag)得到具体的技术类对象,其参数即得到的TagNFC标签类对象。在实现TagTechnology接口的对象中,需要首先调用connect()建立连接;之后可以根据不同的技术实现,调用相关的读写操作方法;最终在操作结束后,调用close()断开连接即可。

HCE服务功能

该功能是由Android系统实现的一套在后台使用NFC进行交易等服务的架构。该架构主要依赖android.nfc.cardemulation.HostApduService抽象服务类。在自定义的服务中必须继承自HostApduService服务类,并实现其两个抽象方法,接收并响应数据的byte[] processCommandApdu(byte[] apdu, Bundle extras)方法,和NFC切换或关闭当前APDU连接时的void onDeactivated(int reason)方法。

在定义了继承自HostApduService的服务之后,需要在清单文件中注册该服务组件,在<service></service>标签中要设置android:exported属性值为true。同时在标签内嵌入<intent-filter></intent-filter>意图过滤标签中,设置行为值为HostApduService.SERVICE_INTERFACE="android.nfc.cardemulation.action.HOST_APDU_SERVICE"。另外要在标签内嵌入<meta-data />额外数据标签,设置其android:name属性值为HostApduService.SERVICE_META_DATA="android.nfc.cardemulation.host_apdu_service",设置其android:resource属性为包含 AID 群组的资源文件。

定义的 AID 群组,是由NFC卡提供的应用唯一标识,如用于支付的银联储蓄卡、公交卡等,每张卡都有唯一的16字节组成的AID。而在资源文件中可以定义该应用程序自定义的HostApduService服务中允许交易的 AID 群组,该群组的所有 AID 只要有一个 AID 连接当前设备的 NFC 硬件,都会唤起 HCE 服务。

在应用程序的资源文件 res/xml 目录下,可以创建自定义的资源文件以定义上述 AID 群组,在资源文件中根标签为<host-apdu-service></host-apdu-service>,在其中可以嵌入多组标签<aid-group></aid-group>用来标记 AID 群组,其中设置android:description属性值为字符串类型的群组介绍,还需要设置android:category属性值为android.nfc.cardemulation.CardEmulation.CATEGORY_PAYMENT="payment"作为支付使用、或者属性值为android.nfc.cardemulation.CardEmulation.CATEGORY_OTHER="other"。在该标签内部,就可以嵌入多组<aid-filter / >标签并设置其android:name属性值,用以标记当前群组下的 AID 值。

Android系统编程入门系列之硬件交互——通信硬件NFC的更多相关文章

  1. Android系统编程入门系列之加载界面Activity

    上回说到应用初始化加载及其生命周期,在Android系统调用Applicaiton.onCreate()之后,继续创建并加载清单文件中注册的首个界面即主Activity,也可称之为入口界面.主Acti ...

  2. Android系统编程入门系列之硬件交互——多媒体摄像头

    多媒体系列硬件 多媒体包括图片.动画.音频.视频,这些多媒体素材的采集(输入)主要依靠摄像头和麦克风等硬件设备转化为基础数据,而他们的播放渲染(输出),则需要依靠具有相关功能的编解码软件.当然随着硬件 ...

  3. Android系统编程入门系列之硬件交互——传感器

    到目前为止,关于应用程序与用户之间的相关内容便比较肤浅的大致介绍完毕.而在整个系统架构中,应用程序与用户之间的交互,犹如参天大树上的枝干和树叶,交互起来五彩缤纷,但使整个生态系统保持生命力的核心,在于 ...

  4. Android系统编程入门系列之硬件交互——通信硬件USB

    在硬件交互的首篇对设备硬件的分类中,互联通信系列硬件主要用来与其他设备进行数据交互.从本文开始,将重点介绍该系列相关硬件. 互联通信系列硬件 根据硬件的可通信距离,由近及远分为USB.NFC.蓝牙.W ...

  5. Android系统编程入门系列之硬件交互——通信硬件Bluetooth

    通信硬件NFC的文章,虽然可以在Android系统中通过非直接接触的形式与支持NFC硬件的设备通信,但是也只能交互一些简短的标签内容,对大量的持续性数据,却并不能很好的支持.因此针对这个弊端,可以考虑 ...

  6. Android系统编程入门系列之硬件交互——多媒体展示

    前两篇文章通过麦克风硬件和摄像头硬件分别采集音频和视频的多媒体数据,在得到的多媒体数据通常是以编码文件的格式存储,在用户需要展示时,可通过设备的内置扩音器或蓝牙耳机等硬件播放音频,通过设备的显示屏或外 ...

  7. Android系统编程入门系列之硬件交互——无线通信WLAN

    Android系统的移动设备大多支持无线WLAN技术.利用该技术,不仅能实现互联网通信,还能实现无线定位,热点共享等远程通信功能.针对使用WLAN的不同功能,可能需要分别申请不同的权限声明,同时调用不 ...

  8. Android系统编程入门系列之硬件交互——通信硬件电信SIM卡

    现在的SIM卡通常具备基站定位.语音通话.短信消息.网络流量这四大功能,而在移动端是无法对SIM卡使用基站定位功能的,所以这里只介绍移动端如何使用SIM卡实现语音通话.短信消息.数据流量三个功能. 语 ...

  9. Android系统编程入门系列之界面Activity交互响应

    在上篇文章中已经了解到界面Activity的绘制完全依赖其加载的视图组件View,不仅如此,用户的每次触摸操作都可以在界面Activity内接收并响应,也可以直接传递给其中的某个视图View响应.本文 ...

随机推荐

  1. listitems.ListItemCollectionPosition属性为空

    SPListItemCollection listitems = list1.GetItems(query);//当执行完上面的代码后,listitems.ListItemCollectionPosi ...

  2. 谷歌浏览器(chrome)查找、打包已安装的扩展程序

    我们有时候会安装浏览器扩展程序,正常情况下,我们回去谷歌应用商店里面进行下载,但是这个需要VPN,有时候我们没法使用VPN,想从其他已安装扩展程序的浏览器上直接安装就可以使用我们下面这个方法 win1 ...

  3. 【LeetCode】621. Task Scheduler 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 公式法 日期 题目地址:https://leetco ...

  4. 第三十五个知识点:给针对ECDLP问题的Pollard rho,Pollard "Kangaroo",parallel Pollard rho攻击的一个粗略的描述

    第三十五个知识点:给针对ECDLP问题的Pollard rho,Pollard "Kangaroo",parallel Pollard rho攻击的一个粗略的描述 我们的目标是对任 ...

  5. 后缀树的建立-Ukkonen算法

    参考: Ukkonen算法讲解 Ukkonen算法动画 Ukkonen算法,以字符串abcabxabcd为例,先介绍一下运算过程,最后讨论一些我自己的理解. 需要维护以下三个变量: 当前扫描位置# 三 ...

  6. [开发配置]Linux系统配置开发环境

    deeplin系统配置开发环境 开发系统:deeplin 15.11 开发工具:Clion 2019.2 ; PyCharm 2019 ; Idea 2019;  Android Studio 开源库 ...

  7. TCP KeepAlive机制理解与实践小结

    0 前言 本文将主要通过抓包并查看报文的方式学习TCP KeepAlive机制,以此加深理解. 1 TCP KeepAlive机制简介 TCP长连接下,客户端和服务器若长时间无数据交互情况下,若一方出 ...

  8. 《手把手教你》系列技巧篇(五十三)-java+ selenium自动化测试-上传文件-上篇(详细教程)

    1.简介 在实际工作中,我们进行web自动化的时候,文件上传是很常见的操作,例如上传用户头像,上传身份证信息等.所以宏哥打算按上传文件的分类对其进行一下讲解和分享. 2.为什么selenium没有提供 ...

  9. emqx的一个配置参数

    这个参数尝试改为internal后,所有用户都可以匿名登录

  10. .NET 微服务——CI/CD(4):避坑和一点经验

    如果你看过之前几篇文章,应该已经Jenkins成功搭建了CICD环境,但是进入正式环境会有一些坑,不注意中招的话很难受,这里总结一下,避免重复消耗精力. 后门漏洞 Jenkins有后门,这是个老问题了 ...