NFC开发概述
NFC(Near Field Communication,近距离无线通信技术) 是一种非接触式识别和互联技术,让移动设备、消费类电子产品、PC和智能设备之间可以进行近距离无线通信。
HarmonyOS的NFC提供的功能有:
NFC基础查询:在进行NFC功能开发之前,开发者应该先确认设备是否支持NFC功能、NFC是否打开等基本信息。
访问安全单元(Secure Element,简称为SE):SE可用于保存重要信息,应用可以访问指定SE,并发送数据到SE上。
卡模拟:设备可以模拟卡片,替代卡片完成对应操作,如模拟门禁卡、公交卡等。
NFC消息通知:通过这个模块,开发者可以获取NFC开关状态改变的消息以及NFC的场强消息。
NFC基础查询
要进行NFC功能开发,需要设备支持NFC功能。
开发者可以通过NfcController类的方法isNfcAvailable()来确认设备是否支持NFC功能。如果设备支持NFC功能,可通过isNfcOpen()来查询NFC的开关状态。示例代码如下:
// 查询本机是否支持NFC if (context != null) { NfcController nfcController = NfcController.getInstance(context); } else { return; } boolean isAvailable = nfcController.isNfcAvailable(); if (isAvailable) { // 调用查询NFC是否打开接口,返回值为NFC是否是打开的状态 boolean isOpen = nfcController.isNfcOpen(); }
访问安全单元
场景介绍
安全单元(Secure Element,简称为SE)可用于保存重要信息,应用或者其他模块可以通过接口完成以下功能:
获取安全单元的个数和名称。
判断安全单元是否在位。
在指定安全单元上打开基础通道。
在指定安全单元上打开逻辑通道。
发送APDU(Application Protocol Data Unit)数据到安全单元上。
接口说明
表1 NFC访问安全单元功能的的主要接口
开发步骤
1.调用SEService类的构造函数,创建一个安全单元服务的实例,用于访问安全单元。
2.调用isConnected()接口,查询安全单元服务的连接状态。
3.调用getReaders()接口,获取本机的全部安全单元。
4.调用Reader类的openSession()接口打开Session,返回一个打开的Session实例。
5.调用Session类的openBasicChannel(Aid aid)接口打开基础通道,或者调openLogicalChannel(Aid aid)接口打开逻辑通道,返回一个打开通道Channel实例。
6.调用Channel类的transmit(byte[] command),发送APDU到安全单元。
7.调用Channel类的closeChannel()接口关闭通道。
8.调用Session类的closeSessionChannels()接口关闭Session的所有通道。
9.调用Reader类的closeSessions()接口关闭安全单元的所有Session。
10.调用SEService类的shutdown()接口关闭安全单元服务。
private static final String ESE = "eSE"; private class AppServiceConnectedCallback implements SEService.OnCallback { @Override public void serviceConnected() { // 应用自实现 } } // 创建安全单元服务实例 SEService sEService = new SEService(context, new AppServiceConnectedCallback()); // 查询安全单元服务的连接状态 boolean isConnected = sEService.isConnected(); // 获取本机的全部安全单元,并获取指定的安全单元eSE Reader[] elements = sEService.getReaders(); Reader eSe = null; for (int i = 0; i < elements.length; i++) { if (ESE.equals(elements[i].getName())) { eSe = elements[i]; break; } } if (eSe == null) { return; } // 查询安全单元是否在位 boolean isPresent = eSe.isSecureElementPresent(); // 打开Session Optional<Session> optionalSession = eSe.openSession(); Session session = optionalSession.orElse(null); if (session == null) { return; } // 打开通道 if (eSe != null) { byte[] aidValue = new byte[]{(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05}; // 创建Aid实例 Aid aid = new Aid(aidValue, 0, aidValue.length); // 打开基础通道 Optional<Channel> optionalChannel = session.openBasicChannel(aid); Channel basicChannel = optionalChannel.orElse(null); // 打开逻辑通道 optionalChannel = session.openLogicalChannel(aid); Channel logicalChannel = optionalChannel.orElse(null); // 发送指令给安全单元,返回值为安全单元对指令的响应 byte[] resp = logicalChannel.transmit(new byte[]{(byte)0x00, (byte)0xa4, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x00}); // 关闭通道资源 if (optionalChannel.isPresent()) { basicChannel.closeChannel(); } if (optionalChannel .isPresent()) { logicalChannel.closeChannel(); } // 关闭Session资源 session.close(); // 关闭安全单元资源 eSe.closeSessions(); // 关闭安全单元服务资源 sEService.shutdown();