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.text.TextUtils;
 | 
				
			||||||
import android.util.Log;
 | 
					import android.util.Log;
 | 
				
			||||||
import android.view.View;
 | 
					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.ImageView;
 | 
				
			||||||
 | 
					import android.widget.LinearLayout;
 | 
				
			||||||
import android.widget.ProgressBar;
 | 
					import android.widget.ProgressBar;
 | 
				
			||||||
import android.widget.TextView;
 | 
					import android.widget.TextView;
 | 
				
			||||||
import android.widget.Toast;
 | 
					import android.widget.Toast;
 | 
				
			||||||
@ -42,20 +46,29 @@ import java.util.regex.Matcher;
 | 
				
			|||||||
import java.util.regex.Pattern;
 | 
					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 {
 | 
					public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			||||||
    private static final String TAG = "EmvTransaction";
 | 
					    private static final String TAG = "EmvTransaction";
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // UI Components - SIMPLIFIED
 | 
					    // UI Components - SIMPLIFIED + MODAL
 | 
				
			||||||
 | 
					    private LinearLayout mainContent;
 | 
				
			||||||
 | 
					    private FrameLayout modalOverlay;
 | 
				
			||||||
    private TextView tvStatus;
 | 
					    private TextView tvStatus;
 | 
				
			||||||
 | 
					    private TextView modalText;
 | 
				
			||||||
 | 
					    private ImageView modalIcon;
 | 
				
			||||||
    private ProgressBar progressBar;
 | 
					    private ProgressBar progressBar;
 | 
				
			||||||
    private ImageView ivCardReader;
 | 
					    private ImageView ivCardReader;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    // Animation
 | 
				
			||||||
 | 
					    private Animation fadeIn;
 | 
				
			||||||
 | 
					    private Animation fadeOut;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    // 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 isModalShowing = false;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // EMV Components
 | 
					    // EMV Components
 | 
				
			||||||
    private EMVOptV2 mEMVOptV2;
 | 
					    private EMVOptV2 mEMVOptV2;
 | 
				
			||||||
@ -85,6 +98,11 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
    private static final int PIN_CLICK_CONFIRM = 52;
 | 
					    private static final int PIN_CLICK_CONFIRM = 52;
 | 
				
			||||||
    private static final int PIN_CLICK_CANCEL = 53;
 | 
					    private static final int PIN_CLICK_CANCEL = 53;
 | 
				
			||||||
    private static final int PIN_ERROR = 54;
 | 
					    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()) {
 | 
					    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
@ -110,10 +128,12 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
                    
 | 
					                    
 | 
				
			||||||
                case EMV_SHOW_PIN_PAD:
 | 
					                case EMV_SHOW_PIN_PAD:
 | 
				
			||||||
                    android.util.Log.d(TAG, "Initializing PIN pad...");
 | 
					                    android.util.Log.d(TAG, "Initializing PIN pad...");
 | 
				
			||||||
 | 
					                    hideModal();
 | 
				
			||||||
                    initPinPad();
 | 
					                    initPinPad();
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                case EMV_ONLINE_PROCESS:
 | 
					                case EMV_ONLINE_PROCESS:
 | 
				
			||||||
 | 
					                    showModalProcessing("Memproses Otorisasi Online...");
 | 
				
			||||||
                    mockOnlineProcess();
 | 
					                    mockOnlineProcess();
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
@ -149,6 +169,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
                    
 | 
					                    
 | 
				
			||||||
                    Log.e(TAG, "EMV Transaction failed: " + errorDesc + " (Code: " + errorCode + ")");
 | 
					                    Log.e(TAG, "EMV Transaction failed: " + errorDesc + " (Code: " + errorCode + ")");
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
 | 
					                    hideModal();
 | 
				
			||||||
                    if (errorCode == -50009) {
 | 
					                    if (errorCode == -50009) {
 | 
				
			||||||
                        // EMV process conflict - reset and retry
 | 
					                        // EMV process conflict - reset and retry
 | 
				
			||||||
                        Log.d(TAG, "EMV process conflict detected - resetting...");
 | 
					                        Log.d(TAG, "EMV process conflict detected - resetting...");
 | 
				
			||||||
@ -163,8 +184,22 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
                    
 | 
					                    
 | 
				
			||||||
                case EMV_TRANS_SUCCESS:
 | 
					                case EMV_TRANS_SUCCESS:
 | 
				
			||||||
                    // Navigate to results screen
 | 
					                    // Navigate to results screen
 | 
				
			||||||
 | 
					                    hideModal();
 | 
				
			||||||
                    navigateToResults();
 | 
					                    navigateToResults();
 | 
				
			||||||
                    break;
 | 
					                    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();
 | 
					        getIntentData();
 | 
				
			||||||
        initViews();
 | 
					        initViews();
 | 
				
			||||||
 | 
					        initAnimations();
 | 
				
			||||||
        initEMVComponents();
 | 
					        initEMVComponents();
 | 
				
			||||||
        initEMVData();
 | 
					        initEMVData();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
@ -208,12 +244,96 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // Initialize UI components
 | 
					        // Initialize UI components
 | 
				
			||||||
 | 
					        mainContent = findViewById(R.id.main_content);
 | 
				
			||||||
 | 
					        modalOverlay = findViewById(R.id.modal_overlay);
 | 
				
			||||||
        tvStatus = findViewById(R.id.tv_status);
 | 
					        tvStatus = findViewById(R.id.tv_status);
 | 
				
			||||||
        progressBar = findViewById(R.id.progress_bar);
 | 
					        progressBar = findViewById(R.id.progress_bar);
 | 
				
			||||||
        ivCardReader = findViewById(R.id.iv_card_reader);
 | 
					        ivCardReader = findViewById(R.id.iv_card_reader);
 | 
				
			||||||
 | 
					        modalText = findViewById(R.id.modal_text);
 | 
				
			||||||
 | 
					        modalIcon = findViewById(R.id.modal_icon);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // Set initial state
 | 
					        // Set initial state
 | 
				
			||||||
        updateStatusUI("Initializing scanner...", true);
 | 
					        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 ======
 | 
					    // ====== 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);
 | 
					        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
 | 
					        // Start scanning automatically
 | 
				
			||||||
        startCardCheck();
 | 
					        startCardCheck();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -396,6 +519,9 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
        updateStatusUI("Scan error: " + errorMessage + "\n\nRetrying in 2 seconds...", false);
 | 
					        updateStatusUI("Scan error: " + errorMessage + "\n\nRetrying in 2 seconds...", false);
 | 
				
			||||||
        showToast(errorMessage);
 | 
					        showToast(errorMessage);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        // Hide modal on error
 | 
				
			||||||
 | 
					        hideModal();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        // Auto-restart scanning after error
 | 
					        // Auto-restart scanning after error
 | 
				
			||||||
        restartAutoScanning();
 | 
					        restartAutoScanning();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -460,39 +586,65 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
        public void findMagCard(Bundle info) throws RemoteException {
 | 
					        public void findMagCard(Bundle info) throws RemoteException {
 | 
				
			||||||
            android.util.Log.d(TAG, "Simple Mode: findMagCard callback triggered");
 | 
					            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
 | 
					        @Override
 | 
				
			||||||
        public void findICCard(String atr) throws RemoteException {
 | 
					        public void findICCard(String atr) throws RemoteException {
 | 
				
			||||||
            Bundle info = new Bundle();
 | 
					            Bundle info = new Bundle();
 | 
				
			||||||
            info.putString("atr", atr);
 | 
					            info.putString("atr", atr);
 | 
				
			||||||
            runOnUiThread(() -> handleSimpleCardResult(info, "IC"));
 | 
					            runOnUiThread(() -> {
 | 
				
			||||||
 | 
					                showModalProcessing("Kartu IC Ditemukan - Memproses...");
 | 
				
			||||||
 | 
					                new Handler(Looper.getMainLooper()).postDelayed(() -> {
 | 
				
			||||||
 | 
					                    handleSimpleCardResult(info, "IC");
 | 
				
			||||||
 | 
					                }, 1500);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
        public void findRFCard(String uuid) throws RemoteException {
 | 
					        public void findRFCard(String uuid) throws RemoteException {
 | 
				
			||||||
            Bundle info = new Bundle();
 | 
					            Bundle info = new Bundle();
 | 
				
			||||||
            info.putString("uuid", uuid);
 | 
					            info.putString("uuid", uuid);
 | 
				
			||||||
            runOnUiThread(() -> handleSimpleCardResult(info, "NFC"));
 | 
					            runOnUiThread(() -> {
 | 
				
			||||||
 | 
					                showModalProcessing("Kartu NFC Ditemukan - Memproses...");
 | 
				
			||||||
 | 
					                new Handler(Looper.getMainLooper()).postDelayed(() -> {
 | 
				
			||||||
 | 
					                    handleSimpleCardResult(info, "NFC");
 | 
				
			||||||
 | 
					                }, 1500);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
        public void onError(int code, String message) throws RemoteException {
 | 
					        public void onError(int code, String message) throws RemoteException {
 | 
				
			||||||
            runOnUiThread(() -> {
 | 
					            runOnUiThread(() -> {
 | 
				
			||||||
                showToast("Card error: " + message);
 | 
					                showToast("Card error: " + message);
 | 
				
			||||||
 | 
					                hideModal();
 | 
				
			||||||
                stopCardCheck();
 | 
					                stopCardCheck();
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
        public void findICCardEx(Bundle info) throws RemoteException {
 | 
					        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
 | 
					        @Override
 | 
				
			||||||
        public void findRFCardEx(Bundle info) throws RemoteException {
 | 
					        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
 | 
					        @Override
 | 
				
			||||||
@ -500,6 +652,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
            runOnUiThread(() -> {
 | 
					            runOnUiThread(() -> {
 | 
				
			||||||
                String msg = info.getString("message", "Unknown error");
 | 
					                String msg = info.getString("message", "Unknown error");
 | 
				
			||||||
                showToast("Card error: " + msg);
 | 
					                showToast("Card error: " + msg);
 | 
				
			||||||
 | 
					                hideModal();
 | 
				
			||||||
                stopCardCheck();
 | 
					                stopCardCheck();
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -509,26 +662,38 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
    private final CheckCardCallbackV2 mEMVCheckCardCallback = new CheckCardCallbackV2.Stub() {
 | 
					    private final CheckCardCallbackV2 mEMVCheckCardCallback = new CheckCardCallbackV2.Stub() {
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
        public void findMagCard(Bundle info) throws RemoteException {
 | 
					        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
 | 
					        @Override
 | 
				
			||||||
        public void findICCard(String atr) throws RemoteException {
 | 
					        public void findICCard(String atr) throws RemoteException {
 | 
				
			||||||
            MyApplication.app.basicOptV2.buzzerOnDevice(1, 2750, 200, 0);
 | 
					            MyApplication.app.basicOptV2.buzzerOnDevice(1, 2750, 200, 0);
 | 
				
			||||||
            mCardType = AidlConstantsV2.CardType.IC.getValue();
 | 
					            mCardType = AidlConstantsV2.CardType.IC.getValue();
 | 
				
			||||||
            runOnUiThread(() -> startEMVTransactionProcess());
 | 
					            runOnUiThread(() -> {
 | 
				
			||||||
 | 
					                showModalProcessing("Kartu IC Ditemukan - Memulai EMV...");
 | 
				
			||||||
 | 
					                startEMVTransactionProcess();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
        public void findRFCard(String uuid) throws RemoteException {
 | 
					        public void findRFCard(String uuid) throws RemoteException {
 | 
				
			||||||
            mCardType = AidlConstantsV2.CardType.NFC.getValue();
 | 
					            mCardType = AidlConstantsV2.CardType.NFC.getValue();
 | 
				
			||||||
            runOnUiThread(() -> startEMVTransactionProcess());
 | 
					            runOnUiThread(() -> {
 | 
				
			||||||
 | 
					                showModalProcessing("Kartu NFC Ditemukan - Memulai EMV...");
 | 
				
			||||||
 | 
					                startEMVTransactionProcess();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
        public void onError(int code, String message) throws RemoteException {
 | 
					        public void onError(int code, String message) throws RemoteException {
 | 
				
			||||||
            runOnUiThread(() -> {
 | 
					            runOnUiThread(() -> {
 | 
				
			||||||
                showToast("EMV Error: " + message);
 | 
					                showToast("EMV Error: " + message);
 | 
				
			||||||
 | 
					                hideModal();
 | 
				
			||||||
                stopCardCheck();
 | 
					                stopCardCheck();
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -536,13 +701,19 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
        public void findICCardEx(Bundle info) throws RemoteException {
 | 
					        public void findICCardEx(Bundle info) throws RemoteException {
 | 
				
			||||||
            mCardType = AidlConstantsV2.CardType.IC.getValue();
 | 
					            mCardType = AidlConstantsV2.CardType.IC.getValue();
 | 
				
			||||||
            runOnUiThread(() -> startEMVTransactionProcess());
 | 
					            runOnUiThread(() -> {
 | 
				
			||||||
 | 
					                showModalProcessing("Kartu IC Ditemukan - Memulai EMV...");
 | 
				
			||||||
 | 
					                startEMVTransactionProcess();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
        public void findRFCardEx(Bundle info) throws RemoteException {
 | 
					        public void findRFCardEx(Bundle info) throws RemoteException {
 | 
				
			||||||
            mCardType = AidlConstantsV2.CardType.NFC.getValue();
 | 
					            mCardType = AidlConstantsV2.CardType.NFC.getValue();
 | 
				
			||||||
            runOnUiThread(() -> startEMVTransactionProcess());
 | 
					            runOnUiThread(() -> {
 | 
				
			||||||
 | 
					                showModalProcessing("Kartu NFC Ditemukan - Memulai EMV...");
 | 
				
			||||||
 | 
					                startEMVTransactionProcess();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
@ -550,6 +721,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
            runOnUiThread(() -> {
 | 
					            runOnUiThread(() -> {
 | 
				
			||||||
                String msg = info.getString("message", "Unknown error");
 | 
					                String msg = info.getString("message", "Unknown error");
 | 
				
			||||||
                showToast("EMV Error: " + msg);
 | 
					                showToast("EMV Error: " + msg);
 | 
				
			||||||
 | 
					                hideModal();
 | 
				
			||||||
                stopCardCheck();
 | 
					                stopCardCheck();
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -601,12 +773,14 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
                    bundle.putInt("cardType", mCardType);
 | 
					                    bundle.putInt("cardType", mCardType);
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    updateStatusUI("EMV processing started...\nReading card data...", true);
 | 
					                    updateStatusUI("EMV processing started...\nReading card data...", true);
 | 
				
			||||||
 | 
					                    showModalProcessing("Memproses Data Kartu EMV...");
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    Log.d(TAG, "Starting transactProcessEx with reset EMV");
 | 
					                    Log.d(TAG, "Starting transactProcessEx with reset EMV");
 | 
				
			||||||
                    mEMVOptV2.transactProcessEx(bundle, mEMVListener);
 | 
					                    mEMVOptV2.transactProcessEx(bundle, mEMVListener);
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                } catch (Exception e) {
 | 
					                } catch (Exception e) {
 | 
				
			||||||
                    Log.e(TAG, "Error in delayed EMV start: " + e.getMessage(), e);
 | 
					                    Log.e(TAG, "Error in delayed EMV start: " + e.getMessage(), e);
 | 
				
			||||||
 | 
					                    hideModal();
 | 
				
			||||||
                    resetScanningState();
 | 
					                    resetScanningState();
 | 
				
			||||||
                    showToast("Error starting EMV: " + e.getMessage());
 | 
					                    showToast("Error starting EMV: " + e.getMessage());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -615,6 +789,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
        } catch (Exception e) {
 | 
					        } catch (Exception e) {
 | 
				
			||||||
            android.util.Log.e(TAG, "Error starting EMV transaction: " + e.getMessage());
 | 
					            android.util.Log.e(TAG, "Error starting EMV transaction: " + e.getMessage());
 | 
				
			||||||
            e.printStackTrace();
 | 
					            e.printStackTrace();
 | 
				
			||||||
 | 
					            hideModal();
 | 
				
			||||||
            resetScanningState();
 | 
					            resetScanningState();
 | 
				
			||||||
            showToast("Error starting EMV transaction: " + e.getMessage());
 | 
					            showToast("Error starting EMV transaction: " + e.getMessage());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -628,6 +803,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
            android.util.Log.d(TAG, "onWaitAppSelect isFirstSelect:" + isFirstSelect);
 | 
					            android.util.Log.d(TAG, "onWaitAppSelect isFirstSelect:" + isFirstSelect);
 | 
				
			||||||
            mProcessStep = EMV_APP_SELECT;
 | 
					            mProcessStep = EMV_APP_SELECT;
 | 
				
			||||||
            String[] candidateNames = getCandidateNames(appNameList);
 | 
					            String[] candidateNames = getCandidateNames(appNameList);
 | 
				
			||||||
 | 
					            runOnUiThread(() -> hideModal());
 | 
				
			||||||
            mHandler.obtainMessage(EMV_APP_SELECT, candidateNames).sendToTarget();
 | 
					            mHandler.obtainMessage(EMV_APP_SELECT, candidateNames).sendToTarget();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -751,6 +927,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
            String displayText = "Card Number Detected:\n" + maskCardNumber(mCardNo) + 
 | 
					            String displayText = "Card Number Detected:\n" + maskCardNumber(mCardNo) + 
 | 
				
			||||||
                               "\n\nConfirming automatically...";
 | 
					                               "\n\nConfirming automatically...";
 | 
				
			||||||
            updateStatusUI(displayText, true);
 | 
					            updateStatusUI(displayText, true);
 | 
				
			||||||
 | 
					            showModalProcessing("Mengkonfirmasi Nomor Kartu...");
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // Auto-confirm after short delay
 | 
					            // Auto-confirm after short delay
 | 
				
			||||||
            new Handler(Looper.getMainLooper()).postDelayed(() -> {
 | 
					            new Handler(Looper.getMainLooper()).postDelayed(() -> {
 | 
				
			||||||
@ -767,6 +944,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
            String displayText = "Certificate Verification:\n" + mCertInfo + 
 | 
					            String displayText = "Certificate Verification:\n" + mCertInfo + 
 | 
				
			||||||
                               "\n\nProcessing automatically...";
 | 
					                               "\n\nProcessing automatically...";
 | 
				
			||||||
            updateStatusUI(displayText, true);
 | 
					            updateStatusUI(displayText, true);
 | 
				
			||||||
 | 
					            showModalProcessing("Memverifikasi Sertifikat...");
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // Auto-confirm after short delay
 | 
					            // Auto-confirm after short delay
 | 
				
			||||||
            new Handler(Looper.getMainLooper()).postDelayed(() -> {
 | 
					            new Handler(Looper.getMainLooper()).postDelayed(() -> {
 | 
				
			||||||
@ -793,7 +971,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(true);
 | 
					            pinPadConfig.setOrderNumKey(true);  // Set to true for normal order, false for random
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            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");
 | 
				
			||||||
@ -837,6 +1015,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
            
 | 
					            
 | 
				
			||||||
            runOnUiThread(() -> {
 | 
					            runOnUiThread(() -> {
 | 
				
			||||||
                updateStatusUI("PIN confirmed, processing...", true);
 | 
					                updateStatusUI("PIN confirmed, processing...", true);
 | 
				
			||||||
 | 
					                showModalProcessing("PIN Dikonfirmasi - Memproses...");
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            if (pinBlock != null) {
 | 
					            if (pinBlock != null) {
 | 
				
			||||||
@ -855,6 +1034,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
            
 | 
					            
 | 
				
			||||||
            runOnUiThread(() -> {
 | 
					            runOnUiThread(() -> {
 | 
				
			||||||
                updateStatusUI("PIN input cancelled", false);
 | 
					                updateStatusUI("PIN input cancelled", false);
 | 
				
			||||||
 | 
					                hideModal();
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            mHandler.obtainMessage(PIN_CLICK_CANCEL).sendToTarget();
 | 
					            mHandler.obtainMessage(PIN_CLICK_CANCEL).sendToTarget();
 | 
				
			||||||
@ -867,6 +1047,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
            
 | 
					            
 | 
				
			||||||
            runOnUiThread(() -> {
 | 
					            runOnUiThread(() -> {
 | 
				
			||||||
                updateStatusUI("PIN error: " + msg, false);
 | 
					                updateStatusUI("PIN error: " + msg, false);
 | 
				
			||||||
 | 
					                hideModal();
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            mHandler.obtainMessage(PIN_ERROR, code, code, msg).sendToTarget();
 | 
					            mHandler.obtainMessage(PIN_ERROR, code, code, msg).sendToTarget();
 | 
				
			||||||
@ -926,6 +1107,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
        mProcessStep = 0;
 | 
					        mProcessStep = 0;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        updateStatusUI("Ready for card...\n\nPlease insert, swipe, or tap your card", true);
 | 
					        updateStatusUI("Ready for card...\n\nPlease insert, swipe, or tap your card", true);
 | 
				
			||||||
 | 
					        hideModal();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // ====== HELPER METHODS ======
 | 
					    // ====== HELPER METHODS ======
 | 
				
			||||||
@ -1066,6 +1248,8 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
            isProcessing = false;
 | 
					            isProcessing = false;
 | 
				
			||||||
            mProcessStep = 0;
 | 
					            mProcessStep = 0;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
 | 
					            hideModal();
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
        } catch (Exception e) {
 | 
					        } catch (Exception e) {
 | 
				
			||||||
            Log.e(TAG, "Error cleaning up on back press: " + e.getMessage());
 | 
					            Log.e(TAG, "Error cleaning up on back press: " + e.getMessage());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -1092,6 +1276,8 @@ public class EmvTransactionActivity extends AppCompatActivity {
 | 
				
			|||||||
                mEMVOptV2.initEmvProcess();
 | 
					                mEMVOptV2.initEmvProcess();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
 | 
					            hideModal();
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
        } catch (Exception e) {
 | 
					        } catch (Exception e) {
 | 
				
			||||||
            Log.e(TAG, "Error cleaning up EMV: " + e.getMessage());
 | 
					            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,35 +1,123 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="utf-8"?>
 | 
					<?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:app="http://schemas.android.com/apk/res-auto"
 | 
				
			||||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
					    xmlns:tools="http://schemas.android.com/tools"
 | 
				
			||||||
    android:layout_width="match_parent"
 | 
					    android:layout_width="match_parent"
 | 
				
			||||||
    android:layout_height="match_parent"
 | 
					    android:layout_height="match_parent"
 | 
				
			||||||
    android:orientation="vertical"
 | 
					 | 
				
			||||||
    android:background="@color/colorBackground"
 | 
					    android:background="@color/colorBackground"
 | 
				
			||||||
    tools:context=".kredit.EmvTransactionActivity">
 | 
					    tools:context=".kredit.EmvTransactionActivity">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <!-- Toolbar -->
 | 
					    <!-- Main Content -->
 | 
				
			||||||
    <androidx.appcompat.widget.Toolbar
 | 
					 | 
				
			||||||
        android:id="@+id/toolbar"
 | 
					 | 
				
			||||||
        android:layout_width="match_parent"
 | 
					 | 
				
			||||||
        android:layout_height="?attr/actionBarSize"
 | 
					 | 
				
			||||||
        android:background="@color/primary_blue"
 | 
					 | 
				
			||||||
        android:theme="@style/CustomToolbarTheme"
 | 
					 | 
				
			||||||
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <!-- Main Content Container with Center Alignment -->
 | 
					 | 
				
			||||||
    <LinearLayout
 | 
					    <LinearLayout
 | 
				
			||||||
 | 
					        android:id="@+id/main_content"
 | 
				
			||||||
        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:gravity="center"
 | 
					 | 
				
			||||||
        android:padding="24dp">
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <!-- Status Modal Card - Centered and Compact -->
 | 
					        <!-- Toolbar -->
 | 
				
			||||||
 | 
					        <androidx.appcompat.widget.Toolbar
 | 
				
			||||||
 | 
					            android:id="@+id/toolbar"
 | 
				
			||||||
 | 
					            android:layout_width="match_parent"
 | 
				
			||||||
 | 
					            android:layout_height="?attr/actionBarSize"
 | 
				
			||||||
 | 
					            android:background="@color/primary_blue"
 | 
				
			||||||
 | 
					            android:theme="@style/CustomToolbarTheme"
 | 
				
			||||||
 | 
					            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!-- Main Content Container with Center Alignment -->
 | 
				
			||||||
 | 
					        <LinearLayout
 | 
				
			||||||
 | 
					            android:layout_width="match_parent"
 | 
				
			||||||
 | 
					            android:layout_height="match_parent"
 | 
				
			||||||
 | 
					            android:orientation="vertical"
 | 
				
			||||||
 | 
					            android:gravity="center"
 | 
				
			||||||
 | 
					            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"
 | 
				
			||||||
 | 
					                        style="@style/HeaderTextStyle"
 | 
				
			||||||
 | 
					                        android:layout_marginBottom="24dp" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    <!-- Card Reader Animation/Icon -->
 | 
				
			||||||
 | 
					                    <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..."
 | 
				
			||||||
 | 
					                        style="@style/StatusTextStyle"
 | 
				
			||||||
 | 
					                        android:layout_marginBottom="24dp" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    <!-- Progress Indicator -->
 | 
				
			||||||
 | 
					                    <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"
 | 
				
			||||||
 | 
					                        android:layout_marginBottom="16dp" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    <!-- Instructions Text -->
 | 
				
			||||||
 | 
					                    <TextView
 | 
				
			||||||
 | 
					                        android:layout_width="match_parent"
 | 
				
			||||||
 | 
					                        android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                        android:text="Please insert, tap, or swipe your card\nScanning will start automatically"
 | 
				
			||||||
 | 
					                        style="@style/HintTextStyle"
 | 
				
			||||||
 | 
					                        android:gravity="center" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                </LinearLayout>
 | 
				
			||||||
 | 
					            </androidx.cardview.widget.CardView>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        </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
 | 
					        <androidx.cardview.widget.CardView
 | 
				
			||||||
 | 
					            android:id="@+id/modal_card"
 | 
				
			||||||
            android:layout_width="match_parent"
 | 
					            android:layout_width="match_parent"
 | 
				
			||||||
            android:layout_height="wrap_content"
 | 
					            android:layout_height="wrap_content"
 | 
				
			||||||
            android:layout_gravity="center"
 | 
					            android:layout_gravity="center"
 | 
				
			||||||
 | 
					            android:layout_margin="32dp"
 | 
				
			||||||
            app:cardCornerRadius="16dp"
 | 
					            app:cardCornerRadius="16dp"
 | 
				
			||||||
            app:cardElevation="8dp"
 | 
					            app:cardElevation="8dp"
 | 
				
			||||||
            app:cardBackgroundColor="@android:color/white">
 | 
					            app:cardBackgroundColor="@android:color/white">
 | 
				
			||||||
@ -41,67 +129,32 @@
 | 
				
			|||||||
                android:padding="32dp"
 | 
					                android:padding="32dp"
 | 
				
			||||||
                android:gravity="center">
 | 
					                android:gravity="center">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <!-- Header Title -->
 | 
					                <!-- Card Icon -->
 | 
				
			||||||
                <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:id="@+id/modal_icon"
 | 
				
			||||||
                    android:layout_width="120dp"
 | 
					                    android:layout_width="80dp"
 | 
				
			||||||
                    android:layout_height="120dp"
 | 
					                    android:layout_height="80dp"
 | 
				
			||||||
                    android:layout_gravity="center"
 | 
					 | 
				
			||||||
                    android:layout_marginBottom="24dp"
 | 
					 | 
				
			||||||
                    android:src="@drawable/ic_card_insert"
 | 
					                    android:src="@drawable/ic_card_insert"
 | 
				
			||||||
                    android:scaleType="centerInside"
 | 
					                    android:layout_marginBottom="24dp"
 | 
				
			||||||
 | 
					                    android:scaleType="fitCenter"
 | 
				
			||||||
 | 
					                    android:adjustViewBounds="true"
 | 
				
			||||||
                    app:tint="@color/primary_blue" />
 | 
					                    app:tint="@color/primary_blue" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <!-- Status Text -->
 | 
					                <!-- Main Text -->
 | 
				
			||||||
                <TextView
 | 
					                <TextView
 | 
				
			||||||
                    android:id="@+id/tv_status"
 | 
					                    android:id="@+id/modal_text"
 | 
				
			||||||
                    android:layout_width="match_parent"
 | 
					                    android:layout_width="wrap_content"
 | 
				
			||||||
                    android:layout_height="wrap_content"
 | 
					                    android:layout_height="wrap_content"
 | 
				
			||||||
                    android:text="Ready for card scanning..."
 | 
					                    android:text="Silakan Tempelkan / Gesekkan / Masukkan Kartu ke Perangkat"
 | 
				
			||||||
                    android:textSize="16sp"
 | 
					                    style="@style/StatusTextStyle"
 | 
				
			||||||
                    android:textColor="#5A6C7D"
 | 
					                    android:textAlignment="center"
 | 
				
			||||||
                    android:gravity="center"
 | 
					                    android:gravity="center"
 | 
				
			||||||
                    android:lineSpacingExtra="4dp"
 | 
					                    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_height="48dp"
 | 
					 | 
				
			||||||
                    android:layout_gravity="center"
 | 
					 | 
				
			||||||
                    android:visibility="visible"
 | 
					 | 
				
			||||||
                    android:indeterminateTint="@color/primary_blue"
 | 
					 | 
				
			||||||
                    android:layout_marginBottom="16dp" />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                <!-- Instructions Text -->
 | 
					 | 
				
			||||||
                <TextView
 | 
					 | 
				
			||||||
                    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" />
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            </LinearLayout>
 | 
					            </LinearLayout>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        </androidx.cardview.widget.CardView>
 | 
					        </androidx.cardview.widget.CardView>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    </LinearLayout>
 | 
					    </FrameLayout>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</LinearLayout>
 | 
					</FrameLayout>
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user