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