From 8e3719a37a6be0c9e244a0160b5f2f3331ca3122 Mon Sep 17 00:00:00 2001 From: zuoxiao <470321431@qq.com> Date: 星期四, 30 十一月 2023 15:11:38 +0800 Subject: [PATCH] 支持虚拟卡读取 --- app/src/main/java/com/dayu/recharge/tools/LoyaltyCardReader.java | 97 +++++++++++++++++++++++++++++------------------- 1 files changed, 58 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/com/dayu/recharge/tools/LoyaltyCardReader.java b/app/src/main/java/com/dayu/recharge/tools/LoyaltyCardReader.java index b80f6d7..8e8fedd 100644 --- a/app/src/main/java/com/dayu/recharge/tools/LoyaltyCardReader.java +++ b/app/src/main/java/com/dayu/recharge/tools/LoyaltyCardReader.java @@ -16,9 +16,11 @@ package com.dayu.recharge.tools; import android.annotation.TargetApi; +import android.app.Activity; import android.nfc.NfcAdapter; import android.nfc.Tag; import android.nfc.tech.IsoDep; +import android.nfc.tech.MifareClassic; import android.os.Build; import android.util.Log; @@ -45,14 +47,21 @@ // Weak reference to prevent retain loop. mAccountCallback is responsible for exiting // foreground mode before it becomes invalid (e.g. during onPause() or onStop()). - private WeakReference<AccountCallback> mAccountCallback; + private AccountCallback mAccountCallback; + + Activity mActivity; public interface AccountCallback { - public void onAccountReceived(Tag tag); + //瀹炰綋鍗″洖璋� + public void physicalCardDoing(Tag tag); + + //铏氭嫙鍗″洖璋� + public void virtualCardDoing(Tag tag); } - public LoyaltyCardReader(AccountCallback accountCallback) { - mAccountCallback = new WeakReference<AccountCallback>(accountCallback); + public LoyaltyCardReader(Activity activity, AccountCallback accountCallback) { + mActivity = activity; + mAccountCallback = accountCallback; } /** @@ -65,44 +74,54 @@ @Override public void onTagDiscovered(Tag tag) { Log.i(TAG, "New tag discovered"); - mAccountCallback.get().onAccountReceived(tag); - // Android's Host-based Card Emulation (HCE) feature implements the ISO-DEP (ISO 14443-4) - // protocol. - // - // In order to communicate with a device using HCE, the discovered tag should be processed - // using the IsoDep class. - IsoDep isoDep = IsoDep.get(tag); - if (isoDep != null) { - try { - // Connect to the remote NFC device - isoDep.connect(); - // Build SELECT AID command for our loyalty card service. - // This command tells the remote device which service we wish to communicate with. - Log.i(TAG, "Requesting remote AID: " + SAMPLE_LOYALTY_CARD_AID); -// mAccountCallback.get().onAccountReceived(); - byte[] command = BuildSelectApdu(SAMPLE_LOYALTY_CARD_AID); - - // Send command to remote device - Log.i(TAG, "Sending: " + ByteArrayToHexString(command)); -// mAccountCallback.get().onAccountReceived(); - byte[] result = isoDep.transceive(command); - // If AID is successfully selected, 0x9000 is returned as the status word (last 2 - // bytes of the result) by convention. Everything before the status word is - // optional payload, which is used here to hold the account number. - int resultLength = result.length; - byte[] statusWord = {result[resultLength - 2], result[resultLength - 1]}; - byte[] payload = Arrays.copyOf(result, resultLength - 2); - if (Arrays.equals(SELECT_OK_SW, statusWord)) { - // The remote NFC device will immediately respond with its stored account number - String accountNumber = new String(payload, "UTF-8"); - Log.i(TAG, "Received: " + accountNumber); - // Inform CardReaderFragment of received account number -// mAccountCallback.get().onAccountReceived(); + MifareClassic mifareClassic= MifareClassic.get(tag); + //鏅�歁1鍗� + if (mifareClassic!=null){ + mActivity.runOnUiThread(new Runnable() { + @Override + public void run() { + mAccountCallback.physicalCardDoing(tag); } - } catch (IOException e) { - Log.e(TAG, "Error communicating with card: " + e.toString()); + }); + }else { + // Android 鐨勫熀浜庝富鏈虹殑鍗′豢鐪� 锛圚CE锛� 鍔熻兘瀹炵幇浜� ISO-DEP 锛圛SO 14443-4锛� 鍗忚銆備负浜嗕娇鐢� HCE 涓庤澶囬�氫俊锛屽簲浣跨敤 IsoDep 绫诲鐞嗗彂鐜扮殑鏍囪銆� + IsoDep isoDep = IsoDep.get(tag); + if (isoDep != null) { + try { + // Connect to the remote NFC device + isoDep.connect(); + // Build SELECT AID command for our loyalty card service. + // This command tells the remote device which service we wish to communicate with. + Log.i(TAG, "Requesting remote AID: " + SAMPLE_LOYALTY_CARD_AID); +// mAccountCallback.get().onAccountReceived(); + byte[] command = BuildSelectApdu(SAMPLE_LOYALTY_CARD_AID); + + // Send command to remote device + Log.i(TAG, "Sending: " + ByteArrayToHexString(command)); +// mAccountCallback.get().onAccountReceived(); + byte[] result = isoDep.transceive(command); + // If AID is successfully selected, 0x9000 is returned as the status word (last 2 + // bytes of the result) by convention. Everything before the status word is + // optional payload, which is used here to hold the account number. + int resultLength = result.length; + byte[] statusWord = {result[resultLength - 2], result[resultLength - 1]}; + byte[] payload = Arrays.copyOf(result, resultLength - 2); + if (Arrays.equals(SELECT_OK_SW, statusWord)) { + // The remote NFC device will immediately respond with its stored account number + String accountNumber = new String(payload, "UTF-8"); + Log.i(TAG, "Received: " + accountNumber); + // Inform CardReaderFragment of received account number +// mAccountCallback.get().onAccountReceived(); + } + } catch (IOException e) { + Log.e(TAG, "Error communicating with card: " + e.toString()); + } } } + + + + } /** -- Gitblit v1.8.0