如何通过ZXingScanner与[My ScannerIntergrator][1]限制用户仅扫码一次,一周后可重试?
Hey there! Let's figure out how to build that "one scan per week" feature using ZXingScanner and your ScannerIntegrator. I'll walk you through a practical, step-by-step implementation that covers all your requirements:
The key here is to track the last time a user successfully scanned a QR code and block any new scan attempts until 7 days have passed since that timestamp. We'll use local storage to keep this data persistent, and add a check before launching the scanner.
1. Set Up Local Storage for Scan Timestamp
We'll use SharedPreferences (Android's built-in lightweight storage) to save the last successful scan time. It's perfect for this use case since we only need to store a single timestamp value.
// Helper function to save the last scan time private fun saveLastScanTime() { val sharedPrefs = getSharedPreferences("ScanTracker", MODE_PRIVATE) sharedPrefs.edit().putLong("last_scan_timestamp", System.currentTimeMillis()).apply() } // Helper function to get the last scan time private fun getLastScanTime(): Long { val sharedPrefs = getSharedPreferences("ScanTracker", MODE_PRIVATE) return sharedPrefs.getLong("last_scan_timestamp", 0) // 0 means no scan has happened yet }
2. Add Scan Validation Before Launching the Scanner
Before calling your ScannerIntegrator to open ZXingScanner, we need to check if enough time has passed since the last scan. Let's calculate the time difference:
private fun canUserScanAgain(): Boolean { val lastScanTime = getLastScanTime() if (lastScanTime == 0) { // First time scanning, allow it return true } val currentTime = System.currentTimeMillis() val oneWeekInMillis = 7 * 24 * 60 * 60 * 1000 // 7 days in milliseconds return (currentTime - lastScanTime) >= oneWeekInMillis }
Then, when the user taps the "Scan QR Code" button, run this check first:
scanButton.setOnClickListener { if (canUserScanAgain()) { // Launch the scanner using your ScannerIntegrator ScannerIntegrator(this).initiateScan() } else { // Show error message to the user Toast.makeText(this, "您已经扫码过,需一周后才能再次扫码", Toast.LENGTH_LONG).show() } }
3. Update Timestamp After Successful Scan
Once the user successfully scans a QR code (in the result callback), immediately save the current timestamp to lock future scans for the next week:
// Assume this is your scanner result handler override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) val result = ScannerIntegrator.parseActivityResult(requestCode, resultCode, data) if (result != null) { if (result.contents == null) { // User canceled the scan, do nothing Toast.makeText(this, "扫码取消", Toast.LENGTH_SHORT).show() } else { // Scan successful! Save the timestamp first saveLastScanTime() // Now process the scanned content Toast.makeText(this, "扫码成功:${result.contents}", Toast.LENGTH_LONG).show() // Optional: Close the scanner or navigate away to prevent re-scanning finish() } } }
- Handle Edge Cases: If you need to support multiple users or reset the scan limit manually, you could extend this to use a local database (like Room) instead of SharedPreferences.
- Server-Side Validation: If this feature needs to be tamper-proof (users can't edit local storage), you should sync the scan timestamp with your backend server and validate the time difference there instead of locally.
- Clear Feedback: Make sure the error message is clear and tells the user exactly when they can scan again (e.g., "您已扫码,可在${formattedDate}后再次尝试").
内容的提问来源于stack exchange,提问作者user2940926

