FC代表近场通讯,其全方位的测量精度可以达到厘米。这项技术也促进了其它一些好玩的技术的成长,如把两个手机碰到一起就可以启动一个多人游戏,把手机贴近NFC读写器就可以进行付款了。
在Android4.4之前,NFC支付过程需要通过借助设备上一个专有的安全部件(Secure Element,可以存在SIM卡中),使用本地存储的方式,关联设备本身的某种支付方式。这样的话其它的APP就很难通过NFC进行支付操作,因为这个过程是依靠部分硬件的,也就是Secure Element,现在的问题就是像Sprint通信公司或者Verizon通信公司的这个载体部件,应该让APP可以使用这个硬件功能。
基于主机的卡仿真技术
基于主机的卡仿真(HCE)是Android4.4的一项新技术,可以让app绕过Secure Element,然后使用云端支付信息或者其它方式存储的支付信息来模拟一个NFC卡。有了HCE,任何APP都可以模拟一个NFC卡,而且任意一台Android设备可以当做NFC读写器。
检测HCE功能就需要看看 FEATURE_NFC_HOST_CARD_EMULATION。
1 2 3 |
; html-script: false ] PackageManager pm = context.getPackageManager(); boolean hasNfcHce = pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION); |
需要在AndroidManifest.xml中声明应用程序需要使用HCE功能:
1 2 3 |
; html-script: false ] <uses-permission android:name="android.permission.NFC" /> <uses-feature android:name="android.hardware.nfc.hce" ... /> |
HCE需要实现为一个服务(service),Android中的服务可以运行在后台,启动后不用和用户进行交互。此服务可以让NFC在使用时不需要用户首先打开APP。在Android4.4中新增了 HostApduService,继承它然后创建一个服务来处理近场通讯:
1 2 3 4 5 6 7 8 |
; html-script: false ] public class NfcHceService extends HostApduService { @Override public byte[] processCommandApdu(byte[] apdu, Bundle extras) { … } @Override public void onDeactivated(int reason) { … } } |
这个NfcHceService需要覆盖两个方法:processCommandApdu()和onDeactivated()。APDU(Application Protocol Data Unit)是NFC读写器发送给NfcHceService的数据单元,然后processCommandApdu()方法回送一个响应APDU。在NFC读写器和另外一个HCE服务通信或者设备不在NFC读写器的范围内时,onDeactivated()方法会被调用。
注意还要在AndroidManifest.xml中声明服务:
1 2 3 4 5 6 7 8 9 10 |
; html-script: false ] <service android:name=".NfcHceService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"> <intent-filter> <action android:name="android.nfc.cardemulation.HOST_APDU_SERVICE" /> </intent-filter> <meta-data android:name="android.nfc.cardemulation.host_apdu_service" android:resource="@xml/hceService" /> </service> |
这个hceService.xml资源文件在meta-data标签里声明,告诉Android系统到哪里去寻找Application的ID组。
Application ID
Application ID (AID)可以让NFC读写器识别出设备需要读哪一张模拟卡(在processCommandApdu()方法中需要得到一个响应)。AID是由ISO/IEC 7816-5(International Organization for Standardization and the International Electrotechnical Commission)制定的,Android设备要想作为NFC读写器,必须注册一个AID。
这里在hceService.xml中定义了一个application的AID组,在此场景中,它就是一个用于支付的组(使用CardEmulation.CATEGORY而不是用其它的组CATEGORY_OTHER)。在这个支付组的AID的应用程序还需要有一个260*96dp的资源,为apduServiceBanner服务。
1 2 3 4 5 6 7 8 9 10 11 |
; html-script: false ] <host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/my_app_hce_service" android:requireDeviceUnlock="false" android:apduServiceBanner="@drawable/my_app_service_banner"> <aid-group android:description="@string/my_app_aid_group" android:category="payment"> <aid-filter android:name="4111111111111111"/> <aid-filter android:name="0123456789ABCDEF"/> </aid-group> </host-apdu-service> |
HCE简化了开启NFC功能,把它从载体部件中解脱出来(不用依赖Secure Element的载体了),解除了其它的设备等相关的限制。
想要了解更多关于给予主机的卡仿真技术可以看看这里 Host-based Card Emulation
本文是KitKat Developer’s Guide的第六篇,请持续关注更新或者在 twitter上关注我们