HCE卡模拟开发指南

HCE卡模拟开发指南

文章目录

一、简介二、场景介绍三、接口说明四、开发步骤

一、简介

近场通信(Near Field Communication,NFC)是一种短距高频的无线电技术,在13.56MHz频率运行,通信距离一般在10厘米距离内。HCE(Host Card Emulation),称为基于主机的卡模拟,表示不依赖安全单元芯片,电子设备上的应用程序模拟NFC卡片和NFC读卡器通信,实现NFC刷卡业务。

二、场景介绍

应用程序模拟NFC卡片,和NFC读卡器通信完成NFC刷卡业务。从使用场景上,可以分成HCE应用前台刷卡,和HCE应用后台刷卡。

HCE应用前台刷卡

前台刷卡是指在触碰NFC读卡器之前,用户先在电子设备上打开特定的应用程序,用户明确想使用所打开的应用程序和NFC读卡器进行刷卡操作。用户打开应用程序在前台,并且进入应用的刷卡页面之后,电子设备触碰NFC读卡器,只会把刷卡交易数据分发给前台应用。

HCE应用后台刷卡

后台刷卡是指不打开特定的HCE应用程序,电子设备触碰NFC读卡器后,根据NFC读卡器选择的应用ID(AID)匹配到HCE应用程序,并自动和匹配的HCE应用程序通信完成刷卡交易。如果匹配到多个HCE应用程序时,说明存在冲突,需要用户打开指定的应用才能完成刷卡。

HCE应用刷卡的约束条件

1、不管是HCE应用前台还是后台刷卡,能够完成HCE应用程序NFC刷卡的条件是电子设备需要亮屏解锁。

2、module.json5文件中需要声明nfc卡模拟权限,具体见示例。

3、前台应用时需要调用start和stop注册和去注册AID,具体见示例。

三、接口说明

NFC卡模拟完整的JS API说明以及实例代码请参考:NFC卡模拟接口。

完成HCE卡模拟功能,可能使用到下面的接口。

接口名功能描述start(elementName: ElementName, aidList: string[]): void启动HCE业务功能。包括设置当前应用为前台优先,动态注册AID列表。stop(elementName: ElementName): void停止HCE业务功能。包括取消APDU数据接收的订阅,退出当前应用前台优先,释放动态注册的AID列表。on(type: ‘hceCmd’, callback: AsyncCallback): void订阅回调,用于接收对端读卡设备发送的APDU数据。transmit(response: number[]): Promise发送APDU数据到对端读卡设备。

四、开发步骤

HCE应用前台刷卡

在module.json5文件中声明NFC卡模拟权限,以及声明HCE特定的action。import需要的NFC卡模拟模块和其他相关的模块。判断设备是否支持NFC能力和HCE能力。使能前台HCE应用程序优先处理NFC刷卡功能。订阅HCE APDU数据的接收。完成HCE刷卡APDU数据的接收和发送。退出应用程序NFC刷卡页面时,退出前台优先功能。

"abilities": [

{

"name": "EntryAbility",

"srcEntry": "./ets/entryability/EntryAbility.ts",

"description": "$string:EntryAbility_desc",

"icon": "$media:icon",

"label": "$string:EntryAbility_label",

"startWindowIcon": "$media:icon",

"startWindowBackground": "$color:start_window_background",

"exported": true,

"skills": [

{

"entities": [

"entity.system.home"

],

"actions": [

"action.system.home",

// Add the nfc card emulation action to filter out for this application.

"ohos.nfc.cardemulation.action.HOST_APDU_SERVICE"

]

}

]

}

],

"requestPermissions": [

{

// Add the permission for nfc card emulation.

"name": "ohos.permission.NFC_CARD_EMULATION",

"reason": "$string:app_name",

}

]

import { cardEmulation } from '@kit.ConnectivityKit';

import { BusinessError } from '@kit.BasicServicesKit';

import { hilog } from '@kit.PerformanceAnalysisKit';

import { AsyncCallback } from '@kit.BasicServicesKit';

import { AbilityConstant, UIAbility, Want, bundleManager } from '@kit.AbilityKit';

let hceElementName: bundleManager.ElementName;

let hceService: cardEmulation.HceService;

const hceCommandCb : AsyncCallback = (error : BusinessError, hceCommand : number[]) => {

if (!error) {

if (hceCommand == null || hceCommand == undefined) {

hilog.error(0x0000, 'testTag', 'hceCommandCb has invalid hceCommand.');

return;

}

// check the command, then transmit the response.

hilog.info(0x0000, 'testTag', 'hceCommand = %{public}s', JSON.stringify(hceCommand));

let responseData = [0x90, 0x00]; // change the response depend on different received command.

hceService.transmit(responseData).then(() => {

hilog.info(0x0000, 'testTag', 'hceService transmit Promise success.');

}).catch((err: BusinessError) => {

hilog.error(0x0000, 'testTag', 'hceService transmit Promise error = %{public}s', JSON.stringify(err));

});

} else {

hilog.error(0x0000, 'testTag', 'hceCommandCb error %{public}s', JSON.stringify(error));

}

}

export default class EntryAbility extends UIAbility {

onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {

hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');

// 判断设备是否支持NFC能力和HCE能力

if (!canIUse("SystemCapability.Communication.NFC.Core")) {

hilog.error(0x0000, 'testTag', 'nfc unavailable.');

return;

}

if (!cardEmulation.hasHceCapability()) {

hilog.error(0x0000, 'testTag', 'hce unavailable.');

return;

}

hceElementName = {

bundleName: want.bundleName ?? '',

abilityName: want.abilityName ?? '',

moduleName: want.moduleName,

}

hceService = new cardEmulation.HceService();

}

onForeground() {

// Ability has brought to foreground

hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');

if (hceElementName != undefined) {

try {

// 调用接口使能前台HCE应用程序优先处理NFC刷卡功能

let aidList = ["A0000000031010", "A0000000031011"]; // change aid tobe correct.

hceService.start(hceElementName, aidList);

// 订阅HCE APDU数据的接收

hceService.on('hceCmd', hceCommandCb);

} catch (error) {

hilog.error(0x0000, 'testTag', 'hceService.start error = %{public}s', JSON.stringify(error));

}

}

}

onBackground() {

// Ability has back to background

hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');

// 退出应用程序NFC标签页面时,调用tag模块退出前台优先功能

if (hceElementName != undefined) {

try {

hceService.stop(hceElementName);

} catch (error) {

hilog.error(0x0000, 'testTag', 'hceService.stop error = %{public}s', JSON.stringify(error));

}

}

}

}

HCE应用后台刷卡

在module.json5文件中声明NFC卡模拟权限,声明HCE特定的action,声明应用能够处理的AID。import需要的NFC卡模拟模块和其他相关的模块。判断设备是否支持NFC能力和HCE能力。订阅HCE APDU数据的接收。完成HCE刷卡APDU数据的接收和发送。退出应用程序时,退出订阅功能。

"abilities": [

{

"name": "EntryAbility",

"srcEntry": "./ets/entryability/EntryAbility.ts",

"description": "$string:EntryAbility_desc",

"icon": "$media:icon",

"label": "$string:EntryAbility_label",

"startWindowIcon": "$media:icon",

"startWindowBackground": "$color:start_window_background",

"exported": true,

"skills": [

{

"entities": [

"entity.system.home"

],

"actions": [

"action.system.home",

// Add the nfc card emulation action to filter out for this application.

"ohos.nfc.cardemulation.action.HOST_APDU_SERVICE"

]

}

],

"metadata": [

{

"name": "payment-aid",

"value": "A0000000031010" // change it tobe correct

},

{

"name": "other-aid",

"value": "A0000000031011" // change it tobe correct

}

]

}

],

"requestPermissions": [

{

// Add the permission for nfc card emulation.

"name": "ohos.permission.NFC_CARD_EMULATION",

"reason": "$string:app_name",

}

]

import { cardEmulation } from '@kit.ConnectivityKit';

import { BusinessError } from '@kit.BasicServicesKit';

import { hilog } from '@kit.PerformanceAnalysisKit';

import { AsyncCallback } from '@kit.BasicServicesKit';

import { AbilityConstant, UIAbility, Want, bundleManager } from '@kit.AbilityKit';

let hceElementName : bundleManager.ElementName;

let hceService: cardEmulation.HceService;

const hceCommandCb : AsyncCallback = (error : BusinessError, hceCommand : number[]) => {

if (!error) {

if (hceCommand == null || hceCommand == undefined) {

hilog.error(0x0000, 'testTag', 'hceCommandCb has invalid hceCommand.');

return;

}

// check the command, then transmit the response.

hilog.info(0x0000, 'testTag', 'hceCommand = %{public}s', JSON.stringify(hceCommand));

let responseData = [0x90, 0x00]; // change the response depend on different received command.

hceService.transmit(responseData).then(() => {

hilog.info(0x0000, 'testTag', 'hceService transmit Promise success.');

}).catch((err: BusinessError) => {

hilog.error(0x0000, 'testTag', 'hceService transmit Promise error = %{public}s', JSON.stringify(err));

});

} else {

hilog.error(0x0000, 'testTag', 'hceCommandCb error %{public}s', JSON.stringify(error));

}

}

export default class EntryAbility extends UIAbility {

onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {

hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');

// 判断设备是否支持NFC能力和HCE能力

if (!canIUse("SystemCapability.Communication.NFC.Core")) {

hilog.error(0x0000, 'testTag', 'nfc unavailable.');

return;

}

if (!cardEmulation.hasHceCapability()) {

hilog.error(0x0000, 'testTag', 'hce unavailable.');

return;

}

hceElementName = {

bundleName: want.bundleName ?? '',

abilityName: want.abilityName ?? '',

moduleName: want.moduleName,

}

hceService = new cardEmulation.HceService();

hceService.on('hceCmd', hceCommandCb);

}

onForeground() {

// Ability has brought to foreground

hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');

}

onDestroy() {

// Ability has back to destroy

hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');

// 退出应用程序NFC标签页面时,调用tag模块退出前台优先功能

if (hceElementName != undefined) {

try {

hceService.stop(hceElementName);

} catch (error) {

hilog.error(0x0000, 'testTag', 'hceService.stop error = %{public}s', JSON.stringify(error));

}

}

}

}

相关推荐

圆字康熙字典多少画
365bet苹果版

圆字康熙字典多少画

📅 08-06 👁️ 384
htc怎么恢复出厂设置 两个方法来帮你【教程】
365bet苹果版

htc怎么恢复出厂设置 两个方法来帮你【教程】

📅 07-22 👁️ 1921
天生赢家NaVi击穿银河战舰FaZe,小李子五年终夺哥本哈根Major冠军!
窗帘纱帘在里面还是外面 窗帘的种类
beat365中国

窗帘纱帘在里面还是外面 窗帘的种类

📅 09-26 👁️ 8712
彩虹岛攻略及主线任务流程 附新手平民提升战力教程
如何在 Windows 11 中隐藏文件:7 种免费方法 ▷➡️
秒付钱包支持哪个平台,秒付钱包能在哪些平台上使用?
佳茵对哪些妇科病有治疗作用
365bet苹果版

佳茵对哪些妇科病有治疗作用

📅 08-12 👁️ 4546
【情報】《無夜國度2~新月的花嫁》官網公開+故事概要公開+特典介紹 @無夜國度 哈啦板