日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HarmonyOS之深入解析NFC的功能和使用

發布時間:2024/5/21 编程问答 94 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HarmonyOS之深入解析NFC的功能和使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、簡介

  • NFC(Near Field Communication,近距離無線通信技術) 是一種非接觸式識別和互聯技術,讓移動設備、消費類電子產品、PC 和智能設備之間可以進行近距離無線通信。
  • HarmonyOS 的 NFC 提供的功能有:
    • NFC 基礎查詢:在進行 NFC 功能開發之前,開發者應該先確認設備是否支持 NFC 功能、NFC 是否打開等基本信息。
    • 訪問安全單元(Secure Element,簡稱為 SE):SE 可用于保存重要信息,應用可以訪問指定 SE,并發送數據到 SE 上。
    • 卡模擬:設備可以模擬卡片,替代卡片完成對應操作,如模擬門禁卡、公交卡等。
    • NFC 消息通知:通過這個模塊,開發者可以獲取 NFC 開關狀態改變的消息以及 NFC 的場強消息。

二、NFC 基礎查詢

  • 要進行 NFC 功能開發,需要設備支持 NFC 功能。
  • 開發者可以通過 NfcController 類的方法 isNfcAvailable() 來確認設備是否支持 NFC 功能。如果設備支持 NFC 功能,可通過 isNfcOpen() 來查詢 NFC 的開關狀態。
  • 示例代碼如下:
// 查詢本機是否支持NFCif (context != null) {NfcController nfcController = NfcController.getInstance(context);} else {return;}boolean isAvailable = nfcController.isNfcAvailable();if (isAvailable) {// 調用查詢NFC是否打開接口,返回值為NFC是否是打開的狀態boolean isOpen = nfcController.isNfcOpen();}

三、訪問安全單元

① 應用場景
  • 安全單元(Secure Element,簡稱為 SE)可用于保存重要信息,應用或者其他模塊可以通過接口完成以下功能:
    • 獲取安全單元的個數和名稱。
    • 判斷安全單元是否在位。
    • 在指定安全單元上打開基礎通道。
    • 在指定安全單元上打開邏輯通道。
    • 發送 APDU(Application Protocol Data Unit)數據到安全單元上。

② API 說明

  • NFC 訪問安全單元功能的的主要接口:
類名接口名功能描述SEServiceSEService()創建一個安全單元服務的實例isConnected()查詢安全單元服務是否已連接shutdown()關閉安全單元服務getReaders()獲取全部安全單元getVersion()獲得安全單元服務的版本OnCallback用于回調的內部類,用于定義回調接口。
在服務連接成功后,回調該接口通知應用ReadergetName()獲取安全單元的名稱isSecureElementPresent()檢查安全單元是否在位openSession()打開當前安全單元上的sessioncloseSession()關閉當前安全單元上的所有sessionSessionopenBasicChannel(Aid aid)打開基礎通道openLogicalChannel(Aid aid)創建邏輯通道getATR()獲得重設安全單元指令的響應closeSessionChannels()關閉當前session的所有通道ChannelisClosed()判斷通道是否關閉isBasicChannel()判斷是否是基礎通道transmit(byte[] command)發送指令到安全單元getSelectResponse()獲得應用程序選擇指令的響應closeChannel()關閉通道AidAid(byte[] aid, int offset, int length)構造一個AID類的實例isAidValid()查詢AID是否有效getAidBytes()獲取AID的字節數組形式的值
③ 使用流程
  • 調用 SEService 類的構造函數,創建一個安全單元服務的實例,用于訪問安全單元。
  • 調用 isConnected() 接口,查詢安全單元服務的連接狀態。
  • 調用 getReaders() 接口,獲取本機的全部安全單元。
  • 調用 Reader 類的 openSession() 接口打開 Session,返回一個打開的 Session 實例。
  • 調用 Session 類的 openBasicChannel(Aid aid) 接口打開基礎通道,或者調用 openLogicalChannel(Aid aid) 接口打開邏輯通道,返回一個打開通道 Channel 實例。
  • 調用 Channel 類的 transmit(byte[] command),發送 APDU 到安全單元。
  • 調用 Channel 類的 closeChannel() 接口關閉通道。
  • 調用 Session 類的 closeSessionChannels() 接口關閉 Session 的所有通道。
  • 調用 Reader 類的 closeSessions() 接口關閉安全單元的所有 Session。
  • 調用 SEService 類的 shutdown() 接口關閉安全單元服務。
private static final String ESE = "eSE";private class AppServiceConnectedCallback implements SEService.OnCallback {@Overridepublic void serviceConnected() {// 應用自實現}}// 創建安全單元服務實例SEService sEService = new SEService(context, new AppServiceConnectedCallback());// 查詢安全單元服務的連接狀態boolean isConnected = sEService.isConnected();// 獲取本機的全部安全單元,并獲取指定的安全單元eSEReader[] elements = sEService.getReaders();Reader eSe = null;for (int i = 0; i < elements.length; i++) {if (ESE.equals(elements[i].getName())) {eSe = elements[i];break;}}if (eSe == null) {return;}// 查詢安全單元是否在位boolean isPresent = eSe.isSecureElementPresent();// 打開SessionOptional<Session> optionalSession = eSe.openSession();Session session = optionalSession.orElse(null);if (session == null) {return;}// 打開通道if (eSe != null) {byte[] aidValue = new byte[]{(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05};// 創建Aid實例Aid aid = new Aid(aidValue, 0, aidValue.length); // 打開基礎通道Optional<Channel> optionalChannel = session.openBasicChannel(aid);Channel basicChannel = optionalChannel.orElse(null);// 打開邏輯通道optionalChannel = session.openLogicalChannel(aid);Channel logicalChannel = optionalChannel.orElse(null);// 發送指令給安全單元,返回值為安全單元對指令的響應byte[] resp = logicalChannel.transmit(new byte[]{(byte)0x00, (byte)0xa4, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x00});// 關閉通道資源if (basicChannel.isPresent()) {basicChannel.closeChannel();}if (logicalChannel.isPresent()) {logicalChannel.closeChannel();}// 關閉Session資源session.close();// 關閉安全單元資源eSe.closeSessions();// 關閉安全單元服務資源sEService.shutdown();

四、卡模擬功能

① 應用場景
  • 設備可以模擬卡片,替代卡片完成對應操作,如模擬門禁卡、公交卡等。
  • 應用或者其他模塊可以通過接口完成以下功能:
    • 查詢是否支持指定安全單元的卡模擬功能,安全單元包括 HCE(Host Card Emulation)、ESE(Embedded Secure Element)和 SIM(Subscriber Identity Module)卡。
    • 打開或關閉指定技術類型的卡模擬,并查詢卡模擬狀態。
    • 獲取 NFC 信息,包括當前激活的安全單元、Hisee 上電狀態、是否支持RSSI(Received Signal Strength Indication)查詢等。
    • 根據 NFC 服務的類型獲取刷卡時選擇服務的方式,包括支付(Payment)類型和非支付(Other)類型。
    • 動態設置和注銷前臺優先應用。
    • NFC 應用的 AID(Application Identifier,應用標識)相關操作,包括注冊和刪除應用的 AID、查詢應用是否是指定 AID 的默認應用、獲取應用的 AID 等。
    • 定義 Host 和 OffHost 服務的抽象類,應用可以通過繼承抽象類來實現 NFC 卡模擬功能。
② API 說明
  • NFC 卡模擬功能的主要接口說明如下,在使用對應的接口前,需要申請 ohos.permission.NFC_CARD_EMULATION 權限。
  • NFC 卡模擬功能的主要接口如下表所示:
類名接口名功能描述CardEmulationgetInstance(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 aids)給應用注冊指定類型的AIDremoveAids(ElementName appName, String type)刪除應用的指定類型的AIDgetAids(ElementName appName, String type)獲取應用中指定類型的AID列表HostServicesendResponse(byte[] response)發送響應的數據到對端設備handleRemoteCommand(byte[] cmd, IntentParams params)處理對端設備發送的命令disabledCallback(int errCode)連接異常的回調
③ 查詢是否支持卡模擬功能
  • 調用 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(); // 關閉卡模擬cardEmulation.setListenMode(CardEmulation.DISABLE_MODE_A_B);// 調用查詢卡模擬開關狀態的接口,返回值為卡模擬是否是打開的狀態isEnabled = cardEmulation.isListenModeEnabled();
⑤ 獲取 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_DEFAULTresult = 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);// 動態設置前臺優先應用Ability ability = new Ability();cardEmulation.registerForegroundPreferred(ability, new ElementName());// 注銷前臺優先應用cardEmulation.unregisterForegroundPreferred(ability);

五、NFC 消息通知

① 應用場景
  • NFC 消息通知是 HarmonyOS 內部或者與應用之間跨進程通訊的機制,注冊者在注冊消息通知后,一旦符合條件的消息被發出,注冊者即可接收到該消息。
② API 說明
  • NFC 消息通知的相關廣播介紹:
描述通知名附加參數
NFC狀態usual.event.nfc.action.ADAPTER_STATE_CHANGEDextra_nfc_state
進場消息usual.event.nfc.action.RF_FIELD_ON_DETECTEDextra_nfc_transaction
離場消息usual.event.nfc.action.RF_FIELD_OFF_DETECTED-
③ 注冊并獲取 NFC 狀態改變消息
  • 構建消息通知接收者 NfcStateEventSubscriber。
  • 注冊 NFC 狀態改變消息。
  • NfcStateEventSubscriber 接收并處理 NFC 狀態改變消息。
// 構建消息接收者/注冊者class NfcStateEventSubscriber extends CommonEventSubscriber {NfcStateEventSubscriber (CommonEventSubscribeInfo info) {super(info);}@Overridepublic void onReceiveEvent(CommonEventData commonEventData) {if (commonEventData == null || commonEventData.getIntent() == null) {return;}if (NfcController.STATE_CHANGED.equals(commonEventData.getIntent().getAction())) {IntentParams params = commonEventData.getIntent().getParams();int currState = commonEventData.getIntent().getIntParam(NfcController.EXTRA_NFC_STATE, NfcController.STATE_OFF);}}}// 注冊消息MatchingSkills matchingSkills = new MatchingSkills();// 增加獲取NFC狀態改變消息matchingSkills.addEvent(NfcController.STATE_CHANGED);matchingSkills.addEvent(CommonEventSupport.COMMON_EVENT_NFC_ACTION_ADAPTER_STATE_CHANGED);CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);NfcStateEventSubscriber subscriber = new NfcStateEventSubscriber(subscribeInfo);try {CommonEventManager.subscribeCommonEvent(subscriber);} catch (RemoteException e) {HiLog.error(TAG, "doSubscribe occur exception: %{public}s" ,e.toString());}
④ 注冊并獲取 NFC 場強消息
  • 構建消息通知接收者 NfcFieldOnAndOffEventSubscriber。
  • 注冊 NFC 場強消息。
  • NfcFieldOnAndOffEventSubscriber 接收并處理 NFC 場強消息。
// 構建消息接收者/注冊者class NfcFieldOnAndOffEventSubscriber extends CommonEventSubscriber {NfcFieldOnAndOffEventSubscriber (CommonEventSubscribeInfo info) {super(info);}@Overridepublic void onReceiveEvent(CommonEventData commonEventData) {if (commonEventData == null || commonEventData.getIntent() == null) {return;}if (NfcController.FIELD_ON_DETECTED.equals(commonEventData.getIntent().getAction())) {IntentParams params = commonEventData.getIntent().getParams();if (params == null) {HiLog.info(TAG, "Pure FIELD_ON_DETECTED");} else {HiLog.info(TAG, "Transaction FIELD_ON_DETECTED"); Intent transactionIntent = (Intent) params.getParam("transactionIntent");}} else if (NfcController.FIELD_OFF_DETECTED.equals(commonEventData.getIntent().getAction())) {HiLog.info(TAG, "FIELD_OFF_DETECTED");}HiLog.info(TAG, "NfcFieldOnAndOffEventSubscriber onReceiveEvent: %{public}s", commonEventData.getIntent().getAction());}}// 注冊消息MatchingSkills matchingSkills = new MatchingSkills();// 增加獲取NFC狀態改變消息matchingSkills.addEvent(NfcController.FIELD_ON_DETECTED);matchingSkills.addEvent(NfcController.FIELD_OFF_DETECTED);CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);HiLog.info(TAG, "subscribeInfo permission: %{public}s", subscribeInfo.getPermission());NfcFieldOnAndOffEventSubscriber subscriber = new NfcFieldOnAndOffEventSubscriber(subscribeInfo);try {CommonEventManager.subscribeCommonEvent(subscriber);} catch (RemoteException e) {HiLog.error(TAG, "doSubscribe occur exception: %{public}s", e.toString());}

總結

以上是生活随笔為你收集整理的HarmonyOS之深入解析NFC的功能和使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。