利用NFC增强用户体验:HarmonyOS Next的NFC应用指南

打印 上一主题 下一主题

主题 842|帖子 842|积分 2526

本文旨在深入探究华为鸿蒙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:
  1. {
  2.   "abilities": [
  3.     {
  4.       "name": "EntryAbility",
  5.       "srcEntry": "./ets/entryability/EntryAbility.ts",
  6.       "description": "$string:EntryAbility_desc",
  7.       "icon": "$media:icon",
  8.       "label": "$string:EntryAbility_label",
  9.       "startWindowIcon": "$media:icon",
  10.       "startWindowBackground": "$color:start_window_background",
  11.       "exported": true,
  12.       "skills": [
  13.         {
  14.           "entities": [
  15.             "entity.system.home"
  16.           ],
  17.           "actions": [
  18.             "action.system.home",
  19.             "ohos.nfc.tag.action.TAG_FOUND"
  20.           ]
  21.         }
  22.       ]
  23.     }
  24.   ],
  25.   "requestPermissions": [
  26.     {
  27.       "name": "ohos.permission.NFC_TAG",
  28.       "reason": "$string:app_name"
  29.     }
  30.   ]
  31. }
复制代码
然后,在应用代码中进行以下操作:
  1. import { tag } from '@kit.ConnectivityKit';
  2. import { hilog } from '@kit.PerformanceAnalysisKit';
  3. // 判断设备是否支持NFC能力
  4. if (!canIUse("SystemCapability.Communication.NFC.Core")) {
  5.     hilog.error(0x0000, 'testTag', 'nfc unavailable.');
  6.     return;
  7. }
  8. // 调⽤tag模块中前台优先的接⼝,使能前台应⽤程序优先处理所发现的NFC标签功能
  9. tag.enableForegroundDispatch((result) => {
  10.     if (result === 0) {
  11.         hilog.info(0x0000, 'testTag', 'enableForegroundDispatch success');
  12.     } else {
  13.         hilog.error(0x0000, 'testTag', 'enableForegroundDispatch failed with error code:'+ result);
  14.     }
  15. });
  16. // 获取特定技术类型的NFC标签对象(以NfcA为例)
  17. tag.getNfcA(tagInfo).then((nfcATag) => {
  18.     // 执行读写接口完成标签数据的读取或写入数据到标签
  19.     // 例如,读取标签数据
  20.     nfcATag.read().then((data) => {
  21.         hilog.info(0x0000, 'testTag', 'Read data from NFC tag:'+ JSON.stringify(data));
  22.     }).catch((err) => {
  23.         hilog.error(0x0000, 'testTag', 'Error reading NFC tag:'+ JSON.stringify(err));
  24.     });
  25. }).catch((err) => {
  26.     hilog.error(0x0000, 'testTag', 'Error getting NfcA tag object:'+ JSON.stringify(err));
  27. });
  28. // 退出应⽤程序NFC标签页面时,调⽤tag模块退出前台优先功能
  29. tag.disableForegroundDispatch((result) => {
  30.     if (result === 0) {
  31.         hilog.info(0x0000, 'testTag', 'disableForegroundDispatch success');
  32.     } else {
  33.         hilog.error(0x0000, 'testTag', 'disableForegroundDispatch failed with error code:'+ result);
  34.     }
  35. });
复制代码
3. 背景标签识别实现

背景标签识别是指设备在未打开特定NFC标签应用程序的情况下,触碰发现NFC标签后,根据标签的技术范例,分发给可以大概处理的应用程序。如果匹配到多个应用程序,则弹出应用选择器让用户手动选择。
在module.json5文件中声明NFC标签读取的权限、相关action以及应用可以大概处理的AID(应用程序标识符):
  1. {
  2.   "abilities": [
  3.     {
  4.       "name": "EntryAbility",
  5.       "srcEntry": "./ets/entryability/EntryAbility.ts",
  6.       "description": "$string:EntryAbility_desc",
  7.       "icon": "$media:icon",
  8.       "label": "$string:EntryAbility_label",
  9.       "startWindowIcon": "$media:icon",
  10.       "startWindowBackground": "$color:start_window_background",
  11.       "exported": true,
  12.       "skills": [
  13.         {
  14.           "entities": [
  15.             "entity.system.home"
  16.           ],
  17.           "actions": [
  18.             "action.system.home",
  19.             "ohos.nfc.tag.action.TAG_FOUND"
  20.           ]
  21.         ]
  22.       },
  23.       "metadata": [
  24.         {
  25.           "name": "payment-aid",
  26.           "value": "A0000000031010"
  27.         },
  28.         {
  29.           "name": "other-aid",
  30.           "value": "A0000000031011"
  31.         }
  32.       ]
  33.     }
  34.   ],
  35.   "requestPermissions": [
  36.     {
  37.       "name": "ohos.permission.NFC_TAG",
  38.       "reason": "$string:app_name"
  39.     }
  40.   ]
  41. }
复制代码
在应用代码中,主要是订阅标签发现事件,当检测到符合条件的标签时,进行相应处理:
  1. import { tag } from '@kit.ConnectivityKit';
  2. import { hilog } from '@kit.PerformanceAnalysisKit';
  3. // 判断设备是否支持NFC能力
  4. if (!canIUse("SystemCapability.Communication.NFC.Core")) {
  5.     hilog.error(0x0000, 'testTag', 'nfc unavailable.');
  6.     return;
  7. }
  8. // 订阅标签发现事件
  9. tag.on('tagFound', (tagInfo) => {
  10.     hilog.info(0x0000, 'testTag', 'NFC tag found:'+ JSON.stringify(tagInfo));
  11.     // 根据标签信息进行处理,例如获取标签类型并根据业务逻辑进行相应操作
  12.     const techList = tagInfo.techList;
  13.     if (techList.includes('NfcA')) {
  14.         // 处理NfcA类型标签
  15.         handleNfcATag(tagInfo);
  16.     } else if (techList.includes('NfcB')) {
  17.         // 处理NfcB类型标签
  18.         handleNfcBTag(tagInfo);
  19.     }
  20. });
复制代码
三、NFC卡模拟(HCE)实现

1. HCE应用场景

HCE在许多场景中都具有紧张应用代价。比方,在移动支付领域,用户可以将银行卡信息模拟得手机中,在支持NFC支付的终端上进行刷卡消耗,无需携带实体银行卡;在门禁系统中,手机模拟门禁卡,方便用户进出办公场所或住宅小区。
2. HCE卡模拟实现示例

以下是一个简单的HCE卡模拟的基本代码示例,包罗前台刷卡和背景刷卡的部门实现。
前台刷卡:
在module.json5文件中声明NFC卡模拟权限和HCE特定的action:
  1. {
  2.   "abilities": [
  3.     {
  4.       "name": "EntryAbility",
  5.       "srcEntry": "./ets/entryability/EntryAbility.ts",
  6.       "description": "$string:EntryAbility_desc",
  7.       "icon": "$media:icon",
  8.       "label": "$string:EntryAbility_label",
  9.       "startWindowIcon": "$media:icon",
  10.       "startWindowBackground": "$color:start_window_background",
  11.       "exported": true,
  12.       "skills": [
  13.         {
  14.           "entities": [
  15.             "entity.system.home"
  16.           ],
  17.           "actions": [
  18.             "action.system.home",
  19.             "ohos.nfc.cardemulation.action.HOST_APDU_SERVICE"
  20.           ]
  21.         ]
  22.       },
  23.       "metadata": []
  24.     }
  25.   ],
  26.   "requestPermissions": [
  27.     {
  28.       "name": "ohos.permission.NFC_CARD_EMULATION",
  29.       "reason": "$string:app_name"
  30.     }
  31.   ]
  32. }
复制代码
在应用代码中:
  1. import { cardEmulation } from '@kit.ConnectivityKit';
  2. import { BusinessError } from '@kit.BasicServicesKit';
  3. import { hilog } from '@kit.PerformanceAnalysisKit';
  4. import { AsyncCallback } from '@kit.BasicServicesKit';
  5. import { AbilityConstant, UIAbility, Want, bundleManager } from '@kit.AbilityKit';
  6. let hceElementName: bundleManager.ElementName;
  7. let hceService: cardEmulation.HceService;
  8. const hceCommandCb: AsyncCallback<number[]> = (error: BusinessError, hceCommand: number[]) => {
  9.     if (!error) {
  10.         if (hceCommand == null || hceCommand == undefined) {
  11.             hilog.error(0x0000, 'testTag', 'hceCommandCb has invalid hceCommand.');
  12.             return;
  13.         }
  14.         // 根据接收到的命令进行处理,然后发送响应
  15.         let responseData = [0x90, 0x00]; // 根据不同命令修改响应数据
  16.         hceService.transmit(responseData).then(() => {
  17.             hilog.info(0x0000, 'testTag', 'hceService transmit Promise success.');
  18.         }).catch((err: BusinessError) => {
  19.             hilog.error(0x0000, 'testTag', 'hceService transmit Promise error ='+ JSON.stringify(err));
  20.         });
  21.     } else {
  22.         hilog.error(0x0000, 'testTag', 'hceCommandCb error'+ JSON.stringify(error));
  23.     }
  24. };
  25. export default class EntryAbility extends UIAbility {
  26.     onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
  27.         hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  28.         // 判断设备是否支持NFC能力和HCE能力
  29.         if (!canIUse("SystemCapability.Communication.NFC.Core")) {
  30.             hilog.error(0x0000, 'testTag', 'nfc unavailable.');
  31.             return;
  32.         }
  33.         if (!cardEmulation.hasHceCapability()) {
  34.             hilog.error(0x0000, 'testTag', 'hce unavailable.');
  35.             return;
  36.         }
  37.         hceElementName = {
  38.             bundleName: want.bundleName?? '',
  39.             abilityName: want.abilityName?? '',
  40.             moduleName: want.moduleName
  41.         };
  42.         hceService = new cardEmulation.HceService();
  43.     }
  44.     onForeground() {
  45.         // 使能前台HCE应用程序优先处理NFC刷卡功能
  46.         let aidList = ["A0000000031010", "A0000000031011"]; // 根据实际情况修改AID
  47.         hceService.start(hceElementName, aidList);
  48.         // 订阅HCE APDU数据的接收
  49.         hceService.on('hceCmd', hceCommandCb);
  50.     }
  51.     onBackground() {
  52.         // 退出应用程序NFC标签页面时,退出前台优先功能
  53.         hceService.stop(hceElementName);
  54.     }
  55. }
复制代码
背景刷卡:
在module.json5文件中声明NFC卡模拟权限、HCE特定的action以及应用可以大概处理的AID:
  1. {
  2.   "abilities": [
  3.     {
  4.       "name": "EntryAbility",
  5.       "srcEntry": "./ets/entryability/EntryAbility.ts",
  6.       "description": "$string:EntryAbility_desc",
  7.       "icon": "$media:icon",
  8.       "label": "$string:EntryAbility_label",
  9.       "startWindowIcon": "$media:icon",
  10.       "startWindowBackground": "$color:start_window_background",
  11.       "exported": true,
  12.       "skills": [
  13.         {
  14.           "entities": [
  15.             "entity.system.home"
  16.           ],
  17.           "actions": [
  18.             "action.system.home",
  19.             "ohos.nfc.cardemulation.action.HOST_APDU_SERVICE"
  20.           ]
  21.         ]
  22.       },
  23.       "metadata": [
  24.         {
  25.           "name": "payment-aid",
  26.           "value": "A0000000031010"
  27.         },
  28.         {
  29.           "name": "other-aid",
  30.           "value": "A0000000031011"
  31.         }
  32.       ]
  33.     }
  34.   ],
  35.   "requestPermissions": [
  36.     {
  37.       "name": "ohos.permission.NFC_CARD_EMULATION",
  38.       "reason": "$string:app_name"
  39.     }
  40.   ]
  41. }
复制代码
在应用代码中:
  1. import { cardEmulation } from '@kit.ConnectivityKit';
  2. import { BusinessError } from '@kit.BasicServicesKit';
  3. import { hilog } from '@kit.PerformanceAnalysisKit';
  4. import { AsyncCallback } from '@kit.BasicServicesKit';
  5. import { AbilityConstant, UIAbility, Want, bundleManager } from '@kit.AbilityKit';
  6. let hceElementName: bundleManager.ElementName;
  7. let hceService: cardEmulation.HceService;
  8. const hceCommandCb: AsyncCallback<number[]> = (error: BusinessError, hceCommand: number[]) => {
  9.     if (!error) {
  10.         if (hceCommand == null || hceCommand == undefined) {
  11.             hilog.error(0x0000, 'testTag', 'hceCommandCb has invalid hceCommand.');
  12.             return;
  13.         }
  14.         // 根据接收到的命令进行处理,然后发送响应
  15.         let responseData = [0x90, 0x00]; // 根据不同命令修改响应数据
  16.         hceService.transmit(responseData).then(() => {
  17.             hilog.info(0x0000, 'testTag', 'hceService transmit Promise success.');
  18.         }).catch((err: BusinessError) => {
  19.             hilog.error(0x0000, 'testTag', 'hceService transmit Promise error ='+ JSON.stringify(err));
  20.         });
  21.     } else {
  22.         hilog.error(0x0000, 'testTag', 'hceCommandCb error'+ JSON.stringify(error));
  23.     }
  24. };
  25. export default class EntryAbility extends UIAbility {
  26.     onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
  27.         hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  28.         // 判断设备是否支持NFC能力和HCE能力
  29.         if (!canIUse("SystemCapability.Communication.NFC.Core")) {
  30.             hilog.error(0x0000, 'testTag', 'nfc unavailable.');
  31.             return;
  32.         }
  33.         if (!cardEmulation.hasHceCapability()) {
  34.             hilog.error(0x0000, 'testTag', 'hce unavailable.');
  35.             return;
  36.         }
  37.         hceElementName = {
  38.             bundleName: want.bundleName?? '',
  39.             abilityName: want.abilityName?? '',
  40.             moduleName: want.moduleName
  41.         };
  42.         hceService = new cardEmulation.HceService();
  43.         hceService.on('hceCmd', hceCommandCb);
  44.     }
  45.     onForeground() {
  46.         // 前台模式下,可进行一些界面提示或准备工作
  47.         hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
  48.     }
  49.     onDestroy() {
  50.         // 退出应用程序时,取消订阅
  51.         if (hceElementName!= undefined) {
  52.             try {
  53.                 hceService.stop(hceElementName);
  54.             } catch (error) {
  55.                 hilog.error(0x0000, 'testTag', 'hceService.stop error ='+ JSON.stringify(error));
  56.             }
  57.         }
  58.     }
  59. }
复制代码
通过以上对HarmonyOS Next中NFC模块的标签读写和卡模拟功能的详细介绍,我们可以看到NFC技术为智能设备带来了丰富的交互方式和便捷的应用体验。无论是在便捷支付、门禁管理还是信息交互等方面,NFC都有着巨大的潜力等待开发者去发掘。就像一把神奇的钥匙,开启了智能设备之间近场通信的新大门,让设备之间的交互变得更加天然和流通。嘿,想象一下,以后出门只带手机,就能轻松搞定各种事情,是不是感觉生活变得更加美好了呢?哈哈!希望这篇文章可以大概资助开发者们更好地理解和运用HarmonyOS Next中的NFC技术,创造出更多有趣、实用的应用程序。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

慢吞云雾缓吐愁

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表