card Scanning tanpa button

This commit is contained in:
riz081 2025-06-22 22:03:22 +07:00
parent 174a1461fd
commit d43c4bad0c
2 changed files with 163 additions and 43 deletions

View File

@ -55,7 +55,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
private String transactionAmount;
private boolean isEMVMode;
private boolean isProcessing = false;
private boolean isButtonProcessing = false;
private boolean isButtonProcessing = false; // ADD THIS MISSING FIELD
// EMV Components
private EMVOptV2 mEMVOptV2;
@ -178,7 +178,11 @@ public class EmvTransactionActivity extends AppCompatActivity {
initViews();
initEMVComponents();
initEMVData();
updateUI();
// Auto-start scanning after short delay
new Handler(Looper.getMainLooper()).postDelayed(() -> {
autoStartScanning();
}, 1000); // 1 second delay to let everything initialize
}
private void getIntentData() {
@ -290,6 +294,38 @@ public class EmvTransactionActivity extends AppCompatActivity {
}
}
// ====== AUTO-SCAN METHODS ======
private void autoStartScanning() {
Log.d(TAG, "Auto-starting card scanning...");
if (isProcessing) {
Log.d(TAG, "Already processing - ignoring auto-start");
return;
}
runOnUiThread(() -> {
tvStatus.setText("Ready for card...\n\nPlease insert, swipe, or tap your card\n\nScanning will start automatically");
btnAction.setText("CANCEL");
btnAction.setEnabled(true);
});
// Start scanning automatically
startCardCheck();
}
private void restartAutoScanning() {
Log.d(TAG, "Restarting auto-scanning after delay...");
// Wait a bit before restarting
new Handler(Looper.getMainLooper()).postDelayed(() -> {
if (!isFinishing() && !isProcessing) {
autoStartScanning();
}
}, 2000); // 2 second delay before restart
}
// ====== CARD SCANNING METHODS ======
private void updateUI() {
long amountCents = Long.parseLong(transactionAmount);
double amountRupiah = amountCents / 100.0;
@ -299,12 +335,13 @@ public class EmvTransactionActivity extends AppCompatActivity {
tvAmountDisplay.setText("Nominal: " + formattedAmount);
String mode = isEMVMode ? "EMV Mode (Full Card Data)" : "Simple Mode (Basic Detection)";
String status = "Ready to scan card...\n" +
"Current Mode: " + mode + "\n\n" +
"Please insert, swipe, or tap your card";
String status = "Auto-scanning active...\n" +
"Mode: " + mode + "\n\n" +
"Please insert, swipe, or tap your card\n" +
"Processing will start automatically";
tvStatus.setText(status);
btnAction.setText("Start Scanning");
btnAction.setText("CANCEL");
}
private void handleActionClick() {
@ -321,10 +358,12 @@ public class EmvTransactionActivity extends AppCompatActivity {
btnAction.postDelayed(() -> isButtonProcessing = false, 1000);
if (mProcessStep == 0) {
// Only handle cancel in auto-scan mode
if (isProcessing) {
stopCardCheck();
cancelScanning();
} else {
startCardCheck();
// If not processing, this becomes cancel to go back
finish();
}
} else if (mProcessStep == EMV_CONFIRM_CARD_NO) {
android.util.Log.d(TAG, "User confirmed card number");
@ -337,6 +376,33 @@ public class EmvTransactionActivity extends AppCompatActivity {
}
}
private void cancelScanning() {
Log.d(TAG, "User cancelled scanning");
try {
// Cancel current operations
if (MyApplication.app != null && MyApplication.app.readCardOptV2 != null) {
MyApplication.app.readCardOptV2.cancelCheckCard();
}
// Reset EMV process
if (mEMVOptV2 != null) {
mEMVOptV2.initEmvProcess();
}
// Reset state
isProcessing = false;
mProcessStep = 0;
// Go back to previous activity
finish();
} catch (Exception e) {
Log.e(TAG, "Error cancelling scan: " + e.getMessage(), e);
finish();
}
}
private void startCardCheck() {
// Prevent multiple calls
if (isProcessing) {
@ -344,10 +410,14 @@ public class EmvTransactionActivity extends AppCompatActivity {
return;
}
Log.d(TAG, "Starting card check - setting isProcessing = true");
Log.d(TAG, "Starting auto card check - setting isProcessing = true");
isProcessing = true;
btnAction.setText("Initializing...");
btnAction.setEnabled(false);
runOnUiThread(() -> {
tvStatus.setText("Initializing scanner...\n\nPlease wait...");
btnAction.setText("CANCEL");
btnAction.setEnabled(true);
});
try {
// Force EMV reset before any operation
@ -356,8 +426,8 @@ public class EmvTransactionActivity extends AppCompatActivity {
mEMVOptV2.initEmvProcess();
// Wait a bit before continuing
btnAction.postDelayed(() -> {
if (isProcessing) { // Double check we're still processing
new Handler(Looper.getMainLooper()).postDelayed(() -> {
if (isProcessing && !isFinishing()) { // Double check we're still processing
continueCardCheck();
}
}, 500);
@ -368,8 +438,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
} catch (Exception e) {
Log.e(TAG, "Error in startCardCheck: " + e.getMessage(), e);
resetScanningState();
showToast("Error: " + e.getMessage());
handleScanError("Error: " + e.getMessage());
}
}
@ -382,8 +451,12 @@ public class EmvTransactionActivity extends AppCompatActivity {
return;
}
btnAction.setText("Stop Scanning");
btnAction.setEnabled(true);
runOnUiThread(() -> {
String mode = isEMVMode ? "EMV Mode" : "Simple Mode";
tvStatus.setText("Scanning for card...\n\nMode: " + mode + "\n\nPlease insert, swipe, or tap your card");
btnAction.setText("CANCEL");
btnAction.setEnabled(true);
});
if (isEMVMode) {
startEMVCardCheck();
@ -393,11 +466,27 @@ public class EmvTransactionActivity extends AppCompatActivity {
} catch (Exception e) {
Log.e(TAG, "Error in continueCardCheck: " + e.getMessage(), e);
resetScanningState();
showToast("Error: " + e.getMessage());
handleScanError("Error: " + e.getMessage());
}
}
private void handleScanError(String errorMessage) {
Log.e(TAG, "Scan error: " + errorMessage);
runOnUiThread(() -> {
isProcessing = false;
mProcessStep = 0;
tvStatus.setText("Scan error: " + errorMessage + "\n\nRetrying in 2 seconds...");
btnAction.setText("CANCEL");
showToast(errorMessage);
// Auto-restart scanning after error
restartAutoScanning();
});
}
private void startEMVCardCheck() {
try {
if (mEMVOptV2 == null) {
@ -908,29 +997,37 @@ public class EmvTransactionActivity extends AppCompatActivity {
Thread.sleep(1500); // Wait longer for complete reset
runOnUiThread(() -> {
Log.d(TAG, "EMV reset complete - ready for retry");
resetScanningState();
showToast("Ready to scan - please try again");
Log.d(TAG, "EMV reset complete - auto-restarting scan");
isProcessing = false;
mProcessStep = 0;
tvStatus.setText("EMV reset complete\n\nRestarting auto-scan...");
showToast("EMV reset - restarting scan");
// Auto-restart scanning
restartAutoScanning();
});
} catch (Exception e) {
Log.e(TAG, "Error resetting EMV: " + e.getMessage(), e);
runOnUiThread(() -> {
resetScanningState();
showToast("Reset failed - please try again");
handleScanError("Reset failed - " + e.getMessage());
});
}
}).start();
}
private void resetScanningState() {
Log.d(TAG, "Resetting scanning state");
Log.d(TAG, "Resetting scanning state for auto-scan mode");
isProcessing = false;
isButtonProcessing = false;
mProcessStep = 0;
btnAction.setText("Start Scanning");
btnAction.setEnabled(true);
updateUI(); // Reset UI to initial state
runOnUiThread(() -> {
btnAction.setText("CANCEL");
btnAction.setEnabled(true);
updateUI();
});
}
// ====== HELPER METHODS ======
@ -1060,7 +1157,10 @@ public class EmvTransactionActivity extends AppCompatActivity {
@Override
protected void onDestroy() {
Log.d(TAG, "onDestroy - cleaning up EMV resources");
Log.d(TAG, "onDestroy - cleaning up auto-scan resources");
// Stop auto-scanning
isProcessing = false;
try {
// Cancel card operations
@ -1079,4 +1179,24 @@ public class EmvTransactionActivity extends AppCompatActivity {
super.onDestroy();
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause - pausing auto-scan");
// Don't stop scanning on pause - let it continue in background
// This allows card detection even if screen goes off briefly
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume - resuming auto-scan");
// If we're not processing and not finishing, restart auto-scan
if (!isProcessing && !isFinishing() && mProcessStep == 0) {
restartAutoScanning();
}
}
}

View File

@ -94,31 +94,31 @@
<!-- Card Reader Animation/Icon -->
<ImageView
android:id="@+id/iv_card_reader"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_gravity="center"
android:layout_marginBottom="20dp"
android:layout_marginBottom="16dp"
android:src="@drawable/ic_card_insert"
android:scaleType="centerInside"
app:tint="#666666" />
<!-- Status Text -->
<!-- Auto-Scan Status Text -->
<TextView
android:id="@+id/tv_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Ready to scan card..."
android:text="Auto-scanning active..."
style="@style/StatusTextStyle"
android:layout_marginBottom="16dp" />
<!-- Progress Indicator (Initially Hidden) -->
<!-- Progress Indicator (Initially Visible for Auto-Scan) -->
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyle"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:visibility="gone"
android:visibility="visible"
android:indeterminateTint="@color/primary_blue" />
</LinearLayout>
@ -132,30 +132,30 @@
android:orientation="vertical"
android:layout_marginBottom="16dp">
<!-- Main Action Button -->
<!-- Cancel Button (Primary Action) -->
<Button
android:id="@+id/btn_action"
android:layout_width="match_parent"
android:layout_height="56dp"
android:text="Start Scanning"
style="@style/PrimaryButton"
android:text="CANCEL"
style="@style/OutlineButton"
android:layout_marginBottom="12dp" />
<!-- Cancel Button -->
<!-- Secondary Cancel Button -->
<Button
android:id="@+id/btn_cancel"
android:layout_width="match_parent"
android:layout_height="48dp"
android:text="BATAL"
android:text="BACK TO AMOUNT"
style="@style/OutlineButton" />
</LinearLayout>
<!-- Instructions -->
<!-- Auto-Scan Instructions -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="• Pastikan kartu dalam kondisi baik\n• Ikuti instruksi yang muncul di layar\n• Jangan cabut kartu sampai proses selesai"
android:text="• Scanning starts automatically when you enter\n• Card will be detected and processed immediately\n• No need to press any buttons - just present your card"
style="@style/HintTextStyle" />
</LinearLayout>