鸿蒙OS 卡模拟功能
场景介绍
应用或者其他模块可以通过接口完成以下功能:
- 查询是否支持指定安全单元的卡模拟功能,安全单元包括 HCE(Host Card Emulation)、ESE(Embedded Secure Element)和SIM(Subscriber Identity Module)卡。
- 开关卡模拟以及查询卡模拟状态,可以打开或关闭指定技术类型的卡模拟。
- 获取 NFC 信息,信息包括当前激活的安全单元、 Hisee 上电状态、是否支持 RSSI 查询等信息。
- 根据 NFC 服务的类型获取刷卡时选择服务的方式,应用或者其它模块可以查询支付(Payment)类型和非支付(Other)类型业务选择服务的方式。
- 动态设置和注销前台优先应用。
- NFC 应用的 AID 相关操作,包括注册和删除应用的 AID、查询应用是否是指定 AID 的默认应用、获取应用的 AID 等。
- 定义 Host 和 OffHost 服务的抽象类,三方应用通过继承抽象类来实现 NFC 卡模拟功能。
接口说明
类名 | 接口名 | 功能描述 |
---|---|---|
CardEmulation | getInstance(NfcController controller) | 创建一个卡模拟类的实例。 |
isSupported(int feature) | 查询是否支持卡模拟功能。 | |
setListenMode(int mode) | 设置卡模拟模式。 | |
isListenModeEnabled() | 查询卡模拟功能是否打开。 | |
getNfcInfo(String key) | 获取 NFC 的信息。 | |
getSelectionType(String category) | 根据 NFC 服务的类型获取刷卡时选择服务的方式。 | |
registerForegroundPreferred(Ability appAbility, ElementName appName) | 动态设置前台优先应用。 | |
unregisterForegroundPreferred(Ability appAbility) | 取消设置前台优先应用。 | |
isDefaultForAid(ElementName appName, String aid) | 判断应用是否是指定 AID 的默认处理应用。 | |
registerAids(ElementName appName, String type, List<String> aids) | 给应用注册指定类型的AID。 | |
removeAids(ElementName appName, String type) | 删除应用的指定类型的 AID。 | |
getAids(ElementName appName, String type) | 获取应用中指定类型的 AID 列表。 | |
HostService | sendResponse(byte[] response) | 发送响应的数据到对端设备。 |
handleRemoteCommand(byte[] cmd, IntentParams params) | 处理对端设备发送的命令。 | |
disabledCallback(int errCode) | 连接异常的回调。 | |
OffHostService | onConnect(Intent intent) | 连接服务并获取远程服务对象。 |
查询是否支持卡模拟功能
- 调用 NfcController 类的 getInstance(Context context) 接口,获取 NfcController 实例。
- 调用 CardEmulation 类的 getInstance(NfcController controller) 接口,获取 CardEmulation 实例,去管理本机卡模拟模块操作。
- 调用 isSupported(int feature) 接口去查询是否 HCE、UICC、ESE 卡模拟。
// 获取NFC控制对象
NfcController nfcController = NfcController.getInstance(context);
// 获取卡模拟控制对象
CardEmulation cardEmulation = CardEmulation.getInstance(nfcController);
// 查询是否支持HCE、UICC、ESE卡模拟,返回值表示是否支持对应安全单元的卡模拟
boolean isSupportedHce = cardEmulation.isSupported(CardEmulation.FEATURE_HCE);
boolean isSupportedUicc = cardEmulation.isSupported(CardEmulation.FEATURE_UICC);
boolean isSupportedEse = cardEmulation.isSupported(CardEmulation.FEATURE_ESE);
开关卡模拟及查询卡模拟状态
- 调用 NfcController 类的 getInstance(Context context) 接口,获取 NfcController 实例。
- 调用 CardEmulation 类的 getInstance(NfcController controller) 接口,获取 CardEmulation 实例,去管理本机卡模拟模块操作。
- 调用 setListenMode(int mode) 接口去打开或者关闭卡模拟。
- 调用 isListenModeEnabled() 接口去查询卡模拟是否打开。
// 获取 NFC 控制对象
NfcController nfcController = NfcController.getInstance(context);
// 获取卡模拟控制对象
CardEmulation cardEmulation = CardEmulation.getInstance(nfcController);
// 打开卡模拟
cardEmulation.setListenMode(CardEmulation.ENABLE_MODE_ALL);
// 调用查询卡模拟开关状态的接口,返回值为卡模拟是否是打开的状态
boolean isEnabled = cardEmulation.isListenModeEnabled(); // true
// 关闭卡模拟
cardEmulation.setListenMode(CardEmulation.DISABLE_MODE_A_B);
// 调用查询卡模拟开关状态的接口,返回值为卡模拟是否是打开的状态
isEnabled = cardEmulation.isListenModeEnabled(); // false
获取 NFC 信息
- 调用 NfcController 类的 getInstance(Context context) 接口,获取 NfcController 实例。
- 调用 CardEmulation 类的getInstance(NfcController controller)接口,获取 CardEmulation 实例,去管理本机卡模拟模块操作。
- 调用 getNfcInfo(String key)接口去获取 NFC 信息。
// 获取NFC控制对象
NfcController nfcController = NfcController.getInstance(context);
// 获取卡模拟控制对象
CardEmulation cardEmulation = CardEmulation.getInstance(nfcController);
// 查询本机当前使能的安全单元类型
String seType = cardEmulation.getNfcInfo(CardEmulation.KEY_ENABLED_SE_TYPE); // ENABLED_SE_TYPE_ESE
// 查询Hisee上电状态
String hiseeState = cardEmulation.getNfcInfo(CardEmulation.KEY_HISEE_READY);
// 查询是否支持rssi的查询
String rssiAbility = cardEmulation.getNfcInfo(CardEmulation.KEY_RSSI_SUPPORTED);
根据NFC服务的类型获取刷卡时选择服务的方式
- 调用 NfcController 类的 getInstance(Context context) 接口,获取 NfcController 实例。
- 调用 CardEmulation 类的 getInstance(NfcController controller) 接口,获取 CardEmulation 实例,去管理本机卡模拟模块操作。
- 调用 getSelectionType(Sring category) 接口去获取选择服务的方式。
// 获取NFC控制对象
NfcController nfcController = NfcController.getInstance(context);
// 获取卡模拟控制对象
CardEmulation cardEmulation = CardEmulation.getInstance(nfcController);
// 获取选择服务的方式
int result = cardEmulation.getSelectionType(CardEmulation.CATEGORY_PAYMENT); // SELECTION_TYPE_PREFER_DEFAULT
result = cardEmulation.getSelectionType(CardEmulation.CATEGORY_OTHER); // SELECTION_TYPE_ASK_IF_CONFLICT
动态设置和注销前台优先应用
- 调用 NfcController 类的 getInstance(Context context)接口,获取 NfcController 实例。
- 调用 CardEmulation 类的 getInstance(NfcController controller) 接口,获取 CardEmulation 实例,去管理本机卡模拟模块操作。
- 调用 registerForegroundPreferred(Ability appAbility, ElementName appName)接口去动态设置前台优先应用。
- 调用 unregisterForegroundPreferred(Ability appAbility)接口去取消设置前台优先应用。
// 获取NFC控制对象
NfcController nfcController = NfcController.getInstance(context);
// 获取卡模拟控制对象
CardEmulation cardEmulation = CardEmulation.getInstance(nfcController);
// 动态设置前台优先应用
cardEmulation.registerForegroundPreferred(new Ability(), new ElementName());
// 注销前台优先应用
cardEmulation.unregisterForegroundPreferred(new Ability());
NFC 应用的 AID 相关操作
- 调用 NfcController 类的 getInstance(Context context) 接口,获取 NfcController 实例。
- 调用 CardEmulation 类的 getInstance(NfcController controller)接口,获取 CardEmulation 实例,去管理本机卡模拟模块操作。
- 调用 registerAids(ElementName appName, String type, List<String> aids) 接口去给应用注册指定类型的 AID。
- 调用 removeAids(ElementName appName, String type) 接口去删除应用的指定类型的 AID。
- 调用 isDefaultForAid(ElementName appName, String aid) 接口去判断应用是否是指定 AID 的默认处理应用。
- 调用 getAids(ElementName appName, String type) 接口去获取应用中指定类型的 AID 列表。
// 获取NFC控制对象
NfcController nfcController = NfcController.getInstance(context);
// 获取卡模拟控制对象
CardEmulation cardEmulation = CardEmulation.getInstance(nfcController);
// 给应用注册指定类型的AID
List<String> aids = new ArrayList<String>();
aids.add(0, "A0028321901280");
aids.add(1, "A0028321901281");
try { cardEmulation.registerAids(new ElementName(), CardEmulation.CATEGORY_PAYMENT, aids);
} catch (IllegalArgumentException e) {
HiLog.error(LABEL, "IllegalArgumentException when registerAids");
}
// 删除应用的指定类型的AID
cardEmulation.removeAids(new ElementName(), CardEmulation.CATEGORY_PAYMENT);
cardEmulation.removeAids(new ElementName(), CardEmulation.CATEGORY_OTHER);
// 判断应用是否是指定AID的默认处理应用
String aid = "A0028321901280";
cardEmulation.isDefaultForAid(new ElementName(), aid);
// 获取应用中指定类型的AID列表
try {
cardEmulation.getAids(new ElementName(), CardEmulation.CATEGORY_PAYMENT);
} catch (NullPointerException e) {
HiLog.error(LABEL, "NullPointerException when getAids");
} catch (IllegalArgumentException e) {
HiLog.error(LABEL, "IllegalArgumentException when getAids");
}
Host服务的抽象类
- 三方应用的服务继承 HostService,实现 HCE 卡模拟功能。
- 三方应用自定义实现抽象方法handleRemoteCommand(byte[] cmd, IntentParams params)和disabledCallback()。
- 三方应用自定义功能。
// 三方HCE应用的服务继承HostService,实现HCE卡模拟功能
public class AppService extends HostService {
@Override
public byte[] handleRemoteCommand(byte[] cmd, IntentParams params) {
// 三方应用自定义接口实现。
}
@Override
public void disabledCallback(int errCode) {
// 三方应用自定义接口实现。
}
// 三方应用自定义功能
}