menambahkan mdal pada screen emv
This commit is contained in:
		
							parent
							
								
									f403358554
								
							
						
					
					
						commit
						0af0e836b1
					
				@ -9,7 +9,11 @@ import android.os.RemoteException;
 | 
			
		||||
import android.text.TextUtils;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.animation.Animation;
 | 
			
		||||
import android.view.animation.AnimationUtils;
 | 
			
		||||
import android.widget.FrameLayout;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.LinearLayout;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
@ -42,20 +46,29 @@ import java.util.regex.Matcher;
 | 
			
		||||
import java.util.regex.Pattern;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EmvTransactionActivity - Handle card reading and EMV processing
 | 
			
		||||
 * EmvTransactionActivity - Handle card reading and EMV processing with Modal
 | 
			
		||||
 */
 | 
			
		||||
public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
    private static final String TAG = "EmvTransaction";
 | 
			
		||||
    
 | 
			
		||||
    // UI Components - SIMPLIFIED
 | 
			
		||||
    // UI Components - SIMPLIFIED + MODAL
 | 
			
		||||
    private LinearLayout mainContent;
 | 
			
		||||
    private FrameLayout modalOverlay;
 | 
			
		||||
    private TextView tvStatus;
 | 
			
		||||
    private TextView modalText;
 | 
			
		||||
    private ImageView modalIcon;
 | 
			
		||||
    private ProgressBar progressBar;
 | 
			
		||||
    private ImageView ivCardReader;
 | 
			
		||||
    
 | 
			
		||||
    // Animation
 | 
			
		||||
    private Animation fadeIn;
 | 
			
		||||
    private Animation fadeOut;
 | 
			
		||||
    
 | 
			
		||||
    // Transaction Data
 | 
			
		||||
    private String transactionAmount;
 | 
			
		||||
    private boolean isEMVMode;
 | 
			
		||||
    private boolean isProcessing = false;
 | 
			
		||||
    private boolean isModalShowing = false;
 | 
			
		||||
    
 | 
			
		||||
    // EMV Components
 | 
			
		||||
    private EMVOptV2 mEMVOptV2;
 | 
			
		||||
@ -86,6 +99,11 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
    private static final int PIN_CLICK_CANCEL = 53;
 | 
			
		||||
    private static final int PIN_ERROR = 54;
 | 
			
		||||
    
 | 
			
		||||
    // Modal Display Messages
 | 
			
		||||
    private static final int SHOW_MODAL_SCAN_CARD = 101;
 | 
			
		||||
    private static final int SHOW_MODAL_PROCESSING = 102;
 | 
			
		||||
    private static final int HIDE_MODAL = 103;
 | 
			
		||||
 | 
			
		||||
    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
 | 
			
		||||
        @Override
 | 
			
		||||
        public void handleMessage(Message msg) {
 | 
			
		||||
@ -110,10 +128,12 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
                    
 | 
			
		||||
                case EMV_SHOW_PIN_PAD:
 | 
			
		||||
                    android.util.Log.d(TAG, "Initializing PIN pad...");
 | 
			
		||||
                    hideModal();
 | 
			
		||||
                    initPinPad();
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
                case EMV_ONLINE_PROCESS:
 | 
			
		||||
                    showModalProcessing("Memproses Otorisasi Online...");
 | 
			
		||||
                    mockOnlineProcess();
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
@ -149,6 +169,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
                    
 | 
			
		||||
                    Log.e(TAG, "EMV Transaction failed: " + errorDesc + " (Code: " + errorCode + ")");
 | 
			
		||||
                    
 | 
			
		||||
                    hideModal();
 | 
			
		||||
                    if (errorCode == -50009) {
 | 
			
		||||
                        // EMV process conflict - reset and retry
 | 
			
		||||
                        Log.d(TAG, "EMV process conflict detected - resetting...");
 | 
			
		||||
@ -163,8 +184,22 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
                    
 | 
			
		||||
                case EMV_TRANS_SUCCESS:
 | 
			
		||||
                    // Navigate to results screen
 | 
			
		||||
                    hideModal();
 | 
			
		||||
                    navigateToResults();
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
                case SHOW_MODAL_SCAN_CARD:
 | 
			
		||||
                    showModalScanCard();
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
                case SHOW_MODAL_PROCESSING:
 | 
			
		||||
                    String processingMsg = (String) msg.obj;
 | 
			
		||||
                    showModalProcessing(processingMsg);
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
                case HIDE_MODAL:
 | 
			
		||||
                    hideModal();
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
@ -176,6 +211,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        
 | 
			
		||||
        getIntentData();
 | 
			
		||||
        initViews();
 | 
			
		||||
        initAnimations();
 | 
			
		||||
        initEMVComponents();
 | 
			
		||||
        initEMVData();
 | 
			
		||||
        
 | 
			
		||||
@ -208,12 +244,96 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Initialize UI components
 | 
			
		||||
        mainContent = findViewById(R.id.main_content);
 | 
			
		||||
        modalOverlay = findViewById(R.id.modal_overlay);
 | 
			
		||||
        tvStatus = findViewById(R.id.tv_status);
 | 
			
		||||
        progressBar = findViewById(R.id.progress_bar);
 | 
			
		||||
        ivCardReader = findViewById(R.id.iv_card_reader);
 | 
			
		||||
        modalText = findViewById(R.id.modal_text);
 | 
			
		||||
        modalIcon = findViewById(R.id.modal_icon);
 | 
			
		||||
        
 | 
			
		||||
        // Set initial state
 | 
			
		||||
        updateStatusUI("Initializing scanner...", true);
 | 
			
		||||
        
 | 
			
		||||
        // Setup modal overlay click to close
 | 
			
		||||
        modalOverlay.setOnClickListener(v -> {
 | 
			
		||||
            // Optional: close modal when clicking outside
 | 
			
		||||
            // hideModal();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ====== ANIMATION INITIALIZATION ======
 | 
			
		||||
    private void initAnimations() {
 | 
			
		||||
        // Create fade animations programmatically since we want to avoid new resources
 | 
			
		||||
        fadeIn = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
 | 
			
		||||
        fadeOut = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
 | 
			
		||||
        
 | 
			
		||||
        // Set animation duration
 | 
			
		||||
        fadeIn.setDuration(300);
 | 
			
		||||
        fadeOut.setDuration(300);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ====== MODAL METHODS ======
 | 
			
		||||
    private void showModalScanCard() {
 | 
			
		||||
        if (isModalShowing) return;
 | 
			
		||||
        
 | 
			
		||||
        runOnUiThread(() -> {
 | 
			
		||||
            modalText.setText("Silakan Tempelkan / Gesekkan / Masukkan Kartu ke Perangkat");
 | 
			
		||||
            modalIcon.setImageResource(R.drawable.ic_card_insert);
 | 
			
		||||
            
 | 
			
		||||
            modalOverlay.setVisibility(View.VISIBLE);
 | 
			
		||||
            modalOverlay.startAnimation(fadeIn);
 | 
			
		||||
            
 | 
			
		||||
            isModalShowing = true;
 | 
			
		||||
            
 | 
			
		||||
            Log.d(TAG, "Modal scan card shown");
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void showModalProcessing(String message) {
 | 
			
		||||
        if (!isModalShowing) {
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                modalText.setText(message);
 | 
			
		||||
                modalIcon.setImageResource(R.drawable.ic_card_insert);
 | 
			
		||||
                
 | 
			
		||||
                modalOverlay.setVisibility(View.VISIBLE);
 | 
			
		||||
                modalOverlay.startAnimation(fadeIn);
 | 
			
		||||
                
 | 
			
		||||
                isModalShowing = true;
 | 
			
		||||
                
 | 
			
		||||
                Log.d(TAG, "Modal processing shown: " + message);
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            // Just update text if modal already showing
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                modalText.setText(message);
 | 
			
		||||
                Log.d(TAG, "Modal text updated: " + message);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void hideModal() {
 | 
			
		||||
        if (!isModalShowing) return;
 | 
			
		||||
        
 | 
			
		||||
        runOnUiThread(() -> {
 | 
			
		||||
            fadeOut.setAnimationListener(new Animation.AnimationListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onAnimationStart(Animation animation) {}
 | 
			
		||||
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onAnimationEnd(Animation animation) {
 | 
			
		||||
                    modalOverlay.setVisibility(View.GONE);
 | 
			
		||||
                    isModalShowing = false;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onAnimationRepeat(Animation animation) {}
 | 
			
		||||
            });
 | 
			
		||||
            
 | 
			
		||||
            modalOverlay.startAnimation(fadeOut);
 | 
			
		||||
            
 | 
			
		||||
            Log.d(TAG, "Modal hidden");
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ====== NEW METHOD TO UPDATE STATUS UI ======
 | 
			
		||||
@ -314,6 +434,9 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        
 | 
			
		||||
        updateStatusUI("Ready for card...\n\nPlease insert, swipe, or tap your card\n\nScanning will start automatically", true);
 | 
			
		||||
        
 | 
			
		||||
        // Show modal for card scanning
 | 
			
		||||
        mHandler.obtainMessage(SHOW_MODAL_SCAN_CARD).sendToTarget();
 | 
			
		||||
        
 | 
			
		||||
        // Start scanning automatically
 | 
			
		||||
        startCardCheck();
 | 
			
		||||
    }
 | 
			
		||||
@ -396,6 +519,9 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        updateStatusUI("Scan error: " + errorMessage + "\n\nRetrying in 2 seconds...", false);
 | 
			
		||||
        showToast(errorMessage);
 | 
			
		||||
        
 | 
			
		||||
        // Hide modal on error
 | 
			
		||||
        hideModal();
 | 
			
		||||
        
 | 
			
		||||
        // Auto-restart scanning after error
 | 
			
		||||
        restartAutoScanning();
 | 
			
		||||
    }
 | 
			
		||||
@ -460,39 +586,65 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        @Override
 | 
			
		||||
        public void findMagCard(Bundle info) throws RemoteException {
 | 
			
		||||
            android.util.Log.d(TAG, "Simple Mode: findMagCard callback triggered");
 | 
			
		||||
            runOnUiThread(() -> handleSimpleCardResult(info, "MAGNETIC"));
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                showModalProcessing("Kartu Ditemukan - Memproses...");
 | 
			
		||||
                new Handler(Looper.getMainLooper()).postDelayed(() -> {
 | 
			
		||||
                    handleSimpleCardResult(info, "MAGNETIC");
 | 
			
		||||
                }, 1500);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void findICCard(String atr) throws RemoteException {
 | 
			
		||||
            Bundle info = new Bundle();
 | 
			
		||||
            info.putString("atr", atr);
 | 
			
		||||
            runOnUiThread(() -> handleSimpleCardResult(info, "IC"));
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                showModalProcessing("Kartu IC Ditemukan - Memproses...");
 | 
			
		||||
                new Handler(Looper.getMainLooper()).postDelayed(() -> {
 | 
			
		||||
                    handleSimpleCardResult(info, "IC");
 | 
			
		||||
                }, 1500);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void findRFCard(String uuid) throws RemoteException {
 | 
			
		||||
            Bundle info = new Bundle();
 | 
			
		||||
            info.putString("uuid", uuid);
 | 
			
		||||
            runOnUiThread(() -> handleSimpleCardResult(info, "NFC"));
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                showModalProcessing("Kartu NFC Ditemukan - Memproses...");
 | 
			
		||||
                new Handler(Looper.getMainLooper()).postDelayed(() -> {
 | 
			
		||||
                    handleSimpleCardResult(info, "NFC");
 | 
			
		||||
                }, 1500);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onError(int code, String message) throws RemoteException {
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                showToast("Card error: " + message);
 | 
			
		||||
                hideModal();
 | 
			
		||||
                stopCardCheck();
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void findICCardEx(Bundle info) throws RemoteException {
 | 
			
		||||
            runOnUiThread(() -> handleSimpleCardResult(info, "IC"));
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                showModalProcessing("Kartu IC Ditemukan - Memproses...");
 | 
			
		||||
                new Handler(Looper.getMainLooper()).postDelayed(() -> {
 | 
			
		||||
                    handleSimpleCardResult(info, "IC");
 | 
			
		||||
                }, 1500);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void findRFCardEx(Bundle info) throws RemoteException {
 | 
			
		||||
            runOnUiThread(() -> handleSimpleCardResult(info, "NFC"));
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                showModalProcessing("Kartu NFC Ditemukan - Memproses...");
 | 
			
		||||
                new Handler(Looper.getMainLooper()).postDelayed(() -> {
 | 
			
		||||
                    handleSimpleCardResult(info, "NFC");
 | 
			
		||||
                }, 1500);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
@ -500,6 +652,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                String msg = info.getString("message", "Unknown error");
 | 
			
		||||
                showToast("Card error: " + msg);
 | 
			
		||||
                hideModal();
 | 
			
		||||
                stopCardCheck();
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
@ -509,26 +662,38 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
    private final CheckCardCallbackV2 mEMVCheckCardCallback = new CheckCardCallbackV2.Stub() {
 | 
			
		||||
        @Override
 | 
			
		||||
        public void findMagCard(Bundle info) throws RemoteException {
 | 
			
		||||
            runOnUiThread(() -> handleSimpleCardResult(info, "MAGNETIC"));
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                showModalProcessing("Kartu Magnetik Ditemukan - Memproses...");
 | 
			
		||||
                new Handler(Looper.getMainLooper()).postDelayed(() -> {
 | 
			
		||||
                    handleSimpleCardResult(info, "MAGNETIC");
 | 
			
		||||
                }, 1500);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void findICCard(String atr) throws RemoteException {
 | 
			
		||||
            MyApplication.app.basicOptV2.buzzerOnDevice(1, 2750, 200, 0);
 | 
			
		||||
            mCardType = AidlConstantsV2.CardType.IC.getValue();
 | 
			
		||||
            runOnUiThread(() -> startEMVTransactionProcess());
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                showModalProcessing("Kartu IC Ditemukan - Memulai EMV...");
 | 
			
		||||
                startEMVTransactionProcess();
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void findRFCard(String uuid) throws RemoteException {
 | 
			
		||||
            mCardType = AidlConstantsV2.CardType.NFC.getValue();
 | 
			
		||||
            runOnUiThread(() -> startEMVTransactionProcess());
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                showModalProcessing("Kartu NFC Ditemukan - Memulai EMV...");
 | 
			
		||||
                startEMVTransactionProcess();
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onError(int code, String message) throws RemoteException {
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                showToast("EMV Error: " + message);
 | 
			
		||||
                hideModal();
 | 
			
		||||
                stopCardCheck();
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
@ -536,13 +701,19 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        @Override
 | 
			
		||||
        public void findICCardEx(Bundle info) throws RemoteException {
 | 
			
		||||
            mCardType = AidlConstantsV2.CardType.IC.getValue();
 | 
			
		||||
            runOnUiThread(() -> startEMVTransactionProcess());
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                showModalProcessing("Kartu IC Ditemukan - Memulai EMV...");
 | 
			
		||||
                startEMVTransactionProcess();
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void findRFCardEx(Bundle info) throws RemoteException {
 | 
			
		||||
            mCardType = AidlConstantsV2.CardType.NFC.getValue();
 | 
			
		||||
            runOnUiThread(() -> startEMVTransactionProcess());
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                showModalProcessing("Kartu NFC Ditemukan - Memulai EMV...");
 | 
			
		||||
                startEMVTransactionProcess();
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
@ -550,6 +721,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                String msg = info.getString("message", "Unknown error");
 | 
			
		||||
                showToast("EMV Error: " + msg);
 | 
			
		||||
                hideModal();
 | 
			
		||||
                stopCardCheck();
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
@ -601,12 +773,14 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
                    bundle.putInt("cardType", mCardType);
 | 
			
		||||
                    
 | 
			
		||||
                    updateStatusUI("EMV processing started...\nReading card data...", true);
 | 
			
		||||
                    showModalProcessing("Memproses Data Kartu EMV...");
 | 
			
		||||
                    
 | 
			
		||||
                    Log.d(TAG, "Starting transactProcessEx with reset EMV");
 | 
			
		||||
                    mEMVOptV2.transactProcessEx(bundle, mEMVListener);
 | 
			
		||||
                    
 | 
			
		||||
                } catch (Exception e) {
 | 
			
		||||
                    Log.e(TAG, "Error in delayed EMV start: " + e.getMessage(), e);
 | 
			
		||||
                    hideModal();
 | 
			
		||||
                    resetScanningState();
 | 
			
		||||
                    showToast("Error starting EMV: " + e.getMessage());
 | 
			
		||||
                }
 | 
			
		||||
@ -615,6 +789,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            android.util.Log.e(TAG, "Error starting EMV transaction: " + e.getMessage());
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            hideModal();
 | 
			
		||||
            resetScanningState();
 | 
			
		||||
            showToast("Error starting EMV transaction: " + e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
@ -628,6 +803,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
            android.util.Log.d(TAG, "onWaitAppSelect isFirstSelect:" + isFirstSelect);
 | 
			
		||||
            mProcessStep = EMV_APP_SELECT;
 | 
			
		||||
            String[] candidateNames = getCandidateNames(appNameList);
 | 
			
		||||
            runOnUiThread(() -> hideModal());
 | 
			
		||||
            mHandler.obtainMessage(EMV_APP_SELECT, candidateNames).sendToTarget();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -751,6 +927,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
            String displayText = "Card Number Detected:\n" + maskCardNumber(mCardNo) + 
 | 
			
		||||
                               "\n\nConfirming automatically...";
 | 
			
		||||
            updateStatusUI(displayText, true);
 | 
			
		||||
            showModalProcessing("Mengkonfirmasi Nomor Kartu...");
 | 
			
		||||
            
 | 
			
		||||
            // Auto-confirm after short delay
 | 
			
		||||
            new Handler(Looper.getMainLooper()).postDelayed(() -> {
 | 
			
		||||
@ -767,6 +944,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
            String displayText = "Certificate Verification:\n" + mCertInfo + 
 | 
			
		||||
                               "\n\nProcessing automatically...";
 | 
			
		||||
            updateStatusUI(displayText, true);
 | 
			
		||||
            showModalProcessing("Memverifikasi Sertifikat...");
 | 
			
		||||
            
 | 
			
		||||
            // Auto-confirm after short delay
 | 
			
		||||
            new Handler(Looper.getMainLooper()).postDelayed(() -> {
 | 
			
		||||
@ -793,7 +971,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
            PinPadConfigV2 pinPadConfig = new PinPadConfigV2();
 | 
			
		||||
            pinPadConfig.setPinPadType(0);
 | 
			
		||||
            pinPadConfig.setPinType(mPinType);
 | 
			
		||||
            pinPadConfig.setOrderNumKey(true);
 | 
			
		||||
            pinPadConfig.setOrderNumKey(true);  // Set to true for normal order, false for random
 | 
			
		||||
            
 | 
			
		||||
            String panForPin = mCardNo.substring(mCardNo.length() - 13, mCardNo.length() - 1);
 | 
			
		||||
            byte[] panBytes = panForPin.getBytes("US-ASCII");
 | 
			
		||||
@ -837,6 +1015,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
            
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                updateStatusUI("PIN confirmed, processing...", true);
 | 
			
		||||
                showModalProcessing("PIN Dikonfirmasi - Memproses...");
 | 
			
		||||
            });
 | 
			
		||||
            
 | 
			
		||||
            if (pinBlock != null) {
 | 
			
		||||
@ -855,6 +1034,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
            
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                updateStatusUI("PIN input cancelled", false);
 | 
			
		||||
                hideModal();
 | 
			
		||||
            });
 | 
			
		||||
            
 | 
			
		||||
            mHandler.obtainMessage(PIN_CLICK_CANCEL).sendToTarget();
 | 
			
		||||
@ -867,6 +1047,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
            
 | 
			
		||||
            runOnUiThread(() -> {
 | 
			
		||||
                updateStatusUI("PIN error: " + msg, false);
 | 
			
		||||
                hideModal();
 | 
			
		||||
            });
 | 
			
		||||
            
 | 
			
		||||
            mHandler.obtainMessage(PIN_ERROR, code, code, msg).sendToTarget();
 | 
			
		||||
@ -926,6 +1107,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
        mProcessStep = 0;
 | 
			
		||||
        
 | 
			
		||||
        updateStatusUI("Ready for card...\n\nPlease insert, swipe, or tap your card", true);
 | 
			
		||||
        hideModal();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ====== HELPER METHODS ======
 | 
			
		||||
@ -1066,6 +1248,8 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
            isProcessing = false;
 | 
			
		||||
            mProcessStep = 0;
 | 
			
		||||
            
 | 
			
		||||
            hideModal();
 | 
			
		||||
            
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            Log.e(TAG, "Error cleaning up on back press: " + e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
@ -1092,6 +1276,8 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
			
		||||
                mEMVOptV2.initEmvProcess();
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            hideModal();
 | 
			
		||||
            
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            Log.e(TAG, "Error cleaning up EMV: " + e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								app/src/main/res/anim/slide_down.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/src/main/res/anim/slide_down.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
 | 
			
		||||
    <translate
 | 
			
		||||
        android:duration="300"
 | 
			
		||||
        android:fromYDelta="0%p"
 | 
			
		||||
        android:toYDelta="50%p" />
 | 
			
		||||
    <alpha
 | 
			
		||||
        android:duration="300"
 | 
			
		||||
        android:fromAlpha="1.0"
 | 
			
		||||
        android:toAlpha="0.0" />
 | 
			
		||||
</set>
 | 
			
		||||
							
								
								
									
										10
									
								
								app/src/main/res/anim/slide_up.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/src/main/res/anim/slide_up.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
 | 
			
		||||
    <translate
 | 
			
		||||
        android:duration="300"
 | 
			
		||||
        android:fromYDelta="50%p"
 | 
			
		||||
        android:toYDelta="0%p" />
 | 
			
		||||
    <alpha
 | 
			
		||||
        android:duration="300"
 | 
			
		||||
        android:fromAlpha="0.0"
 | 
			
		||||
        android:toAlpha="1.0" />
 | 
			
		||||
</set>
 | 
			
		||||
@ -1,13 +1,19 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    android:orientation="vertical"
 | 
			
		||||
    android:background="@color/colorBackground"
 | 
			
		||||
    tools:context=".kredit.EmvTransactionActivity">
 | 
			
		||||
 | 
			
		||||
    <!-- Main Content -->
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:id="@+id/main_content"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="match_parent"
 | 
			
		||||
        android:orientation="vertical">
 | 
			
		||||
 | 
			
		||||
        <!-- Toolbar -->
 | 
			
		||||
        <androidx.appcompat.widget.Toolbar
 | 
			
		||||
            android:id="@+id/toolbar"
 | 
			
		||||
@ -46,11 +52,7 @@
 | 
			
		||||
                        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"
 | 
			
		||||
                        style="@style/HeaderTextStyle"
 | 
			
		||||
                        android:layout_marginBottom="24dp" />
 | 
			
		||||
 | 
			
		||||
                    <!-- Card Reader Animation/Icon -->
 | 
			
		||||
@ -70,11 +72,7 @@
 | 
			
		||||
                        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"
 | 
			
		||||
                        style="@style/StatusTextStyle"
 | 
			
		||||
                        android:layout_marginBottom="24dp" />
 | 
			
		||||
 | 
			
		||||
                    <!-- Progress Indicator -->
 | 
			
		||||
@ -93,11 +91,8 @@
 | 
			
		||||
                        android:layout_width="match_parent"
 | 
			
		||||
                        android:layout_height="wrap_content"
 | 
			
		||||
                        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" />
 | 
			
		||||
                        style="@style/HintTextStyle"
 | 
			
		||||
                        android:gravity="center" />
 | 
			
		||||
 | 
			
		||||
                </LinearLayout>
 | 
			
		||||
            </androidx.cardview.widget.CardView>
 | 
			
		||||
@ -105,3 +100,61 @@
 | 
			
		||||
        </LinearLayout>
 | 
			
		||||
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
 | 
			
		||||
    <!-- Modal Overlay with Blur Effect -->
 | 
			
		||||
    <FrameLayout
 | 
			
		||||
        android:id="@+id/modal_overlay"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="match_parent"
 | 
			
		||||
        android:background="#80000000"
 | 
			
		||||
        android:visibility="gone"
 | 
			
		||||
        android:clickable="true"
 | 
			
		||||
        android:focusable="true">
 | 
			
		||||
 | 
			
		||||
        <!-- Modal Content -->
 | 
			
		||||
        <androidx.cardview.widget.CardView
 | 
			
		||||
            android:id="@+id/modal_card"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_gravity="center"
 | 
			
		||||
            android:layout_margin="32dp"
 | 
			
		||||
            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">
 | 
			
		||||
 | 
			
		||||
                <!-- Card Icon -->
 | 
			
		||||
                <ImageView
 | 
			
		||||
                    android:id="@+id/modal_icon"
 | 
			
		||||
                    android:layout_width="80dp"
 | 
			
		||||
                    android:layout_height="80dp"
 | 
			
		||||
                    android:src="@drawable/ic_card_insert"
 | 
			
		||||
                    android:layout_marginBottom="24dp"
 | 
			
		||||
                    android:scaleType="fitCenter"
 | 
			
		||||
                    android:adjustViewBounds="true"
 | 
			
		||||
                    app:tint="@color/primary_blue" />
 | 
			
		||||
 | 
			
		||||
                <!-- Main Text -->
 | 
			
		||||
                <TextView
 | 
			
		||||
                    android:id="@+id/modal_text"
 | 
			
		||||
                    android:layout_width="wrap_content"
 | 
			
		||||
                    android:layout_height="wrap_content"
 | 
			
		||||
                    android:text="Silakan Tempelkan / Gesekkan / Masukkan Kartu ke Perangkat"
 | 
			
		||||
                    style="@style/StatusTextStyle"
 | 
			
		||||
                    android:textAlignment="center"
 | 
			
		||||
                    android:gravity="center"
 | 
			
		||||
                    android:lineSpacingExtra="4dp" />
 | 
			
		||||
 | 
			
		||||
            </LinearLayout>
 | 
			
		||||
 | 
			
		||||
        </androidx.cardview.widget.CardView>
 | 
			
		||||
 | 
			
		||||
    </FrameLayout>
 | 
			
		||||
 | 
			
		||||
</FrameLayout>
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user