diff --git a/src/main/java/com/todoroo/andlib/utility/AndroidUtilities.java b/src/main/java/com/todoroo/andlib/utility/AndroidUtilities.java
index 2b549dae3..dfef42880 100644
--- a/src/main/java/com/todoroo/andlib/utility/AndroidUtilities.java
+++ b/src/main/java/com/todoroo/andlib/utility/AndroidUtilities.java
@@ -367,10 +367,18 @@ public class AndroidUtilities {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
}
+ public static boolean atLeastKitKat() {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
+ }
+
public static boolean atLeastLollipop() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
}
+ public static boolean atLeastMarshmallow() {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
+ }
+
/**
* Sort files by date so the newest file is on top
*/
diff --git a/src/main/java/com/todoroo/astrid/reminders/ReminderPreferences.java b/src/main/java/com/todoroo/astrid/reminders/ReminderPreferences.java
index c25aecd9d..3d4396de2 100644
--- a/src/main/java/com/todoroo/astrid/reminders/ReminderPreferences.java
+++ b/src/main/java/com/todoroo/astrid/reminders/ReminderPreferences.java
@@ -27,6 +27,7 @@ import org.tasks.ui.TimePreference;
import javax.inject.Inject;
+import static com.todoroo.andlib.utility.AndroidUtilities.atLeastMarshmallow;
import static com.todoroo.andlib.utility.AndroidUtilities.preJellybean;
public class ReminderPreferences extends InjectingPreferenceActivity {
@@ -38,6 +39,7 @@ public class ReminderPreferences extends InjectingPreferenceActivity {
public static String RESET_GEOFENCES = "reset_geofences";
public static String TOGGLE_GEOFENCES = "toggle_geofences";
+ public static String RESCHEDULE_ALARMS = "reschedule_alarms";
private Bundle result;
@Inject DeviceInfo deviceInfo;
@@ -59,6 +61,11 @@ public class ReminderPreferences extends InjectingPreferenceActivity {
preferenceScreen.removePreference(findPreference(getString(R.string.p_rmd_notif_actions_enabled)));
preferenceScreen.removePreference(findPreference(getString(R.string.p_notification_priority)));
}
+ if (atLeastMarshmallow()) {
+ setExtraOnChange(R.string.p_doze_notifications, RESCHEDULE_ALARMS);
+ } else {
+ preferenceScreen.removePreference(findPreference(getString(R.string.p_doze_notifications)));
+ }
if (deviceInfo.supportsLocationServices()) {
setExtraOnChange(R.string.p_geofence_radius, RESET_GEOFENCES);
diff --git a/src/main/java/org/tasks/preferences/Preferences.java b/src/main/java/org/tasks/preferences/Preferences.java
index 417c6db12..91a8f1b76 100644
--- a/src/main/java/org/tasks/preferences/Preferences.java
+++ b/src/main/java/org/tasks/preferences/Preferences.java
@@ -29,6 +29,7 @@ import timber.log.Timber;
import static android.content.SharedPreferences.Editor;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastJellybean;
+import static com.todoroo.andlib.utility.AndroidUtilities.atLeastMarshmallow;
public class Preferences {
@@ -99,6 +100,10 @@ public class Preferences {
return getStringValue(R.string.gcal_p_default);
}
+ public boolean isDozeNotificationEnabled() {
+ return atLeastMarshmallow() && getBoolean(R.string.p_doze_notifications, false);
+ }
+
public boolean geofencesEnabled() {
return deviceInfo.supportsLocationServices() && getBoolean(R.string.p_geofence_reminders_enabled, true);
}
diff --git a/src/main/java/org/tasks/scheduling/AlarmManager.java b/src/main/java/org/tasks/scheduling/AlarmManager.java
index 2a48e557b..2f5a6aceb 100644
--- a/src/main/java/org/tasks/scheduling/AlarmManager.java
+++ b/src/main/java/org/tasks/scheduling/AlarmManager.java
@@ -3,16 +3,22 @@ package org.tasks.scheduling;
import android.app.PendingIntent;
import android.content.Context;
+import org.tasks.R;
import org.tasks.injection.ForApplication;
+import org.tasks.preferences.Preferences;
import javax.inject.Inject;
+import static com.todoroo.andlib.utility.AndroidUtilities.atLeastKitKat;
+
public class AlarmManager {
private final android.app.AlarmManager alarmManager;
+ private final Preferences preferences;
@Inject
- public AlarmManager(@ForApplication Context context) {
+ public AlarmManager(@ForApplication Context context, Preferences preferences) {
+ this.preferences = preferences;
alarmManager = (android.app.AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
}
@@ -21,11 +27,23 @@ public class AlarmManager {
}
public void wakeup(long time, PendingIntent pendingIntent) {
- alarmManager.set(android.app.AlarmManager.RTC_WAKEUP, time, pendingIntent);
+ if (preferences.isDozeNotificationEnabled()) {
+ alarmManager.setExactAndAllowWhileIdle(android.app.AlarmManager.RTC_WAKEUP, time, pendingIntent);
+ } else if (atLeastKitKat()) {
+ alarmManager.setExact(android.app.AlarmManager.RTC_WAKEUP, time, pendingIntent);
+ } else {
+ alarmManager.set(android.app.AlarmManager.RTC_WAKEUP, time, pendingIntent);
+ }
}
public void noWakeup(long time, PendingIntent pendingIntent) {
- alarmManager.set(android.app.AlarmManager.RTC, time, pendingIntent);
+ if (preferences.isDozeNotificationEnabled()) {
+ alarmManager.setExactAndAllowWhileIdle(android.app.AlarmManager.RTC, time, pendingIntent);
+ } else if (atLeastKitKat()) {
+ alarmManager.setExact(android.app.AlarmManager.RTC, time, pendingIntent);
+ } else {
+ alarmManager.set(android.app.AlarmManager.RTC, time, pendingIntent);
+ }
}
public void setInexactRepeating(long interval, PendingIntent pendingIntent) {
diff --git a/src/main/java/org/tasks/ui/NavigationDrawerFragment.java b/src/main/java/org/tasks/ui/NavigationDrawerFragment.java
index 71a7465f8..db39d18b0 100644
--- a/src/main/java/org/tasks/ui/NavigationDrawerFragment.java
+++ b/src/main/java/org/tasks/ui/NavigationDrawerFragment.java
@@ -32,6 +32,7 @@ import org.tasks.injection.InjectingFragment;
import org.tasks.location.GeofenceService;
import org.tasks.preferences.AppearancePreferences;
import org.tasks.preferences.Preferences;
+import org.tasks.scheduling.AlarmSchedulingIntentService;
import javax.inject.Inject;
@@ -96,6 +97,9 @@ public class NavigationDrawerFragment extends InjectingFragment {
}
} else if (data.getBooleanExtra(ReminderPreferences.RESET_GEOFENCES, false)) {
geofenceService.setupGeofences();
+ } else if (data.getBooleanExtra(ReminderPreferences.RESCHEDULE_ALARMS, false)) {
+ Context context = getContext();
+ context.startService(new Intent(context, AlarmSchedulingIntentService.class));
}
if (data.getBooleanExtra(AppearancePreferences.FILTERS_CHANGED, false)) {
diff --git a/src/main/res/values/keys.xml b/src/main/res/values/keys.xml
index fdca939d3..433fdad91 100644
--- a/src/main/res/values/keys.xml
+++ b/src/main/res/values/keys.xml
@@ -244,6 +244,7 @@
manual_sort
notification_priority
disable_notification_light
+ doze_notifications
- @string/TEA_ctrl_when_pref
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index b621d459f..27ea105da 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -138,6 +138,9 @@
Opt-out
Tag already exists
Disable notification light
+ Interrupt Doze mode for notifications
+ Android will significantly delay notifications while device is in Doze mode
+ Android will allow limited interruptions while device is in Doze mode
diff --git a/src/main/res/xml/preferences_reminders.xml b/src/main/res/xml/preferences_reminders.xml
index d7bfde05c..8b9e01cc1 100644
--- a/src/main/res/xml/preferences_reminders.xml
+++ b/src/main/res/xml/preferences_reminders.xml
@@ -44,6 +44,13 @@
android:key="@string/p_rmd_persistent"
android:summary="@string/persistent_notifications_description"
android:title="@string/persistent_notifications" />
+