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.text.TextUtils;
 | 
			
		||||
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.Toast;
 | 
			
		||||
 | 
			
		||||
@ -45,17 +47,15 @@ import java.util.regex.Pattern;
 | 
			
		||||
public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
    private static final String TAG = "EmvTransaction";
 | 
			
		||||
    
 | 
			
		||||
    // UI Components
 | 
			
		||||
    // UI Components - SIMPLIFIED
 | 
			
		||||
    private TextView tvStatus;
 | 
			
		||||
    private TextView tvAmountDisplay;
 | 
			
		||||
    private Button btnAction;
 | 
			
		||||
    private Button btnCancel;
 | 
			
		||||
    private ProgressBar progressBar;
 | 
			
		||||
    private ImageView ivCardReader;
 | 
			
		||||
    
 | 
			
		||||
    // Transaction Data
 | 
			
		||||
    private String transactionAmount;
 | 
			
		||||
    private boolean isEMVMode;
 | 
			
		||||
    private boolean isProcessing = false;
 | 
			
		||||
    private boolean isButtonProcessing = false; // ADD THIS MISSING FIELD
 | 
			
		||||
    
 | 
			
		||||
    // EMV Components
 | 
			
		||||
    private EMVOptV2 mEMVOptV2;
 | 
			
		||||
@ -197,8 +197,9 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ====== UPDATED INIT VIEWS METHOD ======
 | 
			
		||||
    private void initViews() {
 | 
			
		||||
        // Setup Toolbar
 | 
			
		||||
        // Setup Toolbar with back navigation
 | 
			
		||||
        Toolbar toolbar = findViewById(R.id.toolbar);
 | 
			
		||||
        setSupportActionBar(toolbar);
 | 
			
		||||
        if (getSupportActionBar() != null) {
 | 
			
		||||
@ -206,13 +207,21 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
            getSupportActionBar().setTitle("Scan Kartu");
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Initialize UI components
 | 
			
		||||
        tvStatus = findViewById(R.id.tv_status);
 | 
			
		||||
        tvAmountDisplay = findViewById(R.id.tv_amount_display);
 | 
			
		||||
        btnAction = findViewById(R.id.btn_action);
 | 
			
		||||
        btnCancel = findViewById(R.id.btn_cancel);
 | 
			
		||||
        progressBar = findViewById(R.id.progress_bar);
 | 
			
		||||
        ivCardReader = findViewById(R.id.iv_card_reader);
 | 
			
		||||
        
 | 
			
		||||
        btnAction.setOnClickListener(v -> handleActionClick());
 | 
			
		||||
        btnCancel.setOnClickListener(v -> finish());
 | 
			
		||||
        // Set initial state
 | 
			
		||||
        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() {
 | 
			
		||||
@ -294,7 +303,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ====== AUTO-SCAN METHODS ======
 | 
			
		||||
    // ====== UPDATED AUTO-START SCANNING METHOD ======
 | 
			
		||||
    private void autoStartScanning() {
 | 
			
		||||
        Log.d(TAG, "Auto-starting card scanning...");
 | 
			
		||||
        
 | 
			
		||||
@ -303,11 +312,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
            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);
 | 
			
		||||
        });
 | 
			
		||||
        updateStatusUI("Ready for card...\n\nPlease insert, swipe, or tap your card\n\nScanning will start automatically", true);
 | 
			
		||||
        
 | 
			
		||||
        // Start scanning automatically
 | 
			
		||||
        startCardCheck();
 | 
			
		||||
@ -324,87 +329,8 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        }, 2000); // 2 second delay before restart
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ====== CARD SCANNING 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();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ====== UPDATED CARD CHECK METHODS ======
 | 
			
		||||
    private void startCardCheck() {
 | 
			
		||||
        // Prevent multiple calls
 | 
			
		||||
        if (isProcessing) {
 | 
			
		||||
            Log.d(TAG, "Card check already in progress - ignoring call");
 | 
			
		||||
            return;
 | 
			
		||||
@ -413,21 +339,15 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        Log.d(TAG, "Starting auto card check - setting isProcessing = true");
 | 
			
		||||
        isProcessing = true;
 | 
			
		||||
        
 | 
			
		||||
        runOnUiThread(() -> {
 | 
			
		||||
            tvStatus.setText("Initializing scanner...\n\nPlease wait...");
 | 
			
		||||
            btnAction.setText("CANCEL");
 | 
			
		||||
            btnAction.setEnabled(true);
 | 
			
		||||
        });
 | 
			
		||||
        updateStatusUI("Initializing scanner...\n\nPlease wait...", true);
 | 
			
		||||
        
 | 
			
		||||
        try {
 | 
			
		||||
            // Force EMV reset before any operation
 | 
			
		||||
            if (mEMVOptV2 != null) {
 | 
			
		||||
                Log.d(TAG, "Forcing EMV reset before card check");
 | 
			
		||||
                mEMVOptV2.initEmvProcess();
 | 
			
		||||
                
 | 
			
		||||
                // Wait a bit before continuing
 | 
			
		||||
                new Handler(Looper.getMainLooper()).postDelayed(() -> {
 | 
			
		||||
                    if (isProcessing && !isFinishing()) { // Double check we're still processing
 | 
			
		||||
                    if (isProcessing && !isFinishing()) {
 | 
			
		||||
                        continueCardCheck();
 | 
			
		||||
                    }
 | 
			
		||||
                }, 500);
 | 
			
		||||
@ -451,12 +371,8 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            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);
 | 
			
		||||
            });
 | 
			
		||||
            updateStatusUI("Scanning for card...\n\nMode: " + mode + "\n\nPlease insert, swipe, or tap your card", true);
 | 
			
		||||
            
 | 
			
		||||
            if (isEMVMode) {
 | 
			
		||||
                startEMVCardCheck();
 | 
			
		||||
@ -470,21 +386,18 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ====== UPDATED HANDLE SCAN ERROR ======
 | 
			
		||||
    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");
 | 
			
		||||
            
 | 
			
		||||
        updateStatusUI("Scan error: " + errorMessage + "\n\nRetrying in 2 seconds...", false);
 | 
			
		||||
        showToast(errorMessage);
 | 
			
		||||
        
 | 
			
		||||
        // Auto-restart scanning after error
 | 
			
		||||
        restartAutoScanning();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void startEMVCardCheck() {
 | 
			
		||||
@ -497,7 +410,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
            mEMVOptV2.initEmvProcess();
 | 
			
		||||
            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();
 | 
			
		||||
            android.util.Log.d(TAG, "Starting EMV checkCard with cardType: " + cardType);
 | 
			
		||||
@ -514,13 +427,13 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
    private void startSimpleCardCheck() {
 | 
			
		||||
        try {
 | 
			
		||||
            if (!MyApplication.app.isConnectPaySDK()) {
 | 
			
		||||
                tvStatus.setText("Connecting to PaySDK...");
 | 
			
		||||
                updateStatusUI("Connecting to PaySDK...", true);
 | 
			
		||||
                MyApplication.app.bindPaySDKService();
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            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);
 | 
			
		||||
            
 | 
			
		||||
@ -536,8 +449,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
                MyApplication.app.readCardOptV2.cancelCheckCard();
 | 
			
		||||
            }
 | 
			
		||||
            isProcessing = false;
 | 
			
		||||
            btnAction.setText("Start Scanning");
 | 
			
		||||
            updateUI();
 | 
			
		||||
            updateStatusUI("Ready for card...\n\nPlease insert, swipe, or tap your card", true);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            android.util.Log.e(TAG, "Error stopping card check: " + e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
@ -688,7 +600,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
                    }
 | 
			
		||||
                    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");
 | 
			
		||||
                    mEMVOptV2.transactProcessEx(bundle, mEMVListener);
 | 
			
		||||
@ -833,16 +745,16 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        mAppSelectDialog.show();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ====== UPDATED EMV DIALOG HANDLERS ======
 | 
			
		||||
    private void showCardNumberConfirmation() {
 | 
			
		||||
        runOnUiThread(() -> {
 | 
			
		||||
            String displayText = "Card Number: " + maskCardNumber(mCardNo) + 
 | 
			
		||||
                               "\n\nConfirming card number automatically...";
 | 
			
		||||
            tvStatus.setText(displayText);
 | 
			
		||||
            String displayText = "Card Number Detected:\n" + maskCardNumber(mCardNo) + 
 | 
			
		||||
                               "\n\nConfirming automatically...";
 | 
			
		||||
            updateStatusUI(displayText, true);
 | 
			
		||||
            
 | 
			
		||||
            // Auto-confirm after short delay to avoid manual interaction
 | 
			
		||||
            btnAction.postDelayed(() -> {
 | 
			
		||||
            // Auto-confirm after short delay
 | 
			
		||||
            new Handler(Looper.getMainLooper()).postDelayed(() -> {
 | 
			
		||||
                Log.d(TAG, "Auto-confirming card number");
 | 
			
		||||
                btnAction.setText("Processing...");
 | 
			
		||||
                importCardNoStatus(0);
 | 
			
		||||
            }, 1500);
 | 
			
		||||
            
 | 
			
		||||
@ -852,14 +764,13 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
    private void showCertificateVerification() {
 | 
			
		||||
        runOnUiThread(() -> {
 | 
			
		||||
            String displayText = "Certificate Information:\n" + mCertInfo + 
 | 
			
		||||
                               "\n\nConfirming certificate automatically...";
 | 
			
		||||
            tvStatus.setText(displayText);
 | 
			
		||||
            String displayText = "Certificate Verification:\n" + mCertInfo + 
 | 
			
		||||
                               "\n\nProcessing automatically...";
 | 
			
		||||
            updateStatusUI(displayText, true);
 | 
			
		||||
            
 | 
			
		||||
            // Auto-confirm after short delay
 | 
			
		||||
            btnAction.postDelayed(() -> {
 | 
			
		||||
            new Handler(Looper.getMainLooper()).postDelayed(() -> {
 | 
			
		||||
                Log.d(TAG, "Auto-confirming certificate");
 | 
			
		||||
                btnAction.setText("Processing...");
 | 
			
		||||
                importCertStatus(0);
 | 
			
		||||
            }, 1500);
 | 
			
		||||
            
 | 
			
		||||
@ -867,7 +778,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ====== PIN PAD METHODS ======
 | 
			
		||||
    // ====== UPDATED PIN PAD METHODS ======
 | 
			
		||||
    private void initPinPad() {
 | 
			
		||||
        android.util.Log.e(TAG, "========== PIN PAD INITIALIZATION ==========");
 | 
			
		||||
        try {
 | 
			
		||||
@ -882,7 +793,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
            PinPadConfigV2 pinPadConfig = new PinPadConfigV2();
 | 
			
		||||
            pinPadConfig.setPinPadType(0);
 | 
			
		||||
            pinPadConfig.setPinType(mPinType);
 | 
			
		||||
            pinPadConfig.setOrderNumKey(false);
 | 
			
		||||
            pinPadConfig.setOrderNumKey(true);
 | 
			
		||||
            
 | 
			
		||||
            String panForPin = mCardNo.substring(mCardNo.length() - 13, mCardNo.length() - 1);
 | 
			
		||||
            byte[] panBytes = panForPin.getBytes("US-ASCII");
 | 
			
		||||
@ -895,11 +806,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
            pinPadConfig.setKeySystem(0);
 | 
			
		||||
            pinPadConfig.setAlgorithmType(0);
 | 
			
		||||
            
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                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);
 | 
			
		||||
            });
 | 
			
		||||
            updateStatusUI("PIN Input Required\n\nPIN pad is ready\nPlease enter your PIN on the device", true);
 | 
			
		||||
            
 | 
			
		||||
            mPinPadOptV2.initPinPad(pinPadConfig, mPinPadListener);
 | 
			
		||||
            
 | 
			
		||||
@ -910,6 +817,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ====== UPDATED PIN PAD LISTENER ======
 | 
			
		||||
    private final PinPadListenerV2 mPinPadListener = new PinPadListenerV2.Stub() {
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onPinLength(int len) throws RemoteException {
 | 
			
		||||
@ -919,7 +827,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
                for (int i = 0; i < len; i++) {
 | 
			
		||||
                    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");
 | 
			
		||||
            
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                btnAction.setEnabled(true);
 | 
			
		||||
                btnAction.setText("Processing...");
 | 
			
		||||
                tvStatus.setText("PIN confirmed, processing...");
 | 
			
		||||
                updateStatusUI("PIN confirmed, processing...", true);
 | 
			
		||||
            });
 | 
			
		||||
            
 | 
			
		||||
            if (pinBlock != null) {
 | 
			
		||||
@ -948,9 +854,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
            android.util.Log.d(TAG, "PIN input cancelled by user");
 | 
			
		||||
            
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                btnAction.setEnabled(true);
 | 
			
		||||
                btnAction.setText("Start Scanning");
 | 
			
		||||
                tvStatus.setText("PIN input cancelled");
 | 
			
		||||
                updateStatusUI("PIN input cancelled", false);
 | 
			
		||||
            });
 | 
			
		||||
            
 | 
			
		||||
            mHandler.obtainMessage(PIN_CLICK_CANCEL).sendToTarget();
 | 
			
		||||
@ -962,9 +866,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
            String msg = AidlErrorCodeV2.valueOf(code).getMsg();
 | 
			
		||||
            
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                btnAction.setEnabled(true);
 | 
			
		||||
                btnAction.setText("Start Scanning");
 | 
			
		||||
                tvStatus.setText("PIN error: " + msg);
 | 
			
		||||
                updateStatusUI("PIN error: " + msg, false);
 | 
			
		||||
            });
 | 
			
		||||
            
 | 
			
		||||
            mHandler.obtainMessage(PIN_ERROR, code, code, msg).sendToTarget();
 | 
			
		||||
@ -1001,7 +903,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
                    isProcessing = false;
 | 
			
		||||
                    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");
 | 
			
		||||
                    
 | 
			
		||||
                    // Auto-restart scanning
 | 
			
		||||
@ -1017,17 +919,13 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        }).start();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ====== UPDATED RESET SCANNING STATE ======
 | 
			
		||||
    private void resetScanningState() {
 | 
			
		||||
        Log.d(TAG, "Resetting scanning state for auto-scan mode");
 | 
			
		||||
        isProcessing = false;
 | 
			
		||||
        isButtonProcessing = false;
 | 
			
		||||
        mProcessStep = 0;
 | 
			
		||||
        
 | 
			
		||||
        runOnUiThread(() -> {
 | 
			
		||||
            btnAction.setText("CANCEL");
 | 
			
		||||
            btnAction.setEnabled(true);
 | 
			
		||||
            updateUI();
 | 
			
		||||
        });
 | 
			
		||||
        updateStatusUI("Ready for card...\n\nPlease insert, swipe, or tap your card", true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ====== HELPER METHODS ======
 | 
			
		||||
@ -1041,10 +939,11 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        finish();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ====== UPDATED MOCK ONLINE PROCESS ======
 | 
			
		||||
    private void mockOnlineProcess() {
 | 
			
		||||
        new Thread(() -> {
 | 
			
		||||
            try {
 | 
			
		||||
                runOnUiThread(() -> tvStatus.setText("Processing online authorization..."));
 | 
			
		||||
                runOnUiThread(() -> updateStatusUI("Processing online authorization...", true));
 | 
			
		||||
                Thread.sleep(2000);
 | 
			
		||||
                
 | 
			
		||||
                try {
 | 
			
		||||
@ -1149,9 +1048,29 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ====== UPDATED ON SUPPORT NAVIGATE UP ======
 | 
			
		||||
    @Override
 | 
			
		||||
    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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -17,101 +17,67 @@
 | 
			
		||||
        android:theme="@style/CustomToolbarTheme"
 | 
			
		||||
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
 | 
			
		||||
 | 
			
		||||
    <!-- Content Container -->
 | 
			
		||||
    <!-- Main Content Container with Center Alignment -->
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="match_parent"
 | 
			
		||||
        android:orientation="vertical"
 | 
			
		||||
        android:padding="16dp">
 | 
			
		||||
 | 
			
		||||
        <!-- Amount Display Card -->
 | 
			
		||||
        <androidx.cardview.widget.CardView
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_marginBottom="24dp"
 | 
			
		||||
            app:cardCornerRadius="12dp"
 | 
			
		||||
            app:cardElevation="4dp"
 | 
			
		||||
            app:cardBackgroundColor="@color/primary_blue">
 | 
			
		||||
 | 
			
		||||
            <LinearLayout
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:orientation="vertical"
 | 
			
		||||
                android:padding="20dp">
 | 
			
		||||
 | 
			
		||||
                <ImageView
 | 
			
		||||
                    android:layout_width="48dp"
 | 
			
		||||
                    android:layout_height="48dp"
 | 
			
		||||
                    android:layout_gravity="center"
 | 
			
		||||
                    android:layout_marginBottom="12dp"
 | 
			
		||||
                    android:src="@drawable/ic_credit_card"
 | 
			
		||||
                    app:tint="@android:color/white" />
 | 
			
		||||
 | 
			
		||||
                <TextView
 | 
			
		||||
                    android:id="@+id/tv_amount_display"
 | 
			
		||||
                    android:layout_width="match_parent"
 | 
			
		||||
                    android:layout_height="wrap_content"
 | 
			
		||||
                    android:text="Nominal: Rp 0,00"
 | 
			
		||||
                    android:textSize="20sp"
 | 
			
		||||
                    android:textStyle="bold"
 | 
			
		||||
                    android:textColor="@color/white"
 | 
			
		||||
                    android:fontFamily="@font/inter"
 | 
			
		||||
                    android:gravity="center" />
 | 
			
		||||
 | 
			
		||||
            </LinearLayout>
 | 
			
		||||
        </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" />
 | 
			
		||||
        android:padding="24dp">
 | 
			
		||||
 | 
			
		||||
        <!-- Status Modal Card - Centered and Compact -->
 | 
			
		||||
        <androidx.cardview.widget.CardView
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_gravity="center"
 | 
			
		||||
            app:cardCornerRadius="16dp"
 | 
			
		||||
            app:cardElevation="8dp"
 | 
			
		||||
            app:cardBackgroundColor="@android:color/white">
 | 
			
		||||
 | 
			
		||||
            <LinearLayout
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:orientation="vertical"
 | 
			
		||||
                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
 | 
			
		||||
                    android:id="@+id/iv_card_reader"
 | 
			
		||||
                        android:layout_width="80dp"
 | 
			
		||||
                        android:layout_height="80dp"
 | 
			
		||||
                    android:layout_width="120dp"
 | 
			
		||||
                    android:layout_height="120dp"
 | 
			
		||||
                    android:layout_gravity="center"
 | 
			
		||||
                        android:layout_marginBottom="16dp"
 | 
			
		||||
                    android:layout_marginBottom="24dp"
 | 
			
		||||
                    android:src="@drawable/ic_card_insert"
 | 
			
		||||
                    android:scaleType="centerInside"
 | 
			
		||||
                        app:tint="#666666" />
 | 
			
		||||
                    app:tint="@color/primary_blue" />
 | 
			
		||||
 | 
			
		||||
                    <!-- Auto-Scan Status Text -->
 | 
			
		||||
                <!-- 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" />
 | 
			
		||||
                    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 (Initially Visible for Auto-Scan) -->
 | 
			
		||||
                <!-- Progress Indicator -->
 | 
			
		||||
                <ProgressBar
 | 
			
		||||
                    android:id="@+id/progress_bar"
 | 
			
		||||
                    style="?android:attr/progressBarStyle"
 | 
			
		||||
@ -119,44 +85,22 @@
 | 
			
		||||
                    android:layout_height="48dp"
 | 
			
		||||
                    android:layout_gravity="center"
 | 
			
		||||
                    android:visibility="visible"
 | 
			
		||||
                        android:indeterminateTint="@color/primary_blue" />
 | 
			
		||||
                    android:indeterminateTint="@color/primary_blue"
 | 
			
		||||
                    android:layout_marginBottom="16dp" />
 | 
			
		||||
 | 
			
		||||
                </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 -->
 | 
			
		||||
                <!-- Instructions Text -->
 | 
			
		||||
                <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" />
 | 
			
		||||
                    android:text="Please insert, tap, or swipe your card\nScanning will start automatically"
 | 
			
		||||
                    android:textSize="14sp"
 | 
			
		||||
                    android:textColor="#8A9BAE"
 | 
			
		||||
                    android:gravity="center"
 | 
			
		||||
                    android:lineSpacingExtra="2dp"
 | 
			
		||||
                    android:fontFamily="@font/inter" />
 | 
			
		||||
 | 
			
		||||
            </LinearLayout>
 | 
			
		||||
        </androidx.cardview.widget.CardView>
 | 
			
		||||
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user