每周在特定日期重置数据库值的最佳方法(Android - 房间)
Best way to reset a database value every week on specific day (Android - Room)
我正在开发一个 Android 应用程序,该应用程序具有每周一次的功能,也就是说,用户必须在一周中的每一天将这一天标记为完成。这个值在我的数据库中是一个布尔值,用 false 初始化,当用户单击复选框时设置为 true。一切正常。
但我的问题是,每次新的一周开始时,我都需要在一周的所有 7 天中将此布尔值“重置”为 false。我不需要过去几周的记录。重要的是实际的一周(周日到周六)。
这个任务很简单,我只需要这样做:
for(WeekDay day: dao.getWeekDays()){
day.setDone(false);
dao.updateWeekDay(day); //update the value in database
}
所以,我做了一些研究(我是 android 的新手)并发现 Android 有不同的计划服务,如 JobScheduler 或 AlarmManager。我的应用程序设计为 Android 10+ (API 29+)。
您认为解决我的问题的最佳方法是什么?
这是一项非常简单的任务(它不会占用太多电池、互联网...),我需要每周在特定的一天(星期日)执行此操作。另外,这个任务需要尽快完成,即使 phone 在周日关闭。它不需要是后台服务,但我需要保证当用户打开应用程序并且这是新的一周时,之前需要调用该方法,但前提是在前一周没有调用它.
有人有想法吗?
好的,我想我找到了一个简单的解决方案,基于我阅读的其他类似答案。每次应用程序启动时,我只需要 运行 这些功能。我不需要使用任何后台服务,例如 WorkManager。
我只需要在 SharedPreferences 中存储系统重置值的最后日期。然后,每次我打开该应用程序时,它都会检查今天是否与上次重置日期不同。如果它是真的,那么我 运行 问题中的“for cycle”并在 SharedPreferences 中将最后重置日期更新为今天。如果它是假的,我什么都不做。
方法 inSameCalendarWeek 检查今天是否在同一年的同一周(Locale.US 保证一周从星期日开始。但我可以将其更改为 Locale.getDefault()更灵活)。另外,例如,如果 12 月 31 日与 1 月 1 日在同一周,即使它们在不同的年份,该方法也会 return true.
private void checkAndResetDoneDays() {
long lastResetDay = settings.getLong(LAST_DAY_RESET, 0);
LocalDate date = Instant.ofEpochMilli(lastResetDay).atZone(ZoneId.systemDefault()).toLocalDate();
if (!inSameCalendarWeek(date)) {
resetDoneDays();
settings.edit()
.putLong(LAST_DAY_RESET, LocalDate.now(ZoneId.systemDefault()).atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli())
.commit();
}
}
public boolean inSameCalendarWeek(LocalDate firstDate) {
LocalDate secondDate = LocalDate.now(ZoneId.systemDefault());
// get a reference to the system of calendar weeks in US Locale (to guarantee that week starts on Sunday)
WeekFields weekFields = WeekFields.of(Locale.US);
// find out the calendar week for each of the dates
int firstDatesCalendarWeek = firstDate.get(weekFields.weekOfWeekBasedYear());
int secondDatesCalendarWeek = secondDate.get(weekFields.weekOfWeekBasedYear());
/*
* find out the week based year, too,
* two dates might be both in a calendar week number 1 for example,
* but in different years
*/
int firstWeekBasedYear = firstDate.get(weekFields.weekBasedYear());
int secondWeekBasedYear = secondDate.get(weekFields.weekBasedYear());
// return if they are equal or not
return firstDatesCalendarWeek == secondDatesCalendarWeek
&& firstWeekBasedYear == secondWeekBasedYear;
}
我正在开发一个 Android 应用程序,该应用程序具有每周一次的功能,也就是说,用户必须在一周中的每一天将这一天标记为完成。这个值在我的数据库中是一个布尔值,用 false 初始化,当用户单击复选框时设置为 true。一切正常。
但我的问题是,每次新的一周开始时,我都需要在一周的所有 7 天中将此布尔值“重置”为 false。我不需要过去几周的记录。重要的是实际的一周(周日到周六)。
这个任务很简单,我只需要这样做:
for(WeekDay day: dao.getWeekDays()){
day.setDone(false);
dao.updateWeekDay(day); //update the value in database
}
所以,我做了一些研究(我是 android 的新手)并发现 Android 有不同的计划服务,如 JobScheduler 或 AlarmManager。我的应用程序设计为 Android 10+ (API 29+)。 您认为解决我的问题的最佳方法是什么? 这是一项非常简单的任务(它不会占用太多电池、互联网...),我需要每周在特定的一天(星期日)执行此操作。另外,这个任务需要尽快完成,即使 phone 在周日关闭。它不需要是后台服务,但我需要保证当用户打开应用程序并且这是新的一周时,之前需要调用该方法,但前提是在前一周没有调用它.
有人有想法吗?
好的,我想我找到了一个简单的解决方案,基于我阅读的其他类似答案。每次应用程序启动时,我只需要 运行 这些功能。我不需要使用任何后台服务,例如 WorkManager。 我只需要在 SharedPreferences 中存储系统重置值的最后日期。然后,每次我打开该应用程序时,它都会检查今天是否与上次重置日期不同。如果它是真的,那么我 运行 问题中的“for cycle”并在 SharedPreferences 中将最后重置日期更新为今天。如果它是假的,我什么都不做。
方法 inSameCalendarWeek 检查今天是否在同一年的同一周(Locale.US 保证一周从星期日开始。但我可以将其更改为 Locale.getDefault()更灵活)。另外,例如,如果 12 月 31 日与 1 月 1 日在同一周,即使它们在不同的年份,该方法也会 return true.
private void checkAndResetDoneDays() {
long lastResetDay = settings.getLong(LAST_DAY_RESET, 0);
LocalDate date = Instant.ofEpochMilli(lastResetDay).atZone(ZoneId.systemDefault()).toLocalDate();
if (!inSameCalendarWeek(date)) {
resetDoneDays();
settings.edit()
.putLong(LAST_DAY_RESET, LocalDate.now(ZoneId.systemDefault()).atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli())
.commit();
}
}
public boolean inSameCalendarWeek(LocalDate firstDate) {
LocalDate secondDate = LocalDate.now(ZoneId.systemDefault());
// get a reference to the system of calendar weeks in US Locale (to guarantee that week starts on Sunday)
WeekFields weekFields = WeekFields.of(Locale.US);
// find out the calendar week for each of the dates
int firstDatesCalendarWeek = firstDate.get(weekFields.weekOfWeekBasedYear());
int secondDatesCalendarWeek = secondDate.get(weekFields.weekOfWeekBasedYear());
/*
* find out the week based year, too,
* two dates might be both in a calendar week number 1 for example,
* but in different years
*/
int firstWeekBasedYear = firstDate.get(weekFields.weekBasedYear());
int secondWeekBasedYear = secondDate.get(weekFields.weekBasedYear());
// return if they are equal or not
return firstDatesCalendarWeek == secondDatesCalendarWeek
&& firstWeekBasedYear == secondWeekBasedYear;
}