如何实现隐形眼镜追踪APP每24小时仅显示一次AlertDialog弹窗?
Hey there! Let's walk through exactly how to build this daily dialog feature for your contact lens tracking app using SharedPreferences. I'll break it down into easy-to-follow steps that cover all your requirements:
The key is to track two things in SharedPreferences:
- The last date we checked for the dialog
- Whether the dialog has already been shown to the user on the current day
Every time the user opens the app, we'll compare the current date with the stored date. If it's a new day, we reset the "dialog shown" flag. Then, we check if the dialog needs to be displayed based on that flag.
First, set up constant keys to avoid typos and make your code cleaner:
// In your Activity or a dedicated Constants file private const val PREF_NAME = "ContactLensTrackerPrefs" private const val KEY_LAST_RECORDED_DATE = "last_recorded_date" private const val KEY_DIALOG_SHOWN_TODAY = "dialog_shown_today"
Add this logic to your main Activity's onCreate method (or a base Activity if you have multiple entry points):
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val sharedPref = getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) val currentDate = LocalDate.now().toString() // Uses device's local timezone, format: yyyy-MM-dd val lastRecordedDate = sharedPref.getString(KEY_LAST_RECORDED_DATE, null) val dialogShownToday = sharedPref.getBoolean(KEY_DIALOG_SHOWN_TODAY, false) // Check if we've moved to a new day if (lastRecordedDate != currentDate) { // Reset the dialog state for the new day sharedPref.edit() .putString(KEY_LAST_RECORDED_DATE, currentDate) .putBoolean(KEY_DIALOG_SHOWN_TODAY, false) .apply() // Since it's a new day, show the dialog showContactLensDialog(sharedPref) } else { // Same day, check if we haven't shown the dialog yet if (!dialogShownToday) { showContactLensDialog(sharedPref) } } }
Now write the method to display the dialog and update the flag when the user interacts with it:
private fun showContactLensDialog(sharedPref: SharedPreferences) { AlertDialog.Builder(this) .setTitle("隐形眼镜佩戴确认") .setMessage("是否佩戴隐形眼镜?") .setPositiveButton("是") { _, _ -> // Add your logic here for when the user wears lenses (e.g., start tracking duration) // ... // Mark the dialog as shown for today sharedPref.edit() .putBoolean(KEY_DIALOG_SHOWN_TODAY, true) .apply() } .setNegativeButton("否") { _, _ -> // Add logic here for when the user doesn't wear lenses // ... // Also mark the dialog as shown to avoid repeat pops sharedPref.edit() .putBoolean(KEY_DIALOG_SHOWN_TODAY, true) .apply() } .setCancelable(false) // Optional: Prevent closing without selecting an option .show() }
- Timezone Awareness:
LocalDate.now()uses the device's local timezone, which aligns with your "midnight update" requirement (midnight in the user's local time). - Device Time Changes: If the user manually changes their device time to a previous day, the dialog might trigger again. For most apps, this edge case isn't critical, but if you need to handle it, you could combine date checks with a timestamp of the last dialog display.
- Multiple Entry Points: If your app has multiple Activities that can be launched directly, move the date check logic to your
Applicationclass'sonCreatemethod or a base Activity to ensure it runs every time the app starts.
If you prefer working with timestamps instead of date strings, here's another approach that checks if the last dialog was shown before today's midnight:
val sharedPref = getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) val lastShownTimestamp = sharedPref.getLong("last_shown_timestamp", 0) val calendar = Calendar.getInstance().apply { set(Calendar.HOUR_OF_DAY, 0) set(Calendar.MINUTE, 0) set(Calendar.SECOND, 0) set(Calendar.MILLISECOND, 0) } val todayMidnight = calendar.timeInMillis if (lastShownTimestamp < todayMidnight) { showContactLensDialog(sharedPref) sharedPref.edit() .putLong("last_shown_timestamp", System.currentTimeMillis()) .apply() }
This works just as well, but the date string method is more readable and easier to debug.
内容的提问来源于stack exchange,提问作者Dante313

