Near Field Communication (NFC) is a high-frequency radio technology that enables communication between devices over a distance less than 10 cm. NFC operates at 13.56 MHz. Host Card Emulation (HCE) provides card emulation that does not depend on a secure element. It allows an application to emulate a card and communicate with an NFC card reader through the NFC service.
An application emulates a card and communicates with an NFC card reader through the NFC service. The device can communicate with an NFC card reader by using a started application (foreground mode) or without starting an application (background mode).
HCE foreground mode
The application started by the user communicates with the NFC card reader. Specifically, the user starts the application, opens the application page, and taps the device on the NFC card reader. In this case, the transaction data is distributed only to the foreground application.
HCE background mode
The user taps the device on an NFC card reader without starting any HCE application. Then, the device selects an HCE application based on the application ID (AID) provided by the NFC card reader, and completes the card swiping transaction. If multiple HCE applications are matched, a conflict occurs. In this case, the user needs to open the application to complete card swiping.
Constraints
No natter whether the foreground mode or background mode is used, the NFC service can be implemented only when the device screen is unlocked and illuminated.
For details about the JS APIs and sample code, NFC Card Emulation.
The following table describes the APIs for implementing HCE.
API | Description |
---|---|
start(elementName: ElementName, aidList: string[]): void | Starts HCE, including enabling this application to run in the foreground preferentially and dynamically registering the AID list. |
stop(elementName: ElementName): void | Stops HCE, including canceling the subscription of APDU data, exiting this application from the foreground, and releasing the dynamically registered AID list. |
on(type: 'hceCmd', callback: AsyncCallback<number[]>): void | Registers a callback to receive APDUs from the peer card reader. |
transmit(response: number[]): Promise<void> | Transmits APDU data to the peer card reader. |
"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 '@ohos.nfc.cardEmulation';
import { BusinessError } from '@ohos.base';
import bundleManager from '@ohos.bundle.bundleManager'
let hceElementName: bundleManager.ElementName;
let hceService: cardEmulation.HceService;
async function hceCommandCb(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');
// Check whether the device supports the NFC and HCE capabilities.
if (!canIUse("System.Capability.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 is brought to foreground.
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
if (hceElementName != undefined) {
try {
// Enable the foreground HCE application to preferentially process NFC card swiping.
let aidList = ["A0000000031010", "A0000000031011"]; // Change the AIDs to match your case.
hceService.start(hceElementName, aidList);
// Subscribe to the reception of HCE APDU data.
hceService.on('hceCmd', hceCommandCb);
} catch (error) {
hilog.error(0x0000, 'testTag', 'hceService.start error = %{public}s', JSON.stringify(error));
}
}
}
onBackground() {
// Ability is in the background.
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
// When exiting the NFC tag page of the application, call the tag module API to exit the foreground mode.
if (hceElementName != undefined) {
try {
hceService.stop(hceElementName);
} catch (error) {
hilog.error(0x0000, 'testTag', 'hceService.stop error = %{public}s', JSON.stringify(error));
}
}
}
}
"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 '@ohos.nfc.cardEmulation';
import { BusinessError } from '@ohos.base';
import bundleManager from '@ohos.bundle.bundleManager'
let hceElementName : bundleManager.ElementName;
let hceService: cardEmulation.HceService;
async function hceCommandCb(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');
// Check whether the device supports the NFC and HCE capabilities.
if (!canIUse("System.Capability.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 is 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');
// When exiting the NFC tag page of the application, call the tag module API to exit the foreground mode.
if (hceElementName != undefined) {
try {
hceService.stop(hceElementName);
} catch (error) {
hilog.error(0x0000, 'testTag', 'hceService.stop error = %{public}s', JSON.stringify(error));
}
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。