本文旨在深入探讨华为鸿蒙HarmonyOS Next系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。
在智能设备的交互领域,NFC(Near Field Communication,近场通信)技术以其便捷、快速的特点,为用户带来了诸多便利。HarmonyOS Next中的NFC模块更是将这种便利发挥到了极致,涵盖了从标签读写到卡模拟等丰富功能,为开发者提供了广阔的创新空间。今天,我们就深入探究HarmonyOS Next中NFC模块的奇妙世界,看看如何利用它为用户打造更加智能、高效的体验。
一、NFC模块功能概述
HarmonyOS Next的NFC模块主要提供了以下几个方面的功能:
1. NFC标签读写
设备可以通过NFC通信技术与NFC标签进行交互,读取标签中存储的数据,或者向标签写入新的数据。这一功能在很多场景中都有广泛应用,比如在智能公交卡充值、图书馆书籍借阅管理、商品信息查询等方面,用户只需将设备靠近NFC标签,就能轻松完成相应操作。
2. NFC卡模拟(HCE)
应用程序可以模拟NFC卡片,与NFC读卡器进行通信,实现NFC刷卡业务。这使得电子设备能够替代传统的实体卡片,如银行卡、门禁卡等,为用户提供更加便捷的支付和门禁通行方式。例如,用户在乘坐地铁时,无需拿出实体交通卡,只需使用手机模拟的交通卡靠近闸机读卡器,即可完成刷卡进站。
二、NFC标签读写详解
1. 技术类型与应用场景
NFC标签可能支持多种通信技术,不同技术类型适用于不同的应用场景。
NFC技术类型 | 应用场景 |
---|---|
NfcA(ISO 14443 - 3A) | 广泛应用于门禁卡、公交卡等场景,如常见的城市公交一卡通系统。 |
NfcB(ISO 14443 - 3B) | 在一些特定的门禁系统或会员卡系统中使用。 |
NfcF(JIS 6319 - 4) | 主要在日本等地区用于电子钱包、交通卡等应用。 |
NfcV(ISO 15693) | 常用于物流管理、图书管理等领域,实现物品的快速识别和信息读取。 |
IsoDep | 支持与符合ISO 7816标准的智能卡进行通信,可用于电子护照、银行卡等安全要求较高的应用。 |
NDEF | 用于存储和交换格式化的数据,如文本、URL等,在信息共享和传输方面有广泛应用,例如分享联系人信息、Wi-Fi密码等。 |
MifareClassic | 常用于门禁控制、会员卡等场景,具有较高的安全性和稳定性。 |
MifareUltralight | 适用于简单的数据存储和识别应用,如活动门票、优惠券等。 |
2. 前台标签读取实现
前台标签读取是指用户在触碰NFC标签之前,先打开特定的应用程序,明确使用该应用与NFC标签进行读写操作。以下是实现前台标签读取的关键步骤和API调用示例:
首先,在module.json5
文件中声明NFC标签读取的权限以及相关action:
{
"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",
"ohos.nfc.tag.action.TAG_FOUND"
]
}
]
}
],
"requestPermissions": [
{
"name": "ohos.permission.NFC_TAG",
"reason": "$string:app_name"
}
]
}
然后,在应用代码中进行以下操作:
import { tag } from '@kit.ConnectivityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
// 判断设备是否支持NFC能力
if (!canIUse("SystemCapability.Communication.NFC.Core")) {
hilog.error(0x0000, 'testTag', 'nfc unavailable.');
return;
}
// 调⽤tag模块中前台优先的接⼝,使能前台应⽤程序优先处理所发现的NFC标签功能
tag.enableForegroundDispatch((result) => {
if (result === 0) {
hilog.info(0x0000, 'testTag', 'enableForegroundDispatch success');
} else {
hilog.error(0x0000, 'testTag', 'enableForegroundDispatch failed with error code:'+ result);
}
});
// 获取特定技术类型的NFC标签对象(以NfcA为例)
tag.getNfcA(tagInfo).then((nfcATag) => {
// 执行读写接口完成标签数据的读取或写入数据到标签
// 例如,读取标签数据
nfcATag.read().then((data) => {
hilog.info(0x0000, 'testTag', 'Read data from NFC tag:'+ JSON.stringify(data));
}).catch((err) => {
hilog.error(0x0000, 'testTag', 'Error reading NFC tag:'+ JSON.stringify(err));
});
}).catch((err) => {
hilog.error(0x0000, 'testTag', 'Error getting NfcA tag object:'+ JSON.stringify(err));
});
// 退出应⽤程序NFC标签页面时,调⽤tag模块退出前台优先功能
tag.disableForegroundDispatch((result) => {
if (result === 0) {
hilog.info(0x0000, 'testTag', 'disableForegroundDispatch success');
} else {
hilog.error(0x0000, 'testTag', 'disableForegroundDispatch failed with error code:'+ result);
}
});
3. 后台标签识别实现
后台标签识别是指设备在未打开特定NFC标签应用程序的情况下,触碰发现NFC标签后,根据标签的技术类型,分发给能够处理的应用程序。如果匹配到多个应用程序,则弹出应用选择器让用户手动选择。
在module.json5
文件中声明NFC标签读取的权限、相关action以及应用能够处理的AID(应用程序标识符):
{
"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",
"ohos.nfc.tag.action.TAG_FOUND"
]
]
},
"metadata": [
{
"name": "payment-aid",
"value": "A0000000031010"
},
{
"name": "other-aid",
"value": "A0000000031011"
}
]
}
],
"requestPermissions": [
{
"name": "ohos.permission.NFC_TAG",
"reason": "$string:app_name"
}
]
}
在应用代码中,主要是订阅标签发现事件,当检测到符合条件的标签时,进行相应处理:
import { tag } from '@kit.ConnectivityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
// 判断设备是否支持NFC能力
if (!canIUse("SystemCapability.Communication.NFC.Core")) {
hilog.error(0x0000, 'testTag', 'nfc unavailable.');
return;
}
// 订阅标签发现事件
tag.on('tagFound', (tagInfo) => {
hilog.info(0x0000, 'testTag', 'NFC tag found:'+ JSON.stringify(tagInfo));
// 根据标签信息进行处理,例如获取标签类型并根据业务逻辑进行相应操作
const techList = tagInfo.techList;
if (techList.includes('NfcA')) {
// 处理NfcA类型标签
handleNfcATag(tagInfo);
} else if (techList.includes('NfcB')) {
// 处理NfcB类型标签
handleNfcBTag(tagInfo);
}
});
三、NFC卡模拟(HCE)实现
1. HCE应用场景
HCE在很多场景中都具有重要应用价值。例如,在移动支付领域,用户可以将银行卡信息模拟到手机中,在支持NFC支付的终端上进行刷卡消费,无需携带实体银行卡;在门禁系统中,手机模拟门禁卡,方便用户进出办公场所或住宅小区。
2. HCE卡模拟实现示例
以下是一个简单的HCE卡模拟的基本代码示例,包括前台刷卡和后台刷卡的部分实现。
前台刷卡:
在module.json5
文件中声明NFC卡模拟权限和HCE特定的action:
{
"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",
"ohos.nfc.cardemulation.action.HOST_APDU_SERVICE"
]
]
},
"metadata": []
}
],
"requestPermissions": [
{
"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<number[]> = (error: BusinessError, hceCommand: number[]) => {
if (!error) {
if (hceCommand == null || hceCommand == undefined) {
hilog.error(0x0000, 'testTag', 'hceCommandCb has invalid hceCommand.');
return;
}
// 根据接收到的命令进行处理,然后发送响应
let responseData = [0x90, 0x00]; // 根据不同命令修改响应数据
hceService.transmit(responseData).then(() => {
hilog.info(0x0000, 'testTag', 'hceService transmit Promise success.');
}).catch((err: BusinessError) => {
hilog.error(0x0000, 'testTag', 'hceService transmit Promise error ='+ JSON.stringify(err));
});
} else {
hilog.error(0x0000, 'testTag', 'hceCommandCb error'+ 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() {
// 使能前台HCE应用程序优先处理NFC刷卡功能
let aidList = ["A0000000031010", "A0000000031011"]; // 根据实际情况修改AID
hceService.start(hceElementName, aidList);
// 订阅HCE APDU数据的接收
hceService.on('hceCmd', hceCommandCb);
}
onBackground() {
// 退出应用程序NFC标签页面时,退出前台优先功能
hceService.stop(hceElementName);
}
}
后台刷卡:
在module.json5
文件中声明NFC卡模拟权限、HCE特定的action以及应用能够处理的AID:
{
"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",
"ohos.nfc.cardemulation.action.HOST_APDU_SERVICE"
]
]
},
"metadata": [
{
"name": "payment-aid",
"value": "A0000000031010"
},
{
"name": "other-aid",
"value": "A0000000031011"
}
]
}
],
"requestPermissions": [
{
"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<number[]> = (error: BusinessError, hceCommand: number[]) => {
if (!error) {
if (hceCommand == null || hceCommand == undefined) {
hilog.error(0x0000, 'testTag', 'hceCommandCb has invalid hceCommand.');
return;
}
// 根据接收到的命令进行处理,然后发送响应
let responseData = [0x90, 0x00]; // 根据不同命令修改响应数据
hceService.transmit(responseData).then(() => {
hilog.info(0x0000, 'testTag', 'hceService transmit Promise success.');
}).catch((err: BusinessError) => {
hilog.error(0x0000, 'testTag', 'hceService transmit Promise error ='+ JSON.stringify(err));
});
} else {
hilog.error(0x0000, 'testTag', 'hceCommandCb error'+ 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() {
// 前台模式下,可进行一些界面提示或准备工作
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
}
onDestroy() {
// 退出应用程序时,取消订阅
if (hceElementName!= undefined) {
try {
hceService.stop(hceElementName);
} catch (error) {
hilog.error(0x0000, 'testTag', 'hceService.stop error ='+ JSON.stringify(error));
}
}
}
}
通过以上对HarmonyOS Next中NFC模块的标签读写和卡模拟功能的详细介绍,我们可以看到NFC技术为智能设备带来了丰富的交互方式和便捷的应用体验。无论是在便捷支付、门禁管理还是信息交互等方面,NFC都有着巨大的潜力等待开发者去挖掘。就像一把神奇的钥匙,开启了智能设备之间近场通信的新大门,让设备之间的交互变得更加自然和流畅。嘿,想象一下,以后出门只带手机,就能轻松搞定各种事情,是不是感觉生活变得更加美好了呢?哈哈!希望这篇文章能够帮助开发者们更好地理解和运用HarmonyOS Next中的NFC技术,创造出更多有趣、实用的应用程序。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。