Display UI card read

This commit is contained in:
riz081 2025-06-18 11:44:11 +07:00
parent 124da43a1e
commit 8add903edb

View File

@ -15,6 +15,8 @@ import com.sunmi.pay.hardware.aidl.AidlConstants.CardType;
import com.sunmi.pay.hardware.aidlv2.readcard.CheckCardCallbackV2;
public class CreditCardActivity extends AppCompatActivity {
private static final String TAG = "CreditCard";
private TextView tvResult;
private Button btnCheckCard;
private boolean checkingCard;
@ -22,22 +24,26 @@ public class CreditCardActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
android.util.Log.d("CreditCard", "onCreate called");
android.util.Log.d(TAG, "onCreate called");
setContentView(R.layout.activity_credit_card);
initView();
// Check PaySDK status
checkPaySDKStatus();
}
private void checkPaySDKStatus() {
if (MyApplication.app != null) {
android.util.Log.d("CreditCard", "MyApplication.app exists");
android.util.Log.d("CreditCard", "PaySDK connected: " + MyApplication.app.isConnectPaySDK());
android.util.Log.d("CreditCard", "readCardOptV2 null: " + (MyApplication.app.readCardOptV2 == null));
android.util.Log.d(TAG, "MyApplication.app exists");
android.util.Log.d(TAG, "PaySDK connected: " + MyApplication.app.isConnectPaySDK());
android.util.Log.d(TAG, "readCardOptV2 null: " + (MyApplication.app.readCardOptV2 == null));
} else {
android.util.Log.e("CreditCard", "MyApplication.app is null");
android.util.Log.e(TAG, "MyApplication.app is null");
}
}
private void initView() {
android.util.Log.d("CreditCard", "initView called");
android.util.Log.d(TAG, "initView called");
// Setup Toolbar as ActionBar
androidx.appcompat.widget.Toolbar toolbar = findViewById(R.id.toolbar);
@ -53,20 +59,20 @@ public class CreditCardActivity extends AppCompatActivity {
btnCheckCard = findViewById(R.id.btn_check_card);
if (btnCheckCard != null) {
android.util.Log.d("CreditCard", "Button found, setting click listener");
android.util.Log.d(TAG, "Button found, setting click listener");
btnCheckCard.setOnClickListener(v -> {
android.util.Log.d("CreditCard", "Button clicked!");
android.util.Log.d(TAG, "Button clicked!");
switchCheckCard();
});
} else {
android.util.Log.e("CreditCard", "Button not found!");
android.util.Log.e(TAG, "Button not found!");
}
if (tvResult != null) {
tvResult.setText("Ready to scan card...");
android.util.Log.d("CreditCard", "TextView initialized");
android.util.Log.d(TAG, "TextView initialized");
} else {
android.util.Log.e("CreditCard", "TextView not found!");
android.util.Log.e(TAG, "TextView not found!");
}
}
@ -77,56 +83,75 @@ public class CreditCardActivity extends AppCompatActivity {
}
private void switchCheckCard() {
android.util.Log.d("CreditCard", "switchCheckCard called, checkingCard: " + checkingCard);
android.util.Log.d(TAG, "switchCheckCard called, checkingCard: " + checkingCard);
try {
if (checkingCard) {
android.util.Log.d("CreditCard", "Stopping card check");
MyApplication.app.readCardOptV2.cancelCheckCard();
btnCheckCard.setText(R.string.card_start_check_card);
checkingCard = false;
android.util.Log.d(TAG, "Stopping card check");
stopCardCheck();
} else {
android.util.Log.d("CreditCard", "Starting card check");
checkCreditCard();
checkingCard = true;
btnCheckCard.setText(R.string.card_stop_check_card);
android.util.Log.d(TAG, "Starting card check");
startCardCheck();
}
} catch (Exception e) {
android.util.Log.e("CreditCard", "Error in switchCheckCard: " + e.getMessage());
android.util.Log.e(TAG, "Error in switchCheckCard: " + e.getMessage());
e.printStackTrace();
updateUI("Error: " + e.getMessage(), false);
}
}
private void startCardCheck() {
try {
checkCreditCard();
checkingCard = true;
btnCheckCard.setText(R.string.card_stop_check_card);
} catch (Exception e) {
android.util.Log.e(TAG, "Error starting card check: " + e.getMessage());
updateUI("Error starting card check: " + e.getMessage(), false);
}
}
private void stopCardCheck() {
try {
if (MyApplication.app != null && MyApplication.app.readCardOptV2 != null) {
MyApplication.app.readCardOptV2.cancelCheckCard();
}
checkingCard = false;
btnCheckCard.setText(R.string.card_start_check_card);
updateUI("Card check stopped", false);
} catch (Exception e) {
android.util.Log.e(TAG, "Error stopping card check: " + e.getMessage());
checkingCard = false;
btnCheckCard.setText(R.string.card_start_check_card);
}
}
private void checkCreditCard() {
try {
// Ensure PaySDK is bound first
if (MyApplication.app == null) {
tvResult.setText("Error: Application not initialized");
android.util.Log.e("CreditCard", "MyApplication.app is null");
// Validate application state
if (!validateApplicationState()) {
return;
}
// If not connected, try to bind first
if (!MyApplication.app.isConnectPaySDK()) {
tvResult.setText("Connecting to PaySDK...");
android.util.Log.d("CreditCard", "PaySDK not connected, binding service...");
android.util.Log.d(TAG, "PaySDK not connected, binding service...");
MyApplication.app.bindPaySDKService();
// Wait a bit and retry
// Wait and retry
btnCheckCard.postDelayed(() -> {
if (MyApplication.app.isConnectPaySDK() && MyApplication.app.readCardOptV2 != null) {
startCardScan();
} else {
tvResult.setText("Error: Failed to connect to PaySDK");
checkingCard = false;
btnCheckCard.setText(R.string.card_start_check_card);
updateUI("Error: Failed to connect to PaySDK", false);
}
}, 2000); // Wait 2 seconds
}, 2000);
return;
}
if (MyApplication.app.readCardOptV2 == null) {
tvResult.setText("Error: Card reader not initialized");
android.util.Log.e("CreditCard", "readCardOptV2 is null");
updateUI("Error: Card reader not initialized", false);
android.util.Log.e(TAG, "readCardOptV2 is null");
return;
}
@ -134,36 +159,61 @@ public class CreditCardActivity extends AppCompatActivity {
} catch (Exception e) {
e.printStackTrace();
android.util.Log.e("CreditCard", "Error in checkCreditCard: " + e.getMessage());
tvResult.setText("Error starting card scan: " + e.getMessage());
android.util.Log.e(TAG, "Error in checkCreditCard: " + e.getMessage());
updateUI("Error starting card scan: " + e.getMessage(), false);
}
}
private boolean validateApplicationState() {
if (MyApplication.app == null) {
updateUI("Error: Application not initialized", false);
android.util.Log.e(TAG, "MyApplication.app is null");
return false;
}
return true;
}
private void startCardScan() {
try {
int cardType = CardType.MAGNETIC.getValue() | CardType.IC.getValue() | CardType.NFC.getValue();
tvResult.setText("Starting card scan...\nPlease insert or swipe your card");
tvResult.setText("Starting card scan...\nPlease insert, swipe, or tap your card");
// Log for debugging
android.util.Log.d("CreditCard", "Starting checkCard with cardType: " + cardType);
android.util.Log.d(TAG, "Starting checkCard with cardType: " + cardType);
android.util.Log.d(TAG, "CardType values - MAGNETIC: " + CardType.MAGNETIC.getValue() +
", IC: " + CardType.IC.getValue() + ", NFC: " + CardType.NFC.getValue());
MyApplication.app.readCardOptV2.checkCard(cardType, mCheckCardCallback, 60);
} catch (Exception e) {
e.printStackTrace();
android.util.Log.e("CreditCard", "Error in startCardScan: " + e.getMessage());
tvResult.setText("Error starting card scan: " + e.getMessage());
android.util.Log.e(TAG, "Error in startCardScan: " + e.getMessage());
updateUI("Error starting card scan: " + e.getMessage(), false);
}
}
private void updateUI(String message, boolean isCardDetected) {
runOnUiThread(() -> {
if (tvResult != null) {
tvResult.setText(message);
}
if (isCardDetected) {
checkingCard = false;
btnCheckCard.setText(R.string.card_start_check_card);
}
});
}
// ====== CALLBACK IMPLEMENTATION ======
private final CheckCardCallbackV2 mCheckCardCallback = new CheckCardCallbackV2.Stub() {
@Override
public void findMagCard(Bundle info) throws RemoteException {
android.util.Log.d(TAG, "findMagCard callback triggered");
runOnUiThread(() -> handleMagCardResult(info));
}
@Override
public void findICCard(String atr) throws RemoteException {
android.util.Log.d(TAG, "findICCard callback triggered with ATR: " + atr);
Bundle info = new Bundle();
info.putString("atr", atr);
runOnUiThread(() -> handleICCardResult(info));
@ -171,7 +221,7 @@ public class CreditCardActivity extends AppCompatActivity {
@Override
public void findRFCard(String uuid) throws RemoteException {
// Handle RF card detection - changed to single parameter
android.util.Log.d(TAG, "findRFCard callback triggered with UUID: " + uuid);
Bundle info = new Bundle();
info.putString("uuid", uuid);
runOnUiThread(() -> handleRFCardResult(info));
@ -179,6 +229,7 @@ public class CreditCardActivity extends AppCompatActivity {
@Override
public void onError(int code, String message) throws RemoteException {
android.util.Log.e(TAG, "onError callback triggered - Code: " + code + ", Message: " + message);
Bundle info = new Bundle();
info.putInt("code", code);
info.putString("message", message);
@ -187,78 +238,184 @@ public class CreditCardActivity extends AppCompatActivity {
@Override
public void findICCardEx(Bundle info) throws RemoteException {
android.util.Log.d(TAG, "findICCardEx callback triggered");
runOnUiThread(() -> handleICCardResult(info));
}
@Override
public void findRFCardEx(Bundle info) throws RemoteException {
android.util.Log.d(TAG, "findRFCardEx callback triggered");
runOnUiThread(() -> handleRFCardResult(info));
}
@Override
public void onErrorEx(Bundle info) throws RemoteException {
android.util.Log.e(TAG, "onErrorEx callback triggered");
runOnUiThread(() -> handleErrorResult(info));
}
};
// ====== CARD RESULT HANDLERS ======
private void handleMagCardResult(Bundle info) {
android.util.Log.d("CreditCard", "=== MAGNETIC CARD DATA ===");
// Log dengan detail lengkap
logMagneticCardData(info);
// Update UI
String track1 = Utility.null2String(info.getString("TRACK1"));
String track2 = Utility.null2String(info.getString("TRACK2"));
String track3 = Utility.null2String(info.getString("TRACK3"));
// Log detailed track data
android.util.Log.d("CreditCard", "Track1: " + track1);
android.util.Log.d("CreditCard", "Track2: " + track2);
android.util.Log.d("CreditCard", "Track3: " + track3);
StringBuilder sb = new StringBuilder()
.append(getString(R.string.card_mag_card_detected)).append("\n")
.append("Track1: ").append(track1.isEmpty() ? "N/A" : track1).append("\n")
.append("Track2: ").append(track2.isEmpty() ? "N/A" : track2).append("\n")
.append("Track3: ").append(track3.isEmpty() ? "N/A" : track3);
// Log error codes if available
updateUI(sb.toString(), true);
}
private void handleICCardResult(Bundle info) {
// Log dengan detail lengkap
logICCardData(info);
// Update UI
String atr = info.getString("atr", "");
int cardType = info.getInt("cardType", -1);
StringBuilder sb = new StringBuilder();
sb.append(getString(R.string.card_ic_card_detected)).append("\n")
.append("ATR: ").append(atr.isEmpty() ? "N/A" : atr).append("\n");
if (cardType != -1) {
sb.append("Card Type: ").append(cardType).append("\n");
}
updateUI(sb.toString(), true);
}
private void handleRFCardResult(Bundle info) {
// Log dengan detail lengkap
logRFCardData(info);
// Update UI
String uuid = info.getString("uuid", "");
String ats = info.getString("ats", "");
int sak = info.getInt("sak", -1);
StringBuilder sb = new StringBuilder();
sb.append("RF/NFC Card Detected").append("\n")
.append("UUID: ").append(uuid.isEmpty() ? "N/A" : uuid).append("\n");
if (!ats.isEmpty()) {
sb.append("ATS: ").append(ats).append("\n");
}
if (sak != -1) {
sb.append("SAK: ").append(String.format("0x%02X", sak)).append("\n");
sb.append("Type: ").append(analyzeCardTypeBySAK(sak)).append("\n");
}
updateUI(sb.toString(), true);
}
private void handleErrorResult(Bundle info) {
// Log dengan detail lengkap
logCardError(info);
// Update UI
int code = info.getInt("code", -1);
String msg = info.getString("message", "Unknown error");
String error = "Error: " + msg + " (Code: " + code + ")";
updateUI(error, true);
}
// ====== ENHANCED LOGGING METHODS ======
private void logMagneticCardData(Bundle info) {
android.util.Log.d(TAG, "=======================================");
android.util.Log.d(TAG, " MAGNETIC CARD DETECTED ");
android.util.Log.d(TAG, "=======================================");
// Track Data
String track1 = Utility.null2String(info.getString("TRACK1"));
String track2 = Utility.null2String(info.getString("TRACK2"));
String track3 = Utility.null2String(info.getString("TRACK3"));
android.util.Log.d(TAG, "TRACK DATA:");
android.util.Log.d(TAG, " Track1: " + (track1.isEmpty() ? "N/A" : track1));
android.util.Log.d(TAG, " Track2: " + (track2.isEmpty() ? "N/A" : track2));
android.util.Log.d(TAG, " Track3: " + (track3.isEmpty() ? "N/A" : track3));
// Error Codes
int track1ErrorCode = info.getInt("track1ErrorCode", 0);
int track2ErrorCode = info.getInt("track2ErrorCode", 0);
int track3ErrorCode = info.getInt("track3ErrorCode", 0);
android.util.Log.d("CreditCard", "Track1 Error Code: " + track1ErrorCode);
android.util.Log.d("CreditCard", "Track2 Error Code: " + track2ErrorCode);
android.util.Log.d("CreditCard", "Track3 Error Code: " + track3ErrorCode);
android.util.Log.d(TAG, "ERROR CODES:");
android.util.Log.d(TAG, " Track1 Error: " + track1ErrorCode);
android.util.Log.d(TAG, " Track2 Error: " + track2ErrorCode);
android.util.Log.d(TAG, " Track3 Error: " + track3ErrorCode);
// Log additional info if available
// Additional Data
String pan = info.getString("pan", "");
String serviceCode = info.getString("servicecode", "");
if (!pan.isEmpty()) android.util.Log.d("CreditCard", "PAN: " + pan);
if (!serviceCode.isEmpty()) android.util.Log.d("CreditCard", "Service Code: " + serviceCode);
String servicecode = info.getString("servicecode", "");
String expiryDate = info.getString("expiry", "");
String cardholderName = info.getString("cardholder", "");
StringBuilder sb = new StringBuilder()
.append(getString(R.string.card_mag_card_detected)).append("\n")
.append("Track1:").append(track1).append("\n")
.append("Track2:").append(track2).append("\n")
.append("Track3:").append(track3);
tvResult.setText(sb);
switchCheckCard();
android.util.Log.d(TAG, "PARSED DATA:");
android.util.Log.d(TAG, " PAN: " + (pan.isEmpty() ? "N/A" : maskPAN(pan)));
android.util.Log.d(TAG, " Service Code: " + (servicecode.isEmpty() ? "N/A" : servicecode));
android.util.Log.d(TAG, " Expiry Date: " + (expiryDate.isEmpty() ? "N/A" : expiryDate));
android.util.Log.d(TAG, " Cardholder: " + (cardholderName.isEmpty() ? "N/A" : cardholderName));
// Raw Bundle Data
android.util.Log.d(TAG, "RAW BUNDLE DATA:");
android.util.Log.d(TAG, " " + bundleToString(info));
android.util.Log.d(TAG, "=======================================");
}
private void handleICCardResult(Bundle info) {
android.util.Log.d("CreditCard", "=== IC CARD DATA ===");
private void logICCardData(Bundle info) {
android.util.Log.d(TAG, "=======================================");
android.util.Log.d(TAG, " IC CARD DETECTED ");
android.util.Log.d(TAG, "=======================================");
String atr = info.getString("atr", "");
int cardType = info.getInt("cardType", -1);
String cardTypeStr = info.getString("cardTypeStr", "");
int errorCode = info.getInt("errorCode", 0);
android.util.Log.d("CreditCard", "ATR: " + atr);
android.util.Log.d("CreditCard", "Card Type: " + cardType);
android.util.Log.d("CreditCard", "Full IC Card Data: " + bundleToString(info));
android.util.Log.d(TAG, "BASIC INFO:");
android.util.Log.d(TAG, " ATR: " + (atr.isEmpty() ? "N/A" : atr));
android.util.Log.d(TAG, " Card Type: " + cardType);
android.util.Log.d(TAG, " Card Type String: " + (cardTypeStr.isEmpty() ? "N/A" : cardTypeStr));
android.util.Log.d(TAG, " Error Code: " + errorCode);
StringBuilder sb = new StringBuilder();
sb.append(getString(R.string.card_ic_card_detected)).append("\n")
.append("ATR:").append(atr).append("\n");
if (cardType != -1) {
sb.append("Card Type:").append(cardType).append("\n");
// Parse ATR if available
if (!atr.isEmpty()) {
android.util.Log.d(TAG, "ATR ANALYSIS:");
android.util.Log.d(TAG, " ATR Length: " + atr.length() + " characters");
android.util.Log.d(TAG, " ATR Bytes: " + atr.length()/2 + " bytes");
}
tvResult.setText(sb);
switchCheckCard();
// Check for additional fields
String[] possibleKeys = {"voltage", "protocol", "clockRate", "baudRate",
"historicalBytes", "interfaceBytes", "checkByte"};
android.util.Log.d(TAG, "ADDITIONAL DATA:");
for (String key : possibleKeys) {
if (info.containsKey(key)) {
android.util.Log.d(TAG, " " + key + ": " + info.get(key));
}
}
// Raw Bundle Data
android.util.Log.d(TAG, "RAW BUNDLE DATA:");
android.util.Log.d(TAG, " " + bundleToString(info));
android.util.Log.d(TAG, "=======================================");
}
private void handleRFCardResult(Bundle info) {
android.util.Log.d("CreditCard", "=== RF/NFC CARD DATA ===");
private void logRFCardData(Bundle info) {
android.util.Log.d(TAG, "=======================================");
android.util.Log.d(TAG, " RF/NFC CARD DETECTED ");
android.util.Log.d(TAG, "=======================================");
String uuid = info.getString("uuid", "");
String ats = info.getString("ats", "");
@ -266,54 +423,128 @@ public class CreditCardActivity extends AppCompatActivity {
int sak = info.getInt("sak", -1);
int cardCategory = info.getInt("cardCategory", -1);
byte[] atqa = info.getByteArray("atqa");
int errorCode = info.getInt("errorCode", 0);
android.util.Log.d("CreditCard", "UUID: " + uuid);
android.util.Log.d("CreditCard", "ATS: " + ats);
android.util.Log.d("CreditCard", "Card Type: " + cardType);
android.util.Log.d("CreditCard", "SAK: " + sak);
android.util.Log.d("CreditCard", "Card Category: " + cardCategory);
if (atqa != null) {
android.util.Log.d("CreditCard", "ATQA: " + ByteUtil.bytes2HexStr(atqa));
}
android.util.Log.d("CreditCard", "Full RF Card Data: " + bundleToString(info));
android.util.Log.d(TAG, "BASIC INFO:");
android.util.Log.d(TAG, " UUID: " + (uuid.isEmpty() ? "N/A" : uuid));
android.util.Log.d(TAG, " ATS: " + (ats.isEmpty() ? "N/A" : ats));
android.util.Log.d(TAG, " Card Type: " + cardType);
android.util.Log.d(TAG, " SAK: " + (sak == -1 ? "N/A" : String.format("0x%02X (%d)", sak, sak)));
android.util.Log.d(TAG, " Card Category: " + cardCategory);
android.util.Log.d(TAG, " Error Code: " + errorCode);
StringBuilder sb = new StringBuilder();
sb.append("RF Card Detected").append("\n")
.append("UUID: ").append(uuid).append("\n");
if (!ats.isEmpty()) {
sb.append("ATS: ").append(ats).append("\n");
if (atqa != null && atqa.length > 0) {
android.util.Log.d(TAG, " ATQA: " + ByteUtil.bytes2HexStr(atqa) +
" (" + atqa.length + " bytes)");
} else {
android.util.Log.d(TAG, " ATQA: N/A");
}
// Analyze card type based on SAK
if (sak != -1) {
sb.append("SAK: ").append(String.format("0x%02X", sak)).append("\n");
String cardTypeAnalysis = analyzeCardTypeBySAK(sak);
android.util.Log.d(TAG, "CARD TYPE ANALYSIS:");
android.util.Log.d(TAG, " " + cardTypeAnalysis);
}
tvResult.setText(sb);
switchCheckCard();
// Check for additional NFC fields
String[] possibleKeys = {"historicalBytes", "applicationData", "protocolInfo",
"maxDataRate", "supportedProtocols", "manufacturerData"};
android.util.Log.d(TAG, "ADDITIONAL DATA:");
for (String key : possibleKeys) {
if (info.containsKey(key)) {
Object value = info.get(key);
if (value instanceof byte[]) {
android.util.Log.d(TAG, " " + key + ": " +
ByteUtil.bytes2HexStr((byte[]) value));
} else {
android.util.Log.d(TAG, " " + key + ": " + value);
}
}
}
// Raw Bundle Data
android.util.Log.d(TAG, "RAW BUNDLE DATA:");
android.util.Log.d(TAG, " " + bundleToString(info));
android.util.Log.d(TAG, "=======================================");
}
private void handleErrorResult(Bundle info) {
int code = info.getInt("code");
String msg = info.getString("message");
String error = "Error: " + msg + " (Code: " + code + ")";
tvResult.setText(error);
switchCheckCard();
private void logCardError(Bundle info) {
android.util.Log.e(TAG, "=======================================");
android.util.Log.e(TAG, " CARD READ ERROR ");
android.util.Log.e(TAG, "=======================================");
int code = info.getInt("code", -1);
String message = info.getString("message", "");
String details = info.getString("details", "");
android.util.Log.e(TAG, "ERROR INFO:");
android.util.Log.e(TAG, " Error Code: " + code);
android.util.Log.e(TAG, " Error Message: " + (message.isEmpty() ? "N/A" : message));
android.util.Log.e(TAG, " Error Details: " + (details.isEmpty() ? "N/A" : details));
// Interpret common error codes
String interpretation = interpretErrorCode(code);
android.util.Log.e(TAG, " Interpretation: " + interpretation);
// Raw Bundle Data
android.util.Log.e(TAG, "RAW ERROR DATA:");
android.util.Log.e(TAG, " " + bundleToString(info));
android.util.Log.e(TAG, "=======================================");
}
@Override
protected void onDestroy() {
cancelCheckCard();
super.onDestroy();
}
private void cancelCheckCard() {
try {
MyApplication.app.readCardOptV2.cardOff(CardType.NFC.getValue());
MyApplication.app.readCardOptV2.cardOff(CardType.IC.getValue());
MyApplication.app.readCardOptV2.cancelCheckCard();
} catch (Exception e) {
e.printStackTrace();
// ====== HELPER METHODS ======
private String analyzeCardTypeBySAK(int sak) {
switch (sak & 0xFF) {
case 0x00: return "MIFARE Ultralight";
case 0x04: return "MIFARE Classic 1K";
case 0x08: return "MIFARE Classic 1K";
case 0x09: return "MIFARE Mini";
case 0x18: return "MIFARE Classic 4K";
case 0x20: return "MIFARE Plus/DESFire";
case 0x28: return "JCOP 30";
case 0x38: return "MIFARE DESFire";
case 0x88: return "Infineon my-d move";
case 0x98: return "Gemplus MPCOS";
default: return "Unknown card type (SAK: 0x" + String.format("%02X", sak) + ")";
}
}
private String maskPAN(String pan) {
if (pan == null || pan.length() < 8) {
return pan;
}
String firstFour = pan.substring(0, 4);
String lastFour = pan.substring(pan.length() - 4);
StringBuilder middle = new StringBuilder();
for (int i = 0; i < pan.length() - 8; i++) {
middle.append("*");
}
return firstFour + middle.toString() + lastFour;
}
private String interpretErrorCode(int errorCode) {
switch (errorCode) {
case 0: return "No Error";
case -1: return "General Error";
case -2: return "Timeout";
case -3: return "User Cancelled";
case -4: return "Card Removed";
case -5: return "Hardware Error";
case -6: return "Communication Error";
case -7: return "Card Not Supported";
case -8: return "Invalid Parameter";
case -9: return "Service Not Available";
case -10: return "Permission Denied";
default: return "Unknown Error Code: " + errorCode;
}
}
/**
* Helper method to convert Bundle to readable string for logging
*/
@ -338,4 +569,46 @@ public class CreditCardActivity extends AppCompatActivity {
sb.append("}");
return sb.toString();
}
// ====== LIFECYCLE METHODS ======
@Override
protected void onDestroy() {
android.util.Log.d(TAG, "onDestroy called");
cancelCheckCard();
super.onDestroy();
}
@Override
protected void onPause() {
super.onPause();
android.util.Log.d(TAG, "onPause called");
// Optionally cancel card check when app goes to background
if (checkingCard) {
android.util.Log.d(TAG, "App paused, stopping card check");
stopCardCheck();
}
}
@Override
protected void onResume() {
super.onResume();
android.util.Log.d(TAG, "onResume called");
// Check PaySDK status when returning to app
checkPaySDKStatus();
}
private void cancelCheckCard() {
try {
if (MyApplication.app != null && MyApplication.app.readCardOptV2 != null) {
android.util.Log.d(TAG, "Cancelling card operations...");
MyApplication.app.readCardOptV2.cardOff(CardType.NFC.getValue());
MyApplication.app.readCardOptV2.cardOff(CardType.IC.getValue());
MyApplication.app.readCardOptV2.cancelCheckCard();
android.util.Log.d(TAG, "Card operations cancelled successfully");
}
} catch (Exception e) {
android.util.Log.e(TAG, "Error cancelling card operations: " + e.getMessage());
e.printStackTrace();
}
}
}