diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.kt index df162766c..a2c2b0e99 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.kt @@ -62,6 +62,7 @@ class HabitsApplication : Application() { widgetUpdater = component.widgetUpdater widgetUpdater.startListening() + widgetUpdater.scheduleStartDayWidgetUpdate() reminderScheduler = component.reminderScheduler reminderScheduler.startListening() diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentScheduler.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentScheduler.kt index 934942f15..2882d3022 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentScheduler.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentScheduler.kt @@ -45,7 +45,7 @@ class IntentScheduler private val manager = context.getSystemService(ALARM_SERVICE) as AlarmManager - fun schedule(timestamp: Long, intent: PendingIntent) { + fun schedule(timestamp: Long, intent: PendingIntent, alarmType: Int) { Log.d("IntentScheduler", "timestamp=" + timestamp + " current=" + System.currentTimeMillis()) if (timestamp < System.currentTimeMillis()) { @@ -54,19 +54,24 @@ class IntentScheduler return; } if (SDK_INT >= M) - manager.setExactAndAllowWhileIdle(RTC_WAKEUP, timestamp, intent) + manager.setExactAndAllowWhileIdle(alarmType, timestamp, intent) else - manager.setExact(RTC_WAKEUP, timestamp, intent) + manager.setExact(alarmType, timestamp, intent) } override fun scheduleShowReminder(reminderTime: Long, habit: Habit, timestamp: Long) { val intent = pendingIntents.showReminder(habit, reminderTime, timestamp) - schedule(reminderTime, intent) + schedule(reminderTime, intent, RTC_WAKEUP) logReminderScheduled(habit, reminderTime) } + override fun scheduleWidgetUpdate(updateTime: Long) { + val intent = pendingIntents.updateWidgets() + schedule(updateTime, intent, RTC) + } + override fun log(componentName: String, msg: String) { Log.d(componentName, msg) } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.kt index cb2f84532..2e36dd231 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.kt @@ -27,6 +27,7 @@ import org.isoron.androidbase.* import org.isoron.uhabits.core.* import org.isoron.uhabits.core.models.* import org.isoron.uhabits.receivers.* +import org.isoron.uhabits.widgets.* import javax.inject.* @AppScope @@ -118,4 +119,12 @@ class PendingIntentFactory if (timestamp != null) putExtra("timestamp", timestamp) }, FLAG_UPDATE_CURRENT) + + fun updateWidgets(): PendingIntent = + PendingIntent.getBroadcast( + context, 0, + Intent(context, WidgetReceiver::class.java).apply { + action = WidgetReceiver.ACTION_UPDATE_WIDGETS_VALUE + }, + FLAG_UPDATE_CURRENT) } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/receivers/WidgetReceiver.java b/android/uhabits-android/src/main/java/org/isoron/uhabits/receivers/WidgetReceiver.java index 2942f8141..18474a52b 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/receivers/WidgetReceiver.java +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/receivers/WidgetReceiver.java @@ -26,6 +26,7 @@ import org.isoron.uhabits.core.preferences.*; import org.isoron.uhabits.core.ui.widgets.*; import org.isoron.uhabits.intents.*; +import org.isoron.uhabits.widgets.*; import org.isoron.uhabits.widgets.activities.*; import dagger.*; @@ -52,6 +53,9 @@ public class WidgetReceiver extends BroadcastReceiver public static final String ACTION_SET_NUMERICAL_VALUE = "org.isoron.uhabits.ACTION_SET_NUMERICAL_VALUE"; + public static final String ACTION_UPDATE_WIDGETS_VALUE = + "org.isoron.uhabits.ACTION_UPDATE_WIDGETS_VALUE"; + private static final String TAG = "WidgetReceiver"; @Override @@ -68,13 +72,17 @@ public void onReceive(final Context context, Intent intent) IntentParser parser = app.getComponent().getIntentParser(); WidgetBehavior controller = component.getWidgetController(); Preferences prefs = app.getComponent().getPreferences(); + WidgetUpdater widgetUpdater = app.getComponent().getWidgetUpdater(); Log.i(TAG, String.format("Received intent: %s", intent.toString())); try { - IntentParser.CheckmarkIntentData data; - data = parser.parseCheckmarkIntent(intent); + IntentParser.CheckmarkIntentData data = null; + if (intent.getAction() != ACTION_UPDATE_WIDGETS_VALUE) + { + data = parser.parseCheckmarkIntent(intent); + } switch (intent.getAction()) { @@ -112,6 +120,10 @@ public void onReceive(final Context context, Intent intent) parser.copyIntentData(intent,numberSelectorIntent); context.startActivity(numberSelectorIntent); break; + case ACTION_UPDATE_WIDGETS_VALUE: + widgetUpdater.updateWidgets(); + widgetUpdater.scheduleStartDayWidgetUpdate(); + break; } } catch (RuntimeException e) diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/WidgetUpdater.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/WidgetUpdater.kt index 17d6d5d77..e05bb48db 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/WidgetUpdater.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/WidgetUpdater.kt @@ -25,6 +25,8 @@ import org.isoron.androidbase.* import org.isoron.uhabits.core.commands.* import org.isoron.uhabits.core.preferences.* import org.isoron.uhabits.core.tasks.* +import org.isoron.uhabits.core.utils.* +import org.isoron.uhabits.intents.* import javax.inject.* /** @@ -36,7 +38,8 @@ class WidgetUpdater @AppContext private val context: Context, private val commandRunner: CommandRunner, private val taskRunner: TaskRunner, - private val widgetPrefs: WidgetPreferences + private val widgetPrefs: WidgetPreferences, + private val intentScheduler: IntentScheduler ) : CommandRunner.Listener { override fun onCommandExecuted(command: Command, refreshKey: Long?) { @@ -60,6 +63,11 @@ class WidgetUpdater commandRunner.removeListener(this) } + fun scheduleStartDayWidgetUpdate() { + val timestamp = DateUtils.getStartOfTomorrow() + intentScheduler.scheduleWidgetUpdate(timestamp); + } + fun updateWidgets(modifiedHabitId: Long?) { taskRunner.execute { updateWidgets(modifiedHabitId, CheckmarkWidgetProvider::class.java) diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/reminders/ReminderScheduler.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/reminders/ReminderScheduler.java index 901bb9087..3e170f25c 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/reminders/ReminderScheduler.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/reminders/ReminderScheduler.java @@ -164,6 +164,8 @@ public interface SystemScheduler { void scheduleShowReminder(long reminderTime, Habit habit, long timestamp); + void scheduleWidgetUpdate(long updateTime); + void log(String componentName, String msg); } } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/utils/DateUtils.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/utils/DateUtils.java index 796a12740..e10625d05 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/utils/DateUtils.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/utils/DateUtils.java @@ -175,9 +175,14 @@ public static long getStartOfToday() return getStartOfDay(getLocalTime()); } + public static long getStartOfTomorrow() + { + return getUpcomingTimeInMillis(0, 0); + } + public static long millisecondsUntilTomorrow() { - return getStartOfToday() + DAY_LENGTH - getLocalTime(); + return getStartOfTomorrow() - getLocalTime(); } public static GregorianCalendar getStartOfTodayCalendar() diff --git a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/utils/DateUtilsTest.java b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/utils/DateUtilsTest.java index ee7db003a..84c942cb4 100644 --- a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/utils/DateUtilsTest.java +++ b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/utils/DateUtilsTest.java @@ -164,6 +164,7 @@ public void testTruncate_year() @Test public void testMillisecondsUntilTomorrow() throws Exception { + DateUtils.setFixedTimeZone(TimeZone.getTimeZone("GMT")); DateUtils.setFixedLocalTime(unixTime(2017, JANUARY, 1, 23, 59)); assertThat(DateUtils.millisecondsUntilTomorrow(), equalTo(60000L));