Safepoint Modal Scan Card
This commit is contained in:
parent
d43c4bad0c
commit
f403358554
@ -8,7 +8,9 @@ import android.os.Message;
|
|||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Button;
|
import android.view.View;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@ -45,17 +47,15 @@ import java.util.regex.Pattern;
|
|||||||
public class EmvTransactionActivity extends AppCompatActivity {
|
public class EmvTransactionActivity extends AppCompatActivity {
|
||||||
private static final String TAG = "EmvTransaction";
|
private static final String TAG = "EmvTransaction";
|
||||||
|
|
||||||
// UI Components
|
// UI Components - SIMPLIFIED
|
||||||
private TextView tvStatus;
|
private TextView tvStatus;
|
||||||
private TextView tvAmountDisplay;
|
private ProgressBar progressBar;
|
||||||
private Button btnAction;
|
private ImageView ivCardReader;
|
||||||
private Button btnCancel;
|
|
||||||
|
|
||||||
// Transaction Data
|
// Transaction Data
|
||||||
private String transactionAmount;
|
private String transactionAmount;
|
||||||
private boolean isEMVMode;
|
private boolean isEMVMode;
|
||||||
private boolean isProcessing = false;
|
private boolean isProcessing = false;
|
||||||
private boolean isButtonProcessing = false; // ADD THIS MISSING FIELD
|
|
||||||
|
|
||||||
// EMV Components
|
// EMV Components
|
||||||
private EMVOptV2 mEMVOptV2;
|
private EMVOptV2 mEMVOptV2;
|
||||||
@ -197,8 +197,9 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====== UPDATED INIT VIEWS METHOD ======
|
||||||
private void initViews() {
|
private void initViews() {
|
||||||
// Setup Toolbar
|
// Setup Toolbar with back navigation
|
||||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
if (getSupportActionBar() != null) {
|
if (getSupportActionBar() != null) {
|
||||||
@ -206,13 +207,21 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
getSupportActionBar().setTitle("Scan Kartu");
|
getSupportActionBar().setTitle("Scan Kartu");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize UI components
|
||||||
tvStatus = findViewById(R.id.tv_status);
|
tvStatus = findViewById(R.id.tv_status);
|
||||||
tvAmountDisplay = findViewById(R.id.tv_amount_display);
|
progressBar = findViewById(R.id.progress_bar);
|
||||||
btnAction = findViewById(R.id.btn_action);
|
ivCardReader = findViewById(R.id.iv_card_reader);
|
||||||
btnCancel = findViewById(R.id.btn_cancel);
|
|
||||||
|
|
||||||
btnAction.setOnClickListener(v -> handleActionClick());
|
// Set initial state
|
||||||
btnCancel.setOnClickListener(v -> finish());
|
updateStatusUI("Initializing scanner...", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====== NEW METHOD TO UPDATE STATUS UI ======
|
||||||
|
private void updateStatusUI(String statusText, boolean showProgress) {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
tvStatus.setText(statusText);
|
||||||
|
progressBar.setVisibility(showProgress ? View.VISIBLE : View.GONE);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initEMVComponents() {
|
private void initEMVComponents() {
|
||||||
@ -294,7 +303,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====== AUTO-SCAN METHODS ======
|
// ====== UPDATED AUTO-START SCANNING METHOD ======
|
||||||
private void autoStartScanning() {
|
private void autoStartScanning() {
|
||||||
Log.d(TAG, "Auto-starting card scanning...");
|
Log.d(TAG, "Auto-starting card scanning...");
|
||||||
|
|
||||||
@ -303,11 +312,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
runOnUiThread(() -> {
|
updateStatusUI("Ready for card...\n\nPlease insert, swipe, or tap your card\n\nScanning will start automatically", true);
|
||||||
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
|
// Start scanning automatically
|
||||||
startCardCheck();
|
startCardCheck();
|
||||||
@ -324,87 +329,8 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
}, 2000); // 2 second delay before restart
|
}, 2000); // 2 second delay before restart
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====== CARD SCANNING METHODS ======
|
// ====== UPDATED CARD CHECK METHODS ======
|
||||||
|
|
||||||
private void updateUI() {
|
|
||||||
long amountCents = Long.parseLong(transactionAmount);
|
|
||||||
double amountRupiah = amountCents / 100.0;
|
|
||||||
NumberFormat formatter = NumberFormat.getCurrencyInstance(new Locale("id", "ID"));
|
|
||||||
String formattedAmount = formatter.format(amountRupiah);
|
|
||||||
|
|
||||||
tvAmountDisplay.setText("Nominal: " + formattedAmount);
|
|
||||||
|
|
||||||
String mode = isEMVMode ? "EMV Mode (Full Card Data)" : "Simple Mode (Basic Detection)";
|
|
||||||
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("CANCEL");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleActionClick() {
|
|
||||||
// Prevent multiple rapid clicks
|
|
||||||
if (isButtonProcessing) {
|
|
||||||
Log.d(TAG, "Button click ignored - already processing");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
isButtonProcessing = true;
|
|
||||||
Log.d(TAG, "handleActionClick - mProcessStep: " + mProcessStep + ", isProcessing: " + isProcessing);
|
|
||||||
|
|
||||||
// Reset button processing flag after delay
|
|
||||||
btnAction.postDelayed(() -> isButtonProcessing = false, 1000);
|
|
||||||
|
|
||||||
if (mProcessStep == 0) {
|
|
||||||
// Only handle cancel in auto-scan mode
|
|
||||||
if (isProcessing) {
|
|
||||||
cancelScanning();
|
|
||||||
} else {
|
|
||||||
// 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");
|
|
||||||
btnAction.setText("Processing...");
|
|
||||||
importCardNoStatus(0);
|
|
||||||
} else if (mProcessStep == EMV_CERT_VERIFY) {
|
|
||||||
android.util.Log.d(TAG, "User confirmed certificate");
|
|
||||||
btnAction.setText("Processing...");
|
|
||||||
importCertStatus(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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() {
|
private void startCardCheck() {
|
||||||
// Prevent multiple calls
|
|
||||||
if (isProcessing) {
|
if (isProcessing) {
|
||||||
Log.d(TAG, "Card check already in progress - ignoring call");
|
Log.d(TAG, "Card check already in progress - ignoring call");
|
||||||
return;
|
return;
|
||||||
@ -413,21 +339,15 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
Log.d(TAG, "Starting auto card check - setting isProcessing = true");
|
Log.d(TAG, "Starting auto card check - setting isProcessing = true");
|
||||||
isProcessing = true;
|
isProcessing = true;
|
||||||
|
|
||||||
runOnUiThread(() -> {
|
updateStatusUI("Initializing scanner...\n\nPlease wait...", true);
|
||||||
tvStatus.setText("Initializing scanner...\n\nPlease wait...");
|
|
||||||
btnAction.setText("CANCEL");
|
|
||||||
btnAction.setEnabled(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Force EMV reset before any operation
|
|
||||||
if (mEMVOptV2 != null) {
|
if (mEMVOptV2 != null) {
|
||||||
Log.d(TAG, "Forcing EMV reset before card check");
|
Log.d(TAG, "Forcing EMV reset before card check");
|
||||||
mEMVOptV2.initEmvProcess();
|
mEMVOptV2.initEmvProcess();
|
||||||
|
|
||||||
// Wait a bit before continuing
|
|
||||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||||
if (isProcessing && !isFinishing()) { // Double check we're still processing
|
if (isProcessing && !isFinishing()) {
|
||||||
continueCardCheck();
|
continueCardCheck();
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
@ -451,12 +371,8 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
runOnUiThread(() -> {
|
String mode = isEMVMode ? "EMV Mode" : "Simple Mode";
|
||||||
String mode = isEMVMode ? "EMV Mode" : "Simple Mode";
|
updateStatusUI("Scanning for card...\n\nMode: " + mode + "\n\nPlease insert, swipe, or tap your card", true);
|
||||||
tvStatus.setText("Scanning for card...\n\nMode: " + mode + "\n\nPlease insert, swipe, or tap your card");
|
|
||||||
btnAction.setText("CANCEL");
|
|
||||||
btnAction.setEnabled(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isEMVMode) {
|
if (isEMVMode) {
|
||||||
startEMVCardCheck();
|
startEMVCardCheck();
|
||||||
@ -470,21 +386,18 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====== UPDATED HANDLE SCAN ERROR ======
|
||||||
private void handleScanError(String errorMessage) {
|
private void handleScanError(String errorMessage) {
|
||||||
Log.e(TAG, "Scan error: " + errorMessage);
|
Log.e(TAG, "Scan error: " + errorMessage);
|
||||||
|
|
||||||
runOnUiThread(() -> {
|
isProcessing = false;
|
||||||
isProcessing = false;
|
mProcessStep = 0;
|
||||||
mProcessStep = 0;
|
|
||||||
|
updateStatusUI("Scan error: " + errorMessage + "\n\nRetrying in 2 seconds...", false);
|
||||||
tvStatus.setText("Scan error: " + errorMessage + "\n\nRetrying in 2 seconds...");
|
showToast(errorMessage);
|
||||||
btnAction.setText("CANCEL");
|
|
||||||
|
// Auto-restart scanning after error
|
||||||
showToast(errorMessage);
|
restartAutoScanning();
|
||||||
|
|
||||||
// Auto-restart scanning after error
|
|
||||||
restartAutoScanning();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startEMVCardCheck() {
|
private void startEMVCardCheck() {
|
||||||
@ -497,7 +410,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
mEMVOptV2.initEmvProcess();
|
mEMVOptV2.initEmvProcess();
|
||||||
initEmvTlvData();
|
initEmvTlvData();
|
||||||
|
|
||||||
tvStatus.setText("EMV Mode: Starting card scan...\nPlease insert, swipe, or tap your card");
|
updateStatusUI("EMV Mode: Starting card scan...\nPlease insert, swipe, or tap your card", true);
|
||||||
|
|
||||||
int cardType = AidlConstantsV2.CardType.NFC.getValue() | AidlConstantsV2.CardType.IC.getValue();
|
int cardType = AidlConstantsV2.CardType.NFC.getValue() | AidlConstantsV2.CardType.IC.getValue();
|
||||||
android.util.Log.d(TAG, "Starting EMV checkCard with cardType: " + cardType);
|
android.util.Log.d(TAG, "Starting EMV checkCard with cardType: " + cardType);
|
||||||
@ -514,13 +427,13 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
private void startSimpleCardCheck() {
|
private void startSimpleCardCheck() {
|
||||||
try {
|
try {
|
||||||
if (!MyApplication.app.isConnectPaySDK()) {
|
if (!MyApplication.app.isConnectPaySDK()) {
|
||||||
tvStatus.setText("Connecting to PaySDK...");
|
updateStatusUI("Connecting to PaySDK...", true);
|
||||||
MyApplication.app.bindPaySDKService();
|
MyApplication.app.bindPaySDKService();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cardType = CardType.MAGNETIC.getValue() | CardType.IC.getValue() | CardType.NFC.getValue();
|
int cardType = CardType.MAGNETIC.getValue() | CardType.IC.getValue() | CardType.NFC.getValue();
|
||||||
tvStatus.setText("Simple Mode: Starting card scan...\nPlease insert, swipe, or tap your card");
|
updateStatusUI("Simple Mode: Starting card scan...\nPlease insert, swipe, or tap your card", true);
|
||||||
|
|
||||||
MyApplication.app.readCardOptV2.checkCard(cardType, mSimpleCheckCardCallback, 60);
|
MyApplication.app.readCardOptV2.checkCard(cardType, mSimpleCheckCardCallback, 60);
|
||||||
|
|
||||||
@ -536,8 +449,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
MyApplication.app.readCardOptV2.cancelCheckCard();
|
MyApplication.app.readCardOptV2.cancelCheckCard();
|
||||||
}
|
}
|
||||||
isProcessing = false;
|
isProcessing = false;
|
||||||
btnAction.setText("Start Scanning");
|
updateStatusUI("Ready for card...\n\nPlease insert, swipe, or tap your card", true);
|
||||||
updateUI();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
android.util.Log.e(TAG, "Error stopping card check: " + e.getMessage());
|
android.util.Log.e(TAG, "Error stopping card check: " + e.getMessage());
|
||||||
}
|
}
|
||||||
@ -688,7 +600,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
bundle.putInt("cardType", mCardType);
|
bundle.putInt("cardType", mCardType);
|
||||||
|
|
||||||
tvStatus.setText("EMV processing started...\nReading card data...");
|
updateStatusUI("EMV processing started...\nReading card data...", true);
|
||||||
|
|
||||||
Log.d(TAG, "Starting transactProcessEx with reset EMV");
|
Log.d(TAG, "Starting transactProcessEx with reset EMV");
|
||||||
mEMVOptV2.transactProcessEx(bundle, mEMVListener);
|
mEMVOptV2.transactProcessEx(bundle, mEMVListener);
|
||||||
@ -833,16 +745,16 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
mAppSelectDialog.show();
|
mAppSelectDialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====== UPDATED EMV DIALOG HANDLERS ======
|
||||||
private void showCardNumberConfirmation() {
|
private void showCardNumberConfirmation() {
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
String displayText = "Card Number: " + maskCardNumber(mCardNo) +
|
String displayText = "Card Number Detected:\n" + maskCardNumber(mCardNo) +
|
||||||
"\n\nConfirming card number automatically...";
|
"\n\nConfirming automatically...";
|
||||||
tvStatus.setText(displayText);
|
updateStatusUI(displayText, true);
|
||||||
|
|
||||||
// Auto-confirm after short delay to avoid manual interaction
|
// Auto-confirm after short delay
|
||||||
btnAction.postDelayed(() -> {
|
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||||
Log.d(TAG, "Auto-confirming card number");
|
Log.d(TAG, "Auto-confirming card number");
|
||||||
btnAction.setText("Processing...");
|
|
||||||
importCardNoStatus(0);
|
importCardNoStatus(0);
|
||||||
}, 1500);
|
}, 1500);
|
||||||
|
|
||||||
@ -852,14 +764,13 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
private void showCertificateVerification() {
|
private void showCertificateVerification() {
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
String displayText = "Certificate Information:\n" + mCertInfo +
|
String displayText = "Certificate Verification:\n" + mCertInfo +
|
||||||
"\n\nConfirming certificate automatically...";
|
"\n\nProcessing automatically...";
|
||||||
tvStatus.setText(displayText);
|
updateStatusUI(displayText, true);
|
||||||
|
|
||||||
// Auto-confirm after short delay
|
// Auto-confirm after short delay
|
||||||
btnAction.postDelayed(() -> {
|
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||||
Log.d(TAG, "Auto-confirming certificate");
|
Log.d(TAG, "Auto-confirming certificate");
|
||||||
btnAction.setText("Processing...");
|
|
||||||
importCertStatus(0);
|
importCertStatus(0);
|
||||||
}, 1500);
|
}, 1500);
|
||||||
|
|
||||||
@ -867,7 +778,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====== PIN PAD METHODS ======
|
// ====== UPDATED PIN PAD METHODS ======
|
||||||
private void initPinPad() {
|
private void initPinPad() {
|
||||||
android.util.Log.e(TAG, "========== PIN PAD INITIALIZATION ==========");
|
android.util.Log.e(TAG, "========== PIN PAD INITIALIZATION ==========");
|
||||||
try {
|
try {
|
||||||
@ -882,7 +793,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
PinPadConfigV2 pinPadConfig = new PinPadConfigV2();
|
PinPadConfigV2 pinPadConfig = new PinPadConfigV2();
|
||||||
pinPadConfig.setPinPadType(0);
|
pinPadConfig.setPinPadType(0);
|
||||||
pinPadConfig.setPinType(mPinType);
|
pinPadConfig.setPinType(mPinType);
|
||||||
pinPadConfig.setOrderNumKey(false);
|
pinPadConfig.setOrderNumKey(true);
|
||||||
|
|
||||||
String panForPin = mCardNo.substring(mCardNo.length() - 13, mCardNo.length() - 1);
|
String panForPin = mCardNo.substring(mCardNo.length() - 13, mCardNo.length() - 1);
|
||||||
byte[] panBytes = panForPin.getBytes("US-ASCII");
|
byte[] panBytes = panForPin.getBytes("US-ASCII");
|
||||||
@ -895,11 +806,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
pinPadConfig.setKeySystem(0);
|
pinPadConfig.setKeySystem(0);
|
||||||
pinPadConfig.setAlgorithmType(0);
|
pinPadConfig.setAlgorithmType(0);
|
||||||
|
|
||||||
runOnUiThread(() -> {
|
updateStatusUI("PIN Input Required\n\nPIN pad is ready\nPlease enter your PIN on the device", true);
|
||||||
tvStatus.setText("PIN Input Required\n\nPIN pad is ready\nPlease enter your PIN on the device");
|
|
||||||
btnAction.setText("PIN Pad Active");
|
|
||||||
btnAction.setEnabled(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
mPinPadOptV2.initPinPad(pinPadConfig, mPinPadListener);
|
mPinPadOptV2.initPinPad(pinPadConfig, mPinPadListener);
|
||||||
|
|
||||||
@ -910,6 +817,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====== UPDATED PIN PAD LISTENER ======
|
||||||
private final PinPadListenerV2 mPinPadListener = new PinPadListenerV2.Stub() {
|
private final PinPadListenerV2 mPinPadListener = new PinPadListenerV2.Stub() {
|
||||||
@Override
|
@Override
|
||||||
public void onPinLength(int len) throws RemoteException {
|
public void onPinLength(int len) throws RemoteException {
|
||||||
@ -919,7 +827,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
dots += "• ";
|
dots += "• ";
|
||||||
}
|
}
|
||||||
tvStatus.setText("PIN Input: " + dots + "\n\nEntering PIN... (" + len + " digits)");
|
updateStatusUI("PIN Input: " + dots + "\n\nEntering PIN... (" + len + " digits)", true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -928,9 +836,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
android.util.Log.d(TAG, "PIN input confirmed");
|
android.util.Log.d(TAG, "PIN input confirmed");
|
||||||
|
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
btnAction.setEnabled(true);
|
updateStatusUI("PIN confirmed, processing...", true);
|
||||||
btnAction.setText("Processing...");
|
|
||||||
tvStatus.setText("PIN confirmed, processing...");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (pinBlock != null) {
|
if (pinBlock != null) {
|
||||||
@ -948,9 +854,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
android.util.Log.d(TAG, "PIN input cancelled by user");
|
android.util.Log.d(TAG, "PIN input cancelled by user");
|
||||||
|
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
btnAction.setEnabled(true);
|
updateStatusUI("PIN input cancelled", false);
|
||||||
btnAction.setText("Start Scanning");
|
|
||||||
tvStatus.setText("PIN input cancelled");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
mHandler.obtainMessage(PIN_CLICK_CANCEL).sendToTarget();
|
mHandler.obtainMessage(PIN_CLICK_CANCEL).sendToTarget();
|
||||||
@ -962,9 +866,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
String msg = AidlErrorCodeV2.valueOf(code).getMsg();
|
String msg = AidlErrorCodeV2.valueOf(code).getMsg();
|
||||||
|
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
btnAction.setEnabled(true);
|
updateStatusUI("PIN error: " + msg, false);
|
||||||
btnAction.setText("Start Scanning");
|
|
||||||
tvStatus.setText("PIN error: " + msg);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
mHandler.obtainMessage(PIN_ERROR, code, code, msg).sendToTarget();
|
mHandler.obtainMessage(PIN_ERROR, code, code, msg).sendToTarget();
|
||||||
@ -1001,7 +903,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
isProcessing = false;
|
isProcessing = false;
|
||||||
mProcessStep = 0;
|
mProcessStep = 0;
|
||||||
|
|
||||||
tvStatus.setText("EMV reset complete\n\nRestarting auto-scan...");
|
updateStatusUI("EMV reset complete\n\nRestarting auto-scan...", true);
|
||||||
showToast("EMV reset - restarting scan");
|
showToast("EMV reset - restarting scan");
|
||||||
|
|
||||||
// Auto-restart scanning
|
// Auto-restart scanning
|
||||||
@ -1017,17 +919,13 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====== UPDATED RESET SCANNING STATE ======
|
||||||
private void resetScanningState() {
|
private void resetScanningState() {
|
||||||
Log.d(TAG, "Resetting scanning state for auto-scan mode");
|
Log.d(TAG, "Resetting scanning state for auto-scan mode");
|
||||||
isProcessing = false;
|
isProcessing = false;
|
||||||
isButtonProcessing = false;
|
|
||||||
mProcessStep = 0;
|
mProcessStep = 0;
|
||||||
|
|
||||||
runOnUiThread(() -> {
|
updateStatusUI("Ready for card...\n\nPlease insert, swipe, or tap your card", true);
|
||||||
btnAction.setText("CANCEL");
|
|
||||||
btnAction.setEnabled(true);
|
|
||||||
updateUI();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====== HELPER METHODS ======
|
// ====== HELPER METHODS ======
|
||||||
@ -1041,10 +939,11 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====== UPDATED MOCK ONLINE PROCESS ======
|
||||||
private void mockOnlineProcess() {
|
private void mockOnlineProcess() {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
runOnUiThread(() -> tvStatus.setText("Processing online authorization..."));
|
runOnUiThread(() -> updateStatusUI("Processing online authorization...", true));
|
||||||
Thread.sleep(2000);
|
Thread.sleep(2000);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -1149,9 +1048,29 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
|||||||
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====== UPDATED ON SUPPORT NAVIGATE UP ======
|
||||||
@Override
|
@Override
|
||||||
public boolean onSupportNavigateUp() {
|
public boolean onSupportNavigateUp() {
|
||||||
onBackPressed();
|
// Handle back button press - clean up and go back
|
||||||
|
try {
|
||||||
|
// Cancel any ongoing operations
|
||||||
|
if (MyApplication.app != null && MyApplication.app.readCardOptV2 != null) {
|
||||||
|
MyApplication.app.readCardOptV2.cancelCheckCard();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset EMV process
|
||||||
|
if (mEMVOptV2 != null) {
|
||||||
|
mEMVOptV2.initEmvProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
isProcessing = false;
|
||||||
|
mProcessStep = 0;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error cleaning up on back press: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
finish();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
|
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:duration="300"
|
android:duration="300"
|
||||||
android:fromAlpha="0.0"
|
android:fromAlpha="0.0"
|
||||||
android:toAlpha="1.0" />
|
android:toAlpha="1.0" />
|
@ -17,147 +17,91 @@
|
|||||||
android:theme="@style/CustomToolbarTheme"
|
android:theme="@style/CustomToolbarTheme"
|
||||||
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
|
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
|
||||||
|
|
||||||
<!-- Content Container -->
|
<!-- Main Content Container with Center Alignment -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="16dp">
|
android:gravity="center"
|
||||||
|
android:padding="24dp">
|
||||||
|
|
||||||
<!-- Amount Display Card -->
|
<!-- Status Modal Card - Centered and Compact -->
|
||||||
<androidx.cardview.widget.CardView
|
<androidx.cardview.widget.CardView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="24dp"
|
android:layout_gravity="center"
|
||||||
app:cardCornerRadius="12dp"
|
app:cardCornerRadius="16dp"
|
||||||
app:cardElevation="4dp"
|
app:cardElevation="8dp"
|
||||||
app:cardBackgroundColor="@color/primary_blue">
|
app:cardBackgroundColor="@android:color/white">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="20dp">
|
android:padding="32dp"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<!-- Header Title -->
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Card Scanner"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#2E3A47"
|
||||||
|
android:gravity="center"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:layout_marginBottom="24dp" />
|
||||||
|
|
||||||
|
<!-- Card Reader Animation/Icon -->
|
||||||
<ImageView
|
<ImageView
|
||||||
|
android:id="@+id/iv_card_reader"
|
||||||
|
android:layout_width="120dp"
|
||||||
|
android:layout_height="120dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginBottom="24dp"
|
||||||
|
android:src="@drawable/ic_card_insert"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
app:tint="@color/primary_blue" />
|
||||||
|
|
||||||
|
<!-- Status Text -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_status"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Ready for card scanning..."
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="#5A6C7D"
|
||||||
|
android:gravity="center"
|
||||||
|
android:lineSpacingExtra="4dp"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:layout_marginBottom="24dp" />
|
||||||
|
|
||||||
|
<!-- Progress Indicator -->
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress_bar"
|
||||||
|
style="?android:attr/progressBarStyle"
|
||||||
android:layout_width="48dp"
|
android:layout_width="48dp"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_marginBottom="12dp"
|
android:visibility="visible"
|
||||||
android:src="@drawable/ic_credit_card"
|
android:indeterminateTint="@color/primary_blue"
|
||||||
app:tint="@android:color/white" />
|
android:layout_marginBottom="16dp" />
|
||||||
|
|
||||||
|
<!-- Instructions Text -->
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_amount_display"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Nominal: Rp 0,00"
|
android:text="Please insert, tap, or swipe your card\nScanning will start automatically"
|
||||||
android:textSize="20sp"
|
android:textSize="14sp"
|
||||||
android:textStyle="bold"
|
android:textColor="#8A9BAE"
|
||||||
android:textColor="@color/white"
|
android:gravity="center"
|
||||||
android:fontFamily="@font/inter"
|
android:lineSpacingExtra="2dp"
|
||||||
android:gravity="center" />
|
android:fontFamily="@font/inter" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</androidx.cardview.widget.CardView>
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
<!-- Status Card -->
|
|
||||||
<androidx.cardview.widget.CardView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_marginBottom="24dp"
|
|
||||||
app:cardCornerRadius="12dp"
|
|
||||||
app:cardElevation="4dp">
|
|
||||||
|
|
||||||
<ScrollView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:fillViewport="true">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="20dp">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Status Transaksi"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:textColor="#333333"
|
|
||||||
android:gravity="center"
|
|
||||||
android:layout_marginBottom="16dp" />
|
|
||||||
|
|
||||||
<!-- Card Reader Animation/Icon -->
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/iv_card_reader"
|
|
||||||
android:layout_width="80dp"
|
|
||||||
android:layout_height="80dp"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:src="@drawable/ic_card_insert"
|
|
||||||
android:scaleType="centerInside"
|
|
||||||
app:tint="#666666" />
|
|
||||||
|
|
||||||
<!-- Auto-Scan Status Text -->
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tv_status"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Auto-scanning active..."
|
|
||||||
style="@style/StatusTextStyle"
|
|
||||||
android:layout_marginBottom="16dp" />
|
|
||||||
|
|
||||||
<!-- 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="visible"
|
|
||||||
android:indeterminateTint="@color/primary_blue" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</ScrollView>
|
|
||||||
</androidx.cardview.widget.CardView>
|
|
||||||
|
|
||||||
<!-- Action Buttons -->
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_marginBottom="16dp">
|
|
||||||
|
|
||||||
<!-- Cancel Button (Primary Action) -->
|
|
||||||
<Button
|
|
||||||
android:id="@+id/btn_action"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="56dp"
|
|
||||||
android:text="CANCEL"
|
|
||||||
style="@style/OutlineButton"
|
|
||||||
android:layout_marginBottom="12dp" />
|
|
||||||
|
|
||||||
<!-- Secondary Cancel Button -->
|
|
||||||
<Button
|
|
||||||
android:id="@+id/btn_cancel"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:text="BACK TO AMOUNT"
|
|
||||||
style="@style/OutlineButton" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- Auto-Scan Instructions -->
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
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>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
Loading…
x
Reference in New Issue
Block a user