From a840cec30954b314201668938e42feb5219fab2a Mon Sep 17 00:00:00 2001 From: Tzachi Dar Date: Wed, 19 Oct 2016 11:40:20 +0300 Subject: [PATCH 1/9] Import re-raise alerts from xdrip. Signed-off-by: Tzachi Dar --- .../dexdrip/Models/AlertType.java | 16 ++- .../dexdrip/Models/UserNotification.java | 22 +++- .../Services/MissedReadingService.java | 37 ++++-- .../SnoozeOnNotificationDismissService.java | 24 ++++ .../dexdrip/UtilityModels/AlertPlayer.java | 1 + .../dexdrip/UtilityModels/Notifications.java | 123 ++++++++++++------ app/src/main/res/xml/pref_notifications.xml | 14 +- 7 files changed, 175 insertions(+), 62 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Models/AlertType.java b/app/src/main/java/com/eveningoutpost/dexdrip/Models/AlertType.java index 7732537180..83cd324172 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Models/AlertType.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Models/AlertType.java @@ -22,6 +22,7 @@ import java.util.Date; import java.util.List; import java.util.UUID; +import java.util.concurrent.atomic.AtomicBoolean; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -152,7 +153,7 @@ public static AlertType get_alert(String uuid) { * In the case of "unclear state" for more than predefined time, return the "55" alert * In case that alerts are turned off, only return the 55. */ - public static AlertType get_highest_active_alert(Context context, double bg) { + public static AlertType get_highest_active_alert(Context context, double bg, AtomicBoolean unclearReading) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); if(prefs.getLong("alerts_disabled_until", 0) > new Date().getTime()){ Log.d("NOTIFICATIONS", "Notifications are currently disabled!!"); @@ -171,6 +172,7 @@ public static AlertType get_highest_active_alert(Context context, double bg) { AlertType at; if (UnclearTime >= UnclearTimeSetting && bg_unclear_readings_alerts ) { Log.d("NOTIFICATIONS", "Readings have been unclear for too long!!"); + unclearReading.set(true); Notifications.bgUnclearAlert(context); } if ((UnclearTime > 0 ) && bg_unclear_readings_alerts) { @@ -427,15 +429,15 @@ public static void CreateStaticAlerts() { public static void testAll(Context context) { - + AtomicBoolean unclearReading = new AtomicBoolean(false); remove_all(); add_alert(null, "high alert 1", true, 180, true, 10, null, 0, 0, true, 20, true, true); add_alert(null, "high alert 2", true, 200, true, 10, null, 0, 0, true, 20, true, true); add_alert(null, "high alert 3", true, 220, true, 10, null, 0, 0, true, 20, true, true); print_all(); - AlertType a1 = get_highest_active_alert(context, 190); + AlertType a1 = get_highest_active_alert(context, 190, unclearReading); Log.d(TAG, "a1 = " + a1.toString()); - AlertType a2 = get_highest_active_alert(context, 210); + AlertType a2 = get_highest_active_alert(context, 210, unclearReading); Log.d(TAG, "a2 = " + a2.toString()); @@ -445,11 +447,11 @@ public static void testAll(Context context) { add_alert(null, "low alert 1", false, 80, true, 10, null, 0, 0, true, 20, true, true); add_alert(null, "low alert 2", false, 60, true, 10, null, 0, 0, true, 20, true, true); - AlertType al1 = get_highest_active_alert(context, 90); + AlertType al1 = get_highest_active_alert(context, 90, unclearReading); Log.d(TAG, "al1 should be null " + al1); - al1 = get_highest_active_alert(context, 80); + al1 = get_highest_active_alert(context, 80, unclearReading); Log.d(TAG, "al1 = " + al1.toString()); - AlertType al2 = get_highest_active_alert(context, 50); + AlertType al2 = get_highest_active_alert(context, 50, unclearReading); Log.d(TAG, "al2 = " + al2.toString()); Log.d(TAG, "HigherAlert(a1, a2) = a1?" + (HigherAlert(a1,a2) == a2)); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Models/UserNotification.java b/app/src/main/java/com/eveningoutpost/dexdrip/Models/UserNotification.java index 7d86d69627..8041d45795 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Models/UserNotification.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Models/UserNotification.java @@ -1,7 +1,6 @@ package com.eveningoutpost.dexdrip.Models; import android.provider.BaseColumns; -import android.util.Log; import com.activeandroid.Model; import com.activeandroid.annotation.Column; @@ -12,6 +11,8 @@ import java.util.Arrays; import java.util.Date; import java.util.List; +import com.eveningoutpost.dexdrip.Models.UserError.Log; +import com.eveningoutpost.dexdrip.UtilityModels.AlertPlayer; /** * Created by stephenblack on 11/29/14. @@ -20,6 +21,8 @@ @Table(name = "Notifications", id = BaseColumns._ID) public class UserNotification extends Model { + // For 'other alerts' this will be the time that the alert should be raised again. + // For calibration alerts this is the time that the alert was played. @Column(name = "timestamp", index = true) public double timestamp; @@ -54,7 +57,7 @@ public class UserNotification extends Model { "bg_alert", "calibration_alert", "double_calibration_alert", "extra_calibration_alert", "bg_unclear_readings_alert", "bg_missed_alerts", "bg_rise_alert", "bg_fall_alert"); - private final static String TAG = "UserNotification"; + private final static String TAG = AlertPlayer.class.getSimpleName(); public static UserNotification lastBgAlert() { @@ -124,9 +127,20 @@ public static void DeleteNotificationByType(String type) { } } - public static UserNotification create(String message, String type) { + public static void snoozeAlert(String type, long snoozeMinutes) { + UserNotification userNotification = GetNotificationByType(type); + if(userNotification == null) { + Log.e(TAG, "Error snoozeAlert did not find an alert for type " + type); + return; + } + userNotification.timestamp = new Date().getTime() + snoozeMinutes * 60000; + userNotification.save(); + + } + + public static UserNotification create(String message, String type, long timestamp) { UserNotification userNotification = new UserNotification(); - userNotification.timestamp = new Date().getTime(); + userNotification.timestamp = timestamp; userNotification.message = message; if (type == "bg_alert") { userNotification.bg_alert = true; diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Services/MissedReadingService.java b/app/src/main/java/com/eveningoutpost/dexdrip/Services/MissedReadingService.java index d888e5e035..f5d97ca78f 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Services/MissedReadingService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Services/MissedReadingService.java @@ -72,14 +72,13 @@ protected void onHandleIntent(Intent intent) { } bg_missed_minutes = readPerfsInt(prefs, "bg_missed_minutes", 30); - otherAlertSnooze = readPerfsInt(prefs, "other_alerts_snooze", 20); final long now = new Date().getTime(); if (BgReading.getTimeSinceLastReading() >= (bg_missed_minutes * 1000 * 60) && prefs.getLong("alerts_disabled_until", 0) <= now && inTimeFrame(prefs)) { Notifications.bgMissedAlert(context); - checkBackAfterSnoozeTime(now); + checkBackAfterSnoozeTime(context, now); } else { long disabletime = prefs.getLong("alerts_disabled_until", 0) - now; @@ -99,23 +98,30 @@ private boolean inTimeFrame(SharedPreferences prefs) { return AlertType.s_in_time_frame(allDay, startMinutes, endMinutes); } - public void checkBackAfterSnoozeTime(long now) { + private void checkBackAfterSnoozeTime(Context context, long now) { // This is not 100% acurate, need to take in account also the time of when this alert was snoozed. UserNotification userNotification = UserNotification.GetNotificationByType("bg_missed_alerts"); if(userNotification == null) { - setAlarm(otherAlertSnooze * 1000 * 60); + // No active alert exists, should not happen, we have just created it. + Log.wtf(TAG, "No active alert exists."); + setAlarm(getOtherAlertReraiseSec(context) * 1000, false); } else { - // we have an alert that is snoozed until userNotification.timestamp - setAlarm((long)userNotification.timestamp - now + otherAlertSnooze * 1000 * 60); + // we have an alert that should be re-raised on userNotification.timestamp + long alarmIn = (long)userNotification.timestamp - now; + if(alarmIn < 0) { + alarmIn = 0; + } + setAlarm(alarmIn, true); } } public void checkBackAfterMissedTime(long alarmIn) { - setAlarm(alarmIn); + setAlarm(alarmIn, false); } - - public void setAlarm(long alarmIn) { - if(alarmIn < 5 * 60 * 1000) { + + // alarmIn is relative time ms + public void setAlarm(long alarmIn, boolean force) { + if(!force && (alarmIn < 5 * 60 * 1000)) { // No need to check more than once every 5 minutes alarmIn = 5 * 60 * 1000; } @@ -140,4 +146,15 @@ static public int readPerfsInt(SharedPreferences prefs, String name, int default return defaultValue; } } + + static public long getOtherAlertReraiseSec(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + boolean disableAlertsReraise = prefs.getBoolean("disable_alerts_reraise", false); + if(disableAlertsReraise) { + return readPerfsInt(prefs, "other_alerts_reraise_sec", 60); + } else { + return 60 * readPerfsInt(prefs, "other_alerts_snooze", 20); + } + + } } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java b/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java index 04e2380c55..180c75d323 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java @@ -11,6 +11,7 @@ import com.eveningoutpost.dexdrip.SnoozeActivity; import com.eveningoutpost.dexdrip.Models.ActiveBgAlert; import com.eveningoutpost.dexdrip.Models.AlertType; +import com.eveningoutpost.dexdrip.Models.UserNotification; import com.eveningoutpost.dexdrip.UtilityModels.AlertPlayer; /** @@ -29,6 +30,23 @@ public SnoozeOnNotificationDismissService() { @Override protected void onHandleIntent(Intent intent) { + String alertType = intent.getStringExtra("alertType"); // Replace by constant + Log.e(TAG, "SnoozeOnNotificationDismissService called source = " + alertType); + if(alertType.equals("bg_alerts") ) { + snoozeBgAlert(); + return; + } + if(alertType.equals("bg_unclear_readings_alert") || + alertType.equals("bg_missed_alerts") || + alertType.equals("bg_predict_alert") || + alertType.equals("persistent_high_alert")) { + snoozeOtherAlert(alertType); + return; + } + Log.e(TAG, "SnoozeOnNotificationDismissService called for unknown source = " + alertType); + } + + private void snoozeBgAlert() { AlertType activeBgAlert = ActiveBgAlert.alertTypegetOnly(); int snooze = 30; @@ -42,4 +60,10 @@ protected void onHandleIntent(Intent intent) { AlertPlayer.getPlayer().Snooze(getApplicationContext(), snooze); } + + private void snoozeOtherAlert(String alertType) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + int snoozeMinutes = MissedReadingService.readPerfsInt(prefs, "other_alerts_snooze", 20); + UserNotification.snoozeAlert(alertType, snoozeMinutes); + } } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/AlertPlayer.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/AlertPlayer.java index 89c2398bea..eba2616e4b 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/AlertPlayer.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/AlertPlayer.java @@ -338,6 +338,7 @@ private PendingIntent notificationIntent(Context ctx, Intent intent){ } private PendingIntent snoozeIntent(Context ctx){ Intent intent = new Intent(ctx, SnoozeOnNotificationDismissService.class); + intent.putExtra("alertType", "bg_alerts"); return PendingIntent.getService(ctx, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java index f85e69456a..3a94d6b923 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java @@ -38,7 +38,7 @@ import com.eveningoutpost.dexdrip.Models.UserNotification; import com.eveningoutpost.dexdrip.Services.ActivityRecognizedService; import com.eveningoutpost.dexdrip.Services.MissedReadingService; - +import com.eveningoutpost.dexdrip.Services.SnoozeOnNotificationDismissService; import com.eveningoutpost.dexdrip.R; import com.eveningoutpost.dexdrip.Models.Sensor; import com.eveningoutpost.dexdrip.utils.DexCollectionType; @@ -47,6 +47,7 @@ import java.util.Calendar; import java.util.Date; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; import static com.eveningoutpost.dexdrip.UtilityModels.ColorCache.getCol; import static com.eveningoutpost.dexdrip.UtilityModels.ColorCache.X; @@ -111,6 +112,7 @@ protected void onHandleIntent(Intent intent) { PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE); PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "NotificationsIntent"); wl.acquire(60000); + AtomicBoolean unclearReading = new AtomicBoolean(false); try { Log.d("Notifications", "Running Notifications Intent Service"); final Context context = getApplicationContext(); @@ -120,8 +122,8 @@ protected void onHandleIntent(Intent intent) { } ReadPerfs(context); - notificationSetter(context); - ArmTimer(context); + notificationSetter(context, unclearReading); + ArmTimer(context, unclearReading.get()); context.startService(new Intent(context, MissedReadingService.class)); @@ -166,7 +168,7 @@ public void ReadPerfs(Context context) { */ - private void FileBasedNotifications(Context context) { + private void FileBasedNotifications(Context context, AtomicBoolean unclearReading) { ReadPerfs(context); Sensor sensor = Sensor.currentSensor(); @@ -183,8 +185,9 @@ private void FileBasedNotifications(Context context) { // If the last reading does not have a sensor, or that sensor was stopped. // or the sensor was started, but the 2 hours did not still pass? or there is no calibrations. // In all this cases, bgReading.calculated_value should be 0. + // TODO Tzachi: remove sensor != null once sensor data code is checked in. if (((sensor != null) || (Home.get_follower())) && bgReading != null && bgReading.calculated_value != 0) { - AlertType newAlert = AlertType.get_highest_active_alert(context, bgReading.calculated_value); + AlertType newAlert = AlertType.get_highest_active_alert(context, bgReading.calculated_value, unclearReading); if (newAlert == null) { Log.d(TAG, "FileBasedNotifications - No active notifcation exists, stopping all alerts"); @@ -273,7 +276,7 @@ boolean trendingToAlertEnd(Context context, Boolean newAlert, AlertType Alert) { * ***************************************************************************************************************** */ - private void notificationSetter(Context context) { + private void notificationSetter(Context context, AtomicBoolean unclearReading) { ReadPerfs(context); final long end = System.currentTimeMillis() + (60000 * 5); final long start = end - (60000 * 60 * 3) - (60000 * 10); @@ -286,7 +289,7 @@ private void notificationSetter(Context context) { Log.d("NOTIFICATIONS", "Notifications are currently disabled!!"); return; } - FileBasedNotifications(context); + FileBasedNotifications(context, unclearReading); BgReading.checkForDropAllert(context); BgReading.checkForRisingAllert(context); BgReading.checkForPersistentHigh(); @@ -338,26 +341,69 @@ private void notificationSetter(Context context) { } } - private long calcuatleArmTime(Context ctx, long now) { + // This is the absolute time, not time from now. + private long calcuatleArmTimeUnclearalert(Context ctx, long now, boolean unclearAlert) { + if (!unclearAlert) { + return Long.MAX_VALUE; + } + Long wakeTimeUnclear = Long.MAX_VALUE; - Long wakeTime = Long.MAX_VALUE; // This is the absalute time, not time from now. + UserNotification userNotification = UserNotification.GetNotificationByType("bg_unclear_readings_alert"); + if (userNotification == null) { + // An alert should have already being played, how is this NULL. + Log.wtf(TAG, "No active alert exists."); + wakeTimeUnclear = now + MissedReadingService.getOtherAlertReraiseSec(ctx) * 1000; + } else { + // This alert is snoozed + // reminder - userNotification.timestamp is the time that the alert should be played again + wakeTimeUnclear = (long)userNotification.timestamp; + } + + if(wakeTimeUnclear < now ) { + // we should alert now, + wakeTimeUnclear = now; + } + if( wakeTimeUnclear == Long.MAX_VALUE) { + // Should not happen + Log.e(TAG ,"calcuatleArmTimeUnclearalert wakeTimeUnclear bad value setting it to one minute from now " + new Date(wakeTimeUnclear) + " in " + ((wakeTimeUnclear - now)/60000d) + " minutes" ); + return now + 60 * 1000; + } + Log.w(TAG ,"calcuatleArmTimeUnclearalert returning " + new Date(wakeTimeUnclear) + " in " + ((wakeTimeUnclear - now)/60000d) + " minutes" ); + return wakeTimeUnclear; + } + + // This is the absolute time, not time from now. + private long calcuatleArmTimeBg(long now) { + Long wakeTimeBg = Long.MAX_VALUE; ActiveBgAlert activeBgAlert = ActiveBgAlert.getOnly(); if (activeBgAlert != null) { AlertType alert = AlertType.get_alert(activeBgAlert.alert_uuid); if (alert != null) { - wakeTime = activeBgAlert.next_alert_at ; - Log.d(TAG , "ArmTimer waking at: "+ new Date(wakeTime) +" in " + (wakeTime - now)/60000d + " minutes"); - if (wakeTime < now) { + wakeTimeBg = activeBgAlert.next_alert_at ; + Log.d(TAG , "ArmTimer BG alert -waking at: "+ new Date(wakeTimeBg) +" in " + (wakeTimeBg - now)/60000d + " minutes"); + if (wakeTimeBg < now) { // next alert should be at least one minute from now. - wakeTime = now + 60000; + wakeTimeBg = now + 60000; Log.w(TAG , "setting next alert to 1 minute from now (no problem right now, but needs a fix someplace else)"); } - + } - } else { - // no active alert exists - wakeTime = now + 6 * 60000; } + Log.d("Notifications" , "calcuatleArmTimeBg returning: "+ new Date(wakeTimeBg) +" in " + (wakeTimeBg - now)/60000d + " minutes"); + return wakeTimeBg; + } + + + + // This is the absolute time, not time from now. + private long calcuatleArmTime(Context ctx, long now, boolean unclearAlert) { + Long wakeTimeBg = calcuatleArmTimeBg(now); + Long wakeTimeUnclear = calcuatleArmTimeUnclearalert(ctx, now, unclearAlert); + Long wakeTime = Math.min(wakeTimeBg, wakeTimeUnclear); + + Log.d("Notifications" , "calcuatleArmTimeBg returning: "+ new Date(wakeTime) +" in " + (wakeTime - now)/60000d + " minutes"); + return wakeTime; + /* * * leaving this code here since this is a code for a more correct calculation @@ -379,22 +425,17 @@ private long calcuatleArmTime(Context ctx, long now) { // All this requires listeners on snooze changes... // check when the first alert should be fired. take care of that ??? */ - Log.d("Notifications" , "calcuatleArmTime returning: "+ new Date(wakeTime) +" in " + (wakeTime - now)/60000d + " minutes"); - return wakeTime; } - private void ArmTimer(Context ctx) { + private void ArmTimer(Context ctx, boolean unclearAlert) { Calendar calendar = Calendar.getInstance(); final long now = calendar.getTimeInMillis(); Log.d("Notifications", "ArmTimer called"); - long wakeTime = calcuatleArmTime(ctx, now); - if(wakeTime == Long.MAX_VALUE) { - Log.d("Notifications" , "ArmTimer timer will not br armed"); - return; - } + long wakeTime = calcuatleArmTime(ctx, now, unclearAlert); + - if(wakeTime < now ) { + if(wakeTime < now || wakeTime == Long.MAX_VALUE) { Log.e("Notifications" , "ArmTimer recieved a negative time, will fire in 6 minutes"); wakeTime = now + 6 * 60000; } @@ -635,7 +676,7 @@ private void calibrationRequest() { UserNotification userNotification = UserNotification.lastCalibrationAlert(); if ((userNotification == null) || (userNotification.timestamp <= ((new Date().getTime()) - (60000 * calibration_snooze)))) { if (userNotification != null) { userNotification.delete(); } - UserNotification.create("12 hours since last Calibration (@" + JoH.hourMinuteString() + ")", "calibration_alert"); + UserNotification.create("12 hours since last Calibration (@" + JoH.hourMinuteString() + ")", "calibration_alert", new Date().getTime()); String title = "Calibration Needed"; String content = "12 hours since last calibration"; Intent intent = new Intent(mContext, AddCalibration.class); @@ -647,7 +688,7 @@ private void doubleCalibrationRequest() { UserNotification userNotification = UserNotification.lastDoubleCalibrationAlert(); if ((userNotification == null) || (userNotification.timestamp <= ((new Date().getTime()) - (60000 * calibration_snooze)))) { if (userNotification != null) { userNotification.delete(); } - UserNotification.create("Double Calibration", "double_calibration_alert"); + UserNotification.create("Double Calibration", "double_calibration_alert", new Date().getTime()); String title = "Sensor is ready"; String content = getString(R.string.sensor_is_ready_please_enter_double_calibration) + " (@" + JoH.hourMinuteString() + ")"; Intent intent = new Intent(mContext, DoubleCalibrationActivity.class); @@ -659,7 +700,7 @@ private void extraCalibrationRequest() { UserNotification userNotification = UserNotification.lastExtraCalibrationAlert(); if ((userNotification == null) || (userNotification.timestamp <= ((new Date().getTime()) - (60000 * calibration_snooze)))) { if (userNotification != null) { userNotification.delete(); } - UserNotification.create("Extra Calibration Requested", "extra_calibration_alert"); + UserNotification.create("Extra Calibration Requested", "extra_calibration_alert", new Date().getTime()); String title = "Calibration Needed"; String content = "A calibration entered now will GREATLY increase performance" + " (@" + JoH.hourMinuteString() + ")"; Intent intent = new Intent(mContext, AddCalibration.class); @@ -668,15 +709,13 @@ private void extraCalibrationRequest() { } public static void bgUnclearAlert(Context context) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - int otherAlertSnooze = MissedReadingService.readPerfsInt(prefs, "other_alerts_snooze", 20); - OtherAlert(context, "bg_unclear_readings_alert", "Unclear Sensor Readings" + " (@" + JoH.hourMinuteString() + ")", uncleanAlertNotificationId, otherAlertSnooze); + long otherAlertReraiseSec = MissedReadingService.getOtherAlertReraiseSec(context); + OtherAlert(context, "bg_unclear_readings_alert", "Unclear Sensor Readings" + " (@" + JoH.hourMinuteString() + ")", uncleanAlertNotificationId, otherAlertReraiseSec); } public static void bgMissedAlert(Context context) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - int otherAlertSnooze = MissedReadingService.readPerfsInt(prefs, "other_alerts_snooze", 20); - OtherAlert(context, "bg_missed_alerts", "BG Readings Missed" + " (@" + JoH.hourMinuteString() + ")", missedAlertNotificationId, otherAlertSnooze); + long otherAlertReraiseSec = MissedReadingService.getOtherAlertReraiseSec(context); + OtherAlert(context, "bg_missed_alerts", "BG Readings Missed" + " (@" + JoH.hourMinuteString() + ")", missedAlertNotificationId, otherAlertReraiseSec); } public static void RisingAlert(Context context, boolean on) { @@ -735,14 +774,14 @@ public static void RiseDropAlert(Context context, boolean on, String type, Strin } } - private static void OtherAlert(Context context, String type, String message, int notificatioId, int snooze) { + private static void OtherAlert(Context context, String type, String message, int notificatioId, long reraiseSec) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); String otherAlertsSound = prefs.getString(type+"_sound",prefs.getString("other_alerts_sound", "content://settings/system/notification_sound")); Boolean otherAlertsOverrideSilent = prefs.getBoolean("other_alerts_override_silent", false); - Log.d(TAG,"OtherAlert called " + type + " " + message + " snooze = " + snooze); + Log.d(TAG,"OtherAlert called " + type + " " + message + " reraiseSec = " + reraiseSec); UserNotification userNotification = UserNotification.GetNotificationByType(type); //"bg_unclear_readings_alert" - if ((userNotification == null) || (userNotification.timestamp <= ((new Date().getTime()) - (60000 * snooze)))) { + if ((userNotification == null) || userNotification.timestamp <= new Date().getTime() ) { if (userNotification != null) { try { userNotification.delete(); @@ -751,14 +790,18 @@ private static void OtherAlert(Context context, String type, String message, int } Log.d(TAG, "Delete"); } - UserNotification.create(message, type); + UserNotification.create(message, type, new Date().getTime() + reraiseSec * 1000); + + Intent deleteIntent = new Intent(context, SnoozeOnNotificationDismissService.class); + deleteIntent.putExtra("alertType", type); Intent intent = new Intent(context, Home.class); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context) .setSmallIcon(R.drawable.ic_action_communication_invert_colors_on) .setContentTitle(message) .setContentText(message) - .setContentIntent(PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); + .setContentIntent(PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)) + .setDeleteIntent(PendingIntent.getService(context, 0, deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT)); mBuilder.setVibrate(vibratePattern); mBuilder.setLights(0xff00ff00, 300, 1000); if (AlertPlayer.notSilencedDueToCall()) { diff --git a/app/src/main/res/xml/pref_notifications.xml b/app/src/main/res/xml/pref_notifications.xml index 58ae8bed32..296b9532a3 100644 --- a/app/src/main/res/xml/pref_notifications.xml +++ b/app/src/main/res/xml/pref_notifications.xml @@ -171,8 +171,20 @@ android:defaultValue="20" android:key="other_alerts_snooze" android:numeric="integer" - android:summary="Minimum number of minutes to pass before raising the same alert." + android:summary="Number of minutes before raising the same alert after snooze." android:title="Alert Snooze" /> + + Date: Wed, 26 Oct 2016 01:13:06 +0300 Subject: [PATCH 2/9] Move the calculating of unclear alerts to a higher level, so it can be used by all places in stack. Also calculate it only when filters data exists, and feature is turned on. Signed-off-by: Tzachi Dar --- .../dexdrip/Models/AlertType.java | 27 +++--------- .../dexdrip/Models/BgReading.java | 43 ++++++++----------- .../dexdrip/UtilityModels/Notifications.java | 36 ++++++++++------ 3 files changed, 48 insertions(+), 58 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Models/AlertType.java b/app/src/main/java/com/eveningoutpost/dexdrip/Models/AlertType.java index 83cd324172..ff4a22a204 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Models/AlertType.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Models/AlertType.java @@ -153,7 +153,7 @@ public static AlertType get_alert(String uuid) { * In the case of "unclear state" for more than predefined time, return the "55" alert * In case that alerts are turned off, only return the 55. */ - public static AlertType get_highest_active_alert(Context context, double bg, AtomicBoolean unclearReading) { + public static AlertType get_highest_active_alert(Context context, double bg) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); if(prefs.getLong("alerts_disabled_until", 0) > new Date().getTime()){ Log.d("NOTIFICATIONS", "Notifications are currently disabled!!"); @@ -164,21 +164,7 @@ public static AlertType get_highest_active_alert(Context context, double bg, Ato return null; } - Boolean bg_unclear_readings_alerts = prefs.getBoolean("bg_unclear_readings_alerts", false); - Long UnclearTimeSetting = Long.parseLong(prefs.getString("bg_unclear_readings_minutes", "90")) * 60000; - - Long UnclearTime = BgReading.getUnclearTime(UnclearTimeSetting); - AlertType at; - if (UnclearTime >= UnclearTimeSetting && bg_unclear_readings_alerts ) { - Log.d("NOTIFICATIONS", "Readings have been unclear for too long!!"); - unclearReading.set(true); - Notifications.bgUnclearAlert(context); - } - if ((UnclearTime > 0 ) && bg_unclear_readings_alerts) { - Log.d(TAG_ALERT, "We are in an clear state, but not for too long. Alerts are disabled"); - return null; - } at = get_highest_active_alert_helper(bg, prefs); if (at != null) { Log.d(TAG_ALERT, "get_highest_active_alert_helper returned alert uuid = " + at.uuid + " alert name = " + at.name); @@ -429,15 +415,14 @@ public static void CreateStaticAlerts() { public static void testAll(Context context) { - AtomicBoolean unclearReading = new AtomicBoolean(false); remove_all(); add_alert(null, "high alert 1", true, 180, true, 10, null, 0, 0, true, 20, true, true); add_alert(null, "high alert 2", true, 200, true, 10, null, 0, 0, true, 20, true, true); add_alert(null, "high alert 3", true, 220, true, 10, null, 0, 0, true, 20, true, true); print_all(); - AlertType a1 = get_highest_active_alert(context, 190, unclearReading); + AlertType a1 = get_highest_active_alert(context, 190); Log.d(TAG, "a1 = " + a1.toString()); - AlertType a2 = get_highest_active_alert(context, 210, unclearReading); + AlertType a2 = get_highest_active_alert(context, 210); Log.d(TAG, "a2 = " + a2.toString()); @@ -447,11 +432,11 @@ public static void testAll(Context context) { add_alert(null, "low alert 1", false, 80, true, 10, null, 0, 0, true, 20, true, true); add_alert(null, "low alert 2", false, 60, true, 10, null, 0, 0, true, 20, true, true); - AlertType al1 = get_highest_active_alert(context, 90, unclearReading); + AlertType al1 = get_highest_active_alert(context, 90); Log.d(TAG, "al1 should be null " + al1); - al1 = get_highest_active_alert(context, 80, unclearReading); + al1 = get_highest_active_alert(context, 80); Log.d(TAG, "al1 = " + al1.toString()); - AlertType al2 = get_highest_active_alert(context, 50, unclearReading); + AlertType al2 = get_highest_active_alert(context, 50); Log.d(TAG, "al2 = " + al2.toString()); Log.d(TAG, "HigherAlert(a1, a2) = a1?" + (HigherAlert(a1,a2) == a2)); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java b/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java index 43e2ff7117..9274aa8e8a 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java @@ -1189,11 +1189,6 @@ public static void checkForRisingAllert(Context context) { return; } - if(IsUnclearTime(context)) { - Log.d(TAG_ALERT, "checkForRisingAllert we are in an clear time, returning without doing anything"); - return ; - } - String riseRate = prefs.getString("rising_bg_val", "2"); float friseRate = 2; @@ -1223,11 +1218,6 @@ public static void checkForDropAllert(Context context) { return; } - if(IsUnclearTime(context)) { - Log.d(TAG_ALERT, "checkForDropAllert we are in an clear time, returning without doing anything"); - return ; - } - String dropRate = prefs.getString("falling_bg_val", "2"); float fdropRate = 2; @@ -1284,18 +1274,28 @@ private static boolean checkForDropRiseAllert(float MaxSpeed, boolean drop) { return true; } - private static boolean IsUnclearTime(Context context) { + public static boolean getAndRaiseUnclearReading(Context context) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - + Boolean bg_unclear_readings_alerts = prefs.getBoolean("bg_unclear_readings_alerts", false); - if(bg_unclear_readings_alerts) { - Long UnclearTimeSetting = Long.parseLong(prefs.getString("bg_unclear_readings_minutes", "90")) * 60000; - Long unclearTime = getUnclearTime(UnclearTimeSetting); - if (unclearTime > 0) { - Log.d(TAG_ALERT, "IsUnclearTime we are in an clear time, returning true"); - return true; - } + if (!bg_unclear_readings_alerts || (!DexCollectionType.hasFiltered())) { + Log.d(TAG_ALERT, "getUnclearReading returned false since feature is disabled"); + return false; } + Long UnclearTimeSetting = Long.parseLong(prefs.getString("bg_unclear_readings_minutes", "90")) * 60000; + + Long UnclearTime = BgReading.getUnclearTime(UnclearTimeSetting); + + if (UnclearTime >= UnclearTimeSetting ) { + Log.d("NOTIFICATIONS", "Readings have been unclear for too long!!"); + Notifications.bgUnclearAlert(context); + return true; + } + if (UnclearTime > 0 ) { + Log.d(TAG_ALERT, "We are in an clear state, but not for too long. Alerts are disabled"); + return true; + } + return false; } /* @@ -1311,11 +1311,6 @@ public static boolean trendingToAlertEnd(Context context, boolean above) { // TODO: check if we are not in an UnclerTime. Log.d(TAG_ALERT, "trendingToAlertEnd called"); - if(IsUnclearTime(context)) { - Log.d(TAG_ALERT, "trendingToAlertEnd we are in an clear time, returning false"); - return false; - } - List latest = getXRecentPoints(3); if(latest == null) { Log.d(TAG_ALERT, "trendingToAlertEnd we don't have enough points from the last 15 minutes, returning false"); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java index 3a94d6b923..ef460db97b 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java @@ -112,7 +112,7 @@ protected void onHandleIntent(Intent intent) { PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE); PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "NotificationsIntent"); wl.acquire(60000); - AtomicBoolean unclearReading = new AtomicBoolean(false); + boolean unclearReading = false; try { Log.d("Notifications", "Running Notifications Intent Service"); final Context context = getApplicationContext(); @@ -122,8 +122,8 @@ protected void onHandleIntent(Intent intent) { } ReadPerfs(context); - notificationSetter(context, unclearReading); - ArmTimer(context, unclearReading.get()); + unclearReading = notificationSetter(context); + ArmTimer(context, unclearReading); context.startService(new Intent(context, MissedReadingService.class)); @@ -168,7 +168,7 @@ public void ReadPerfs(Context context) { */ - private void FileBasedNotifications(Context context, AtomicBoolean unclearReading) { + private void FileBasedNotifications(Context context) { ReadPerfs(context); Sensor sensor = Sensor.currentSensor(); @@ -187,7 +187,7 @@ private void FileBasedNotifications(Context context, AtomicBoolean unclearReadin // In all this cases, bgReading.calculated_value should be 0. // TODO Tzachi: remove sensor != null once sensor data code is checked in. if (((sensor != null) || (Home.get_follower())) && bgReading != null && bgReading.calculated_value != 0) { - AlertType newAlert = AlertType.get_highest_active_alert(context, bgReading.calculated_value, unclearReading); + AlertType newAlert = AlertType.get_highest_active_alert(context, bgReading.calculated_value); if (newAlert == null) { Log.d(TAG, "FileBasedNotifications - No active notifcation exists, stopping all alerts"); @@ -276,7 +276,8 @@ boolean trendingToAlertEnd(Context context, Boolean newAlert, AlertType Alert) { * ***************************************************************************************************************** */ - private void notificationSetter(Context context, AtomicBoolean unclearReading) { + // returns weather unclear bg reading was detected + private boolean notificationSetter(Context context) { ReadPerfs(context); final long end = System.currentTimeMillis() + (60000 * 5); final long start = end - (60000 * 60 * 3) - (60000 * 10); @@ -287,11 +288,19 @@ private void notificationSetter(Context context, AtomicBoolean unclearReading) { } if (prefs.getLong("alerts_disabled_until", 0) > new Date().getTime()) { Log.d("NOTIFICATIONS", "Notifications are currently disabled!!"); - return; + return false; + } + + boolean unclearReading = BgReading.getAndRaiseUnclearReading(context); + + if (unclearReading) { + AlertPlayer.getPlayer().stopAlert(context, false, true); + } else { + FileBasedNotifications(context); + BgReading.checkForDropAllert(context); + BgReading.checkForRisingAllert(context); } - FileBasedNotifications(context, unclearReading); - BgReading.checkForDropAllert(context); - BgReading.checkForRisingAllert(context); + // TODO: Add this alerts as well to depend on unclear sensor reading. BgReading.checkForPersistentHigh(); evaluateLowPredictionAlarm(); reportNoiseChanges(); @@ -303,10 +312,10 @@ private void notificationSetter(Context context, AtomicBoolean unclearReading) { List bgReadings = BgReading.latest(3); List calibrations = Calibration.allForSensorInLastFourDays(); if (bgReadings == null || bgReadings.size() < 3) { - return; + return unclearReading; } if (calibrations == null || calibrations.size() < 2) { - return; + return unclearReading; } BgReading bgReading = bgReadings.get(0); @@ -339,6 +348,7 @@ private void notificationSetter(Context context, AtomicBoolean unclearReading) { } else { clearAllCalibrationNotifications(); } + return unclearReading; } // This is the absolute time, not time from now. @@ -435,7 +445,7 @@ private void ArmTimer(Context ctx, boolean unclearAlert) { long wakeTime = calcuatleArmTime(ctx, now, unclearAlert); - if(wakeTime < now || wakeTime == Long.MAX_VALUE) { + if(wakeTime < now || wakeTime >= now + 6 * 60000 ) { Log.e("Notifications" , "ArmTimer recieved a negative time, will fire in 6 minutes"); wakeTime = now + 6 * 60000; } From b49fbc366a982e2618bf362d46692bcc8a31d183 Mon Sep 17 00:00:00 2001 From: Tzachi Dar Date: Wed, 26 Oct 2016 01:23:50 +0300 Subject: [PATCH 3/9] Make sure that behavior is preserved unless the user has specifically decided to use shorter reraise. Signed-off-by: Tzachi Dar --- .../Services/SnoozeOnNotificationDismissService.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java b/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java index 180c75d323..2d81612791 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java @@ -40,7 +40,12 @@ protected void onHandleIntent(Intent intent) { alertType.equals("bg_missed_alerts") || alertType.equals("bg_predict_alert") || alertType.equals("persistent_high_alert")) { - snoozeOtherAlert(alertType); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + boolean disableAlertsReraise = prefs.getBoolean("disable_alerts_reraise", false); + if(disableAlertsReraise) { + // Only snooze these alert if it the reraise function is enabled. + snoozeOtherAlert(alertType); + } return; } Log.e(TAG, "SnoozeOnNotificationDismissService called for unknown source = " + alertType); From b9fe9267ccbb986074a667685f2483d569c36806 Mon Sep 17 00:00:00 2001 From: Tzachi Dar Date: Wed, 26 Oct 2016 01:28:27 +0300 Subject: [PATCH 4/9] Rename the disable alerts reraise (enable alerts reraise). Signed-off-by: Tzachi Dar --- .../eveningoutpost/dexdrip/Services/MissedReadingService.java | 4 ++-- .../dexdrip/Services/SnoozeOnNotificationDismissService.java | 4 ++-- app/src/main/res/xml/pref_notifications.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Services/MissedReadingService.java b/app/src/main/java/com/eveningoutpost/dexdrip/Services/MissedReadingService.java index f5d97ca78f..7e55503a02 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Services/MissedReadingService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Services/MissedReadingService.java @@ -149,8 +149,8 @@ static public int readPerfsInt(SharedPreferences prefs, String name, int default static public long getOtherAlertReraiseSec(Context context) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - boolean disableAlertsReraise = prefs.getBoolean("disable_alerts_reraise", false); - if(disableAlertsReraise) { + boolean enableAlertsReraise = prefs.getBoolean("enable_alerts_reraise", false); + if(enableAlertsReraise) { return readPerfsInt(prefs, "other_alerts_reraise_sec", 60); } else { return 60 * readPerfsInt(prefs, "other_alerts_snooze", 20); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java b/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java index 2d81612791..f6e3913707 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java @@ -41,8 +41,8 @@ protected void onHandleIntent(Intent intent) { alertType.equals("bg_predict_alert") || alertType.equals("persistent_high_alert")) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - boolean disableAlertsReraise = prefs.getBoolean("disable_alerts_reraise", false); - if(disableAlertsReraise) { + boolean enableAlertsReraise = prefs.getBoolean("enable_alerts_reraise", false); + if(enableAlertsReraise) { // Only snooze these alert if it the reraise function is enabled. snoozeOtherAlert(alertType); } diff --git a/app/src/main/res/xml/pref_notifications.xml b/app/src/main/res/xml/pref_notifications.xml index 296b9532a3..063fc696d4 100644 --- a/app/src/main/res/xml/pref_notifications.xml +++ b/app/src/main/res/xml/pref_notifications.xml @@ -174,12 +174,12 @@ android:summary="Number of minutes before raising the same alert after snooze." android:title="Alert Snooze" /> Date: Fri, 28 Oct 2016 02:23:08 +0300 Subject: [PATCH 5/9] Add re-raise and snooze options for all alerts. Signed-off-by: Tzachi Dar --- .../dexdrip/MissedReadingActivity.java | 47 +++++++++-- .../Services/MissedReadingService.java | 11 +-- .../SnoozeOnNotificationDismissService.java | 2 +- .../dexdrip/UtilityModels/Notifications.java | 6 +- .../dexdrip/utils/Preferences.java | 15 ---- .../res/layout/activity_missed_readings.xml | 53 ++++++++++++- app/src/main/res/xml/pref_notifications.xml | 78 ++++++++++++++----- 7 files changed, 164 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/MissedReadingActivity.java b/app/src/main/java/com/eveningoutpost/dexdrip/MissedReadingActivity.java index 9f92cab235..9e88c4ef3b 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/MissedReadingActivity.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/MissedReadingActivity.java @@ -27,6 +27,7 @@ public class MissedReadingActivity extends ActivityWithMenu { private CheckBox checkboxEnableAlert; private CheckBox checkboxAllDay; + private CheckBox checkboxEnableReraise; private LinearLayout layoutTimeBetween; private LinearLayout timeInstructions; @@ -35,9 +36,13 @@ public class MissedReadingActivity extends ActivityWithMenu { private TextView timeInstructionsStart; private TextView timeInstructionsEnd; private EditText bgMissedMinutes; + private EditText bgMissedSnoozeMin; + private EditText bgMissedReraiseSec; private TextView viewAlertTime; - private TextView vieSelectTime; + private TextView viewSelectTime; + private TextView viewSnoozeTime; + private TextView viewReraiseTime; private int startHour = 0; @@ -57,14 +62,20 @@ protected void onCreate(Bundle savedInstanceState) { viewTimeEnd = (TextView) findViewById(R.id.missed_reading_time_end); checkboxAllDay = (CheckBox) findViewById(R.id.missed_reading_all_day); checkboxEnableAlert = (CheckBox) findViewById(R.id.missed_reading_enable_alert); + checkboxEnableReraise = (CheckBox) findViewById(R.id.missed_reading_enable_alerts_reraise); layoutTimeBetween = (LinearLayout) findViewById(R.id.missed_reading_time_between); timeInstructions = (LinearLayout) findViewById(R.id.missed_reading_instructions); timeInstructionsStart = (TextView) findViewById(R.id.missed_reading_instructions_start); timeInstructionsEnd = (TextView) findViewById(R.id.missed_reading_instructions_end); bgMissedMinutes = (EditText) findViewById(R.id.missed_reading_bg_minutes); + bgMissedSnoozeMin = (EditText) findViewById(R.id.missed_reading_bg_snooze); + bgMissedReraiseSec = (EditText) findViewById(R.id.missed_reading_reraise_sec); viewAlertTime = (TextView) findViewById(R.id.missed_reading_text_alert_time); - vieSelectTime = (TextView) findViewById(R.id.missed_reading_text_select_time); + viewSelectTime = (TextView) findViewById(R.id.missed_reading_text_select_time); + viewSnoozeTime = (TextView) findViewById(R.id.missed_reading_bg_snooze_text); + viewReraiseTime = (TextView) findViewById(R.id.missed_reading_reraise_sec_text); + // Set the different controls SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); @@ -72,15 +83,20 @@ protected void onCreate(Bundle savedInstanceState) { int endMinutes = prefs.getInt("missed_readings_end", 0); boolean enableAlert = prefs.getBoolean("bg_missed_alerts",false); boolean allDay = prefs.getBoolean("missed_readings_all_day",true); + boolean enableReraise = prefs.getBoolean("bg_missed_alerts_enable_alerts_reraise",false); - checkboxEnableAlert.setChecked(enableAlert); checkboxAllDay.setChecked(allDay); + checkboxEnableAlert.setChecked(enableAlert); + checkboxEnableReraise.setChecked(enableReraise); startHour = AlertType.time2Hours(startMinutes); startMinute = AlertType.time2Minutes(startMinutes); endHour = AlertType.time2Hours(endMinutes); endMinute = AlertType.time2Minutes(endMinutes); bgMissedMinutes.setText(prefs.getString("bg_missed_minutes", "30")); + int defaultSnooze = MissedReadingService.readPerfsInt(prefs, "other_alerts_snooze", 20); + bgMissedSnoozeMin.setText(prefs.getString("bg_missed_alerts_snooze", "" + defaultSnooze)); + bgMissedReraiseSec.setText(prefs.getString("bg_missed_alerts_reraise_sec", "60")); addListenerOnButtons(); enableAllControls(); @@ -94,9 +110,12 @@ public void onDestroy() { prefs.edit().putInt("missed_readings_start", AlertType.toTime(startHour, startMinute)).apply(); prefs.edit().putInt("missed_readings_end", AlertType.toTime(endHour, endMinute)).apply(); prefs.edit().putString("bg_missed_minutes", bgMissedMinutes.getText().toString()).apply(); + prefs.edit().putString("bg_missed_alerts_snooze", bgMissedSnoozeMin.getText().toString()).apply(); + prefs.edit().putString("bg_missed_alerts_reraise_sec", bgMissedReraiseSec.getText().toString()).apply(); prefs.edit().putBoolean("bg_missed_alerts", checkboxEnableAlert.isChecked()).apply(); prefs.edit().putBoolean("missed_readings_all_day", checkboxAllDay.isChecked()).apply(); + prefs.edit().putBoolean("bg_missed_alerts_enable_alerts_reraise", checkboxEnableReraise.isChecked()).apply(); context.startService(new Intent(context, MissedReadingService.class)); } @@ -110,9 +129,14 @@ void EnableControls(boolean enabled) { layoutTimeBetween.setEnabled(enabled); timeInstructions.setEnabled(enabled); checkboxAllDay.setEnabled(enabled); + checkboxEnableReraise.setEnabled(enabled); bgMissedMinutes.setEnabled(enabled); + bgMissedSnoozeMin.setEnabled(enabled); + bgMissedReraiseSec.setEnabled(enabled); viewAlertTime.setEnabled(enabled); - vieSelectTime.setEnabled(enabled); + viewSelectTime.setEnabled(enabled); + viewSnoozeTime.setEnabled(enabled); + viewReraiseTime.setEnabled(enabled); } void enableAllControls() { @@ -129,6 +153,10 @@ void enableAllControls() { } else { setTimeRanges(); } + + boolean enableReraise = checkboxEnableReraise.isChecked(); + bgMissedReraiseSec.setEnabled(enableReraise); + } @@ -141,13 +169,22 @@ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { enableAllControls(); } }); - + checkboxEnableAlert.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { // @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { enableAllControls(); } }); + + checkboxEnableReraise.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + // @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + enableAllControls(); + } + }); + + View.OnClickListener startTimeListener = new View.OnClickListener() { @Override diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Services/MissedReadingService.java b/app/src/main/java/com/eveningoutpost/dexdrip/Services/MissedReadingService.java index 7e55503a02..f7004b2ea6 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Services/MissedReadingService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Services/MissedReadingService.java @@ -104,7 +104,7 @@ private void checkBackAfterSnoozeTime(Context context, long now) { if(userNotification == null) { // No active alert exists, should not happen, we have just created it. Log.wtf(TAG, "No active alert exists."); - setAlarm(getOtherAlertReraiseSec(context) * 1000, false); + setAlarm(getOtherAlertReraiseSec(context, "bg_missed_alerts") * 1000, false); } else { // we have an alert that should be re-raised on userNotification.timestamp long alarmIn = (long)userNotification.timestamp - now; @@ -147,13 +147,14 @@ static public int readPerfsInt(SharedPreferences prefs, String name, int default } } - static public long getOtherAlertReraiseSec(Context context) { + static public long getOtherAlertReraiseSec(Context context, String alertName) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - boolean enableAlertsReraise = prefs.getBoolean("enable_alerts_reraise", false); + boolean enableAlertsReraise = prefs.getBoolean(alertName + "_enable_alerts_reraise" , false); if(enableAlertsReraise) { - return readPerfsInt(prefs, "other_alerts_reraise_sec", 60); + return readPerfsInt(prefs, alertName + "_reraise_sec", 60); } else { - return 60 * readPerfsInt(prefs, "other_alerts_snooze", 20); + int defaultSnooze = readPerfsInt(prefs, "other_alerts_snooze", 20); + return 60 * readPerfsInt(prefs, alertName + "_snooze", defaultSnooze); } } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java b/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java index f6e3913707..c0aece37d5 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java @@ -41,7 +41,7 @@ protected void onHandleIntent(Intent intent) { alertType.equals("bg_predict_alert") || alertType.equals("persistent_high_alert")) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - boolean enableAlertsReraise = prefs.getBoolean("enable_alerts_reraise", false); + boolean enableAlertsReraise = prefs.getBoolean(alertType + "_enable_alerts_reraise", false); if(enableAlertsReraise) { // Only snooze these alert if it the reraise function is enabled. snoozeOtherAlert(alertType); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java index ef460db97b..479a3fbfb0 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java @@ -362,7 +362,7 @@ private long calcuatleArmTimeUnclearalert(Context ctx, long now, boolean unclear if (userNotification == null) { // An alert should have already being played, how is this NULL. Log.wtf(TAG, "No active alert exists."); - wakeTimeUnclear = now + MissedReadingService.getOtherAlertReraiseSec(ctx) * 1000; + wakeTimeUnclear = now + MissedReadingService.getOtherAlertReraiseSec(ctx, "bg_unclear_readings_alert") * 1000; } else { // This alert is snoozed // reminder - userNotification.timestamp is the time that the alert should be played again @@ -719,12 +719,12 @@ private void extraCalibrationRequest() { } public static void bgUnclearAlert(Context context) { - long otherAlertReraiseSec = MissedReadingService.getOtherAlertReraiseSec(context); + long otherAlertReraiseSec = MissedReadingService.getOtherAlertReraiseSec(context, "bg_unclear_readings_alert"); OtherAlert(context, "bg_unclear_readings_alert", "Unclear Sensor Readings" + " (@" + JoH.hourMinuteString() + ")", uncleanAlertNotificationId, otherAlertReraiseSec); } public static void bgMissedAlert(Context context) { - long otherAlertReraiseSec = MissedReadingService.getOtherAlertReraiseSec(context); + long otherAlertReraiseSec = MissedReadingService.getOtherAlertReraiseSec(context, "bg_missed_alerts"); OtherAlert(context, "bg_missed_alerts", "BG Readings Missed" + " (@" + JoH.hourMinuteString() + ")", missedAlertNotificationId, otherAlertReraiseSec); } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/utils/Preferences.java b/app/src/main/java/com/eveningoutpost/dexdrip/utils/Preferences.java index f71a2660da..0bd564dc8f 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/utils/Preferences.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/utils/Preferences.java @@ -545,7 +545,6 @@ public void onCreate(Bundle savedInstanceState) { bindPreferenceSummaryToValue(findPreference("falling_bg_val")); bindPreferenceSummaryToValue(findPreference("rising_bg_val")); bindPreferenceSummaryToValue(findPreference("other_alerts_sound")); - bindPreferenceSummaryToValueAndEnsureNumeric(findPreference("other_alerts_snooze")); addPreferencesFromResource(R.xml.pref_data_source); @@ -1603,20 +1602,6 @@ public void onClick(DialogInterface dialog, int which) { } - private static Preference.OnPreferenceChangeListener sBgMissedAlertsHandler = new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - Context context = preference.getContext(); - context.startService(new Intent(context, MissedReadingService.class)); - return true; - } - }; - - - private void bindBgMissedAlertsListener() { - findPreference("other_alerts_snooze").setOnPreferenceChangeListener(sBgMissedAlertsHandler); - } - // Will update the widget if any setting relevant to the widget gets changed. private static class WidgetListener implements Preference.OnPreferenceChangeListener { diff --git a/app/src/main/res/layout/activity_missed_readings.xml b/app/src/main/res/layout/activity_missed_readings.xml index b3a6903c29..7cb2b94605 100644 --- a/app/src/main/res/layout/activity_missed_readings.xml +++ b/app/src/main/res/layout/activity_missed_readings.xml @@ -74,7 +74,58 @@ android:layout_gravity="center" android:gravity="right" /> - + + + + + + + + + + @@ -167,24 +187,6 @@ android:defaultValue="false" android:key="other_alerts_override_silent" android:title="Override Silent mode on these alerts" /> - - - + + + + + + Date: Mon, 31 Oct 2016 01:09:25 +0200 Subject: [PATCH 6/9] Removed persistent high and predicted low alerts from code. Signed-off-by: Tzachi Dar --- .../SnoozeOnNotificationDismissService.java | 11 +++-- .../dexdrip/UtilityModels/Notifications.java | 23 ++++++----- app/src/main/res/xml/pref_notifications.xml | 41 ------------------- 3 files changed, 21 insertions(+), 54 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java b/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java index c0aece37d5..4a492900c5 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Services/SnoozeOnNotificationDismissService.java @@ -37,9 +37,7 @@ protected void onHandleIntent(Intent intent) { return; } if(alertType.equals("bg_unclear_readings_alert") || - alertType.equals("bg_missed_alerts") || - alertType.equals("bg_predict_alert") || - alertType.equals("persistent_high_alert")) { + alertType.equals("bg_missed_alerts")) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); boolean enableAlertsReraise = prefs.getBoolean(alertType + "_enable_alerts_reraise", false); if(enableAlertsReraise) { @@ -48,6 +46,13 @@ protected void onHandleIntent(Intent intent) { } return; } + + if(alertType.equals("bg_predict_alert") || + alertType.equals("persistent_high_alert")) { + Log.wtf(TAG, "SnoozeOnNotificationDismissService called for unsupported type!!! source = " + alertType); + + } + Log.e(TAG, "SnoozeOnNotificationDismissService called for unknown source = " + alertType); } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java index 479a3fbfb0..35bdbca8b2 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java @@ -720,12 +720,12 @@ private void extraCalibrationRequest() { public static void bgUnclearAlert(Context context) { long otherAlertReraiseSec = MissedReadingService.getOtherAlertReraiseSec(context, "bg_unclear_readings_alert"); - OtherAlert(context, "bg_unclear_readings_alert", "Unclear Sensor Readings" + " (@" + JoH.hourMinuteString() + ")", uncleanAlertNotificationId, otherAlertReraiseSec); + OtherAlert(context, "bg_unclear_readings_alert", "Unclear Sensor Readings" + " (@" + JoH.hourMinuteString() + ")", uncleanAlertNotificationId, true, otherAlertReraiseSec); } public static void bgMissedAlert(Context context) { long otherAlertReraiseSec = MissedReadingService.getOtherAlertReraiseSec(context, "bg_missed_alerts"); - OtherAlert(context, "bg_missed_alerts", "BG Readings Missed" + " (@" + JoH.hourMinuteString() + ")", missedAlertNotificationId, otherAlertReraiseSec); + OtherAlert(context, "bg_missed_alerts", "BG Readings Missed" + " (@" + JoH.hourMinuteString() + ")", missedAlertNotificationId, true, otherAlertReraiseSec); } public static void RisingAlert(Context context, boolean on) { @@ -739,7 +739,7 @@ public static void lowPredictAlert(Context context, boolean on, String msg) { final String type = "bg_predict_alert"; if (on) { if ((Home.getPreferencesLong("alerts_disabled_until", 0) < JoH.tsl()) && (Home.getPreferencesLong("low_alerts_disabled_until", 0) < JoH.tsl())) { - OtherAlert(context, type, msg, lowPredictAlertNotificationId, 20); + OtherAlert(context, type, msg, lowPredictAlertNotificationId, false, 20 * 60); } else { Log.ueh(TAG, "Not Low predict alerting due to snooze: " + msg); } @@ -762,7 +762,7 @@ public static void persistentHighAlert(Context context, boolean on, String msg) } if (snooze_time < 1) snooze_time = 1; // not less than 1 minute if (snooze_time > 1440) snooze_time = 1440; // not more than 1 day - OtherAlert(context, type, msg, persistentHighAlertNotificationId, snooze_time); + OtherAlert(context, type, msg, persistentHighAlertNotificationId, false, snooze_time * 60); } else { Log.ueh(TAG, "Not persistent high alerting due to snooze: " + msg); } @@ -776,7 +776,7 @@ public static void persistentHighAlert(Context context, boolean on, String msg) public static void RiseDropAlert(Context context, boolean on, String type, String message, int notificatioId) { if(on) { // This alerts will only happen once. Want to have maxint, but not create overflow. - OtherAlert(context, type, message, notificatioId, Integer.MAX_VALUE / 100000); + OtherAlert(context, type, message, notificatioId, false, Integer.MAX_VALUE / 100000); } else { NotificationManager mNotifyMgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); mNotifyMgr.cancel(notificatioId); @@ -784,7 +784,7 @@ public static void RiseDropAlert(Context context, boolean on, String type, Strin } } - private static void OtherAlert(Context context, String type, String message, int notificatioId, long reraiseSec) { + private static void OtherAlert(Context context, String type, String message, int notificatioId, boolean addDeleteIntent, long reraiseSec) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); String otherAlertsSound = prefs.getString(type+"_sound",prefs.getString("other_alerts_sound", "content://settings/system/notification_sound")); Boolean otherAlertsOverrideSilent = prefs.getBoolean("other_alerts_override_silent", false); @@ -802,16 +802,19 @@ private static void OtherAlert(Context context, String type, String message, int } UserNotification.create(message, type, new Date().getTime() + reraiseSec * 1000); - Intent deleteIntent = new Intent(context, SnoozeOnNotificationDismissService.class); - deleteIntent.putExtra("alertType", type); + Intent intent = new Intent(context, Home.class); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context) .setSmallIcon(R.drawable.ic_action_communication_invert_colors_on) .setContentTitle(message) .setContentText(message) - .setContentIntent(PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)) - .setDeleteIntent(PendingIntent.getService(context, 0, deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT)); + .setContentIntent(PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); + if (addDeleteIntent) { + Intent deleteIntent = new Intent(context, SnoozeOnNotificationDismissService.class); + deleteIntent.putExtra("alertType", type); + mBuilder.setDeleteIntent(PendingIntent.getService(context, 0, deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT)); + } mBuilder.setVibrate(vibratePattern); mBuilder.setLights(0xff00ff00, 300, 1000); if (AlertPlayer.notSilencedDueToCall()) { diff --git a/app/src/main/res/xml/pref_notifications.xml b/app/src/main/res/xml/pref_notifications.xml index d752bf4b6a..e2efd87f89 100644 --- a/app/src/main/res/xml/pref_notifications.xml +++ b/app/src/main/res/xml/pref_notifications.xml @@ -222,27 +222,6 @@ android:showSilent="true" android:summary="@string/choose_sound_used_for_persistent_high_alarm" android:title="@string/persistent_high_sound" /> - - - - - - - Date: Mon, 31 Oct 2016 02:07:07 +0200 Subject: [PATCH 7/9] Make sure to remove the unclear alert once it is not needed. Signed-off-by: Tzachi Dar --- .../com/eveningoutpost/dexdrip/Models/BgReading.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java b/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java index 9274aa8e8a..79f0f547ac 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java @@ -1274,12 +1274,19 @@ private static boolean checkForDropRiseAllert(float MaxSpeed, boolean drop) { return true; } + // Make sure that this function either sets the alert or removes it. public static boolean getAndRaiseUnclearReading(Context context) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + if(prefs.getLong("alerts_disabled_until", 0) > new Date().getTime()){ + Log.d("NOTIFICATIONS", "getAndRaiseUnclearReading Notifications are currently disabled!!"); + UserNotification.DeleteNotificationByType("bg_unclear_readings_alert"); + return false; + } Boolean bg_unclear_readings_alerts = prefs.getBoolean("bg_unclear_readings_alerts", false); if (!bg_unclear_readings_alerts || (!DexCollectionType.hasFiltered())) { Log.d(TAG_ALERT, "getUnclearReading returned false since feature is disabled"); + UserNotification.DeleteNotificationByType("bg_unclear_readings_alert"); return false; } Long UnclearTimeSetting = Long.parseLong(prefs.getString("bg_unclear_readings_minutes", "90")) * 60000; @@ -1291,6 +1298,9 @@ public static boolean getAndRaiseUnclearReading(Context context) { Notifications.bgUnclearAlert(context); return true; } + + UserNotification.DeleteNotificationByType("bg_unclear_readings_alert"); + if (UnclearTime > 0 ) { Log.d(TAG_ALERT, "We are in an clear state, but not for too long. Alerts are disabled"); return true; From 099776440796a22c5015edae5681132c46f19477 Mon Sep 17 00:00:00 2001 From: Tzachi Dar Date: Mon, 31 Oct 2016 02:11:42 +0200 Subject: [PATCH 8/9] Save the correct timestamp for all notifications. Signed-off-by: Tzachi Dar --- .../com/eveningoutpost/dexdrip/Models/UserNotification.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Models/UserNotification.java b/app/src/main/java/com/eveningoutpost/dexdrip/Models/UserNotification.java index 8041d45795..d06d171776 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Models/UserNotification.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Models/UserNotification.java @@ -160,7 +160,7 @@ public static UserNotification create(String message, String type, long timestam userNotification.bg_fall_alert = true; } else { Log.d(TAG,"Saving workaround for: "+type+" "+message); - Home.setPreferencesString("UserNotification:timestamp:" + type, JoH.qs((JoH.ts()))); + Home.setPreferencesString("UserNotification:timestamp:" + type, JoH.qs(timestamp)); Home.setPreferencesString("UserNotification:message:" + type, message); return null; } From a5a69295292b088e9ec3b6c75078aca053d02022 Mon Sep 17 00:00:00 2001 From: Tzachi Dar Date: Mon, 31 Oct 2016 02:13:44 +0200 Subject: [PATCH 9/9] In the case that a unclear sensor alert is not running don't use it for arming calculation. If need to arm "now" wait one second to avoid an infinite loop. --- .../dexdrip/UtilityModels/Notifications.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java index 35bdbca8b2..852e02cfcb 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java @@ -360,9 +360,9 @@ private long calcuatleArmTimeUnclearalert(Context ctx, long now, boolean unclear UserNotification userNotification = UserNotification.GetNotificationByType("bg_unclear_readings_alert"); if (userNotification == null) { - // An alert should have already being played, how is this NULL. - Log.wtf(TAG, "No active alert exists."); - wakeTimeUnclear = now + MissedReadingService.getOtherAlertReraiseSec(ctx, "bg_unclear_readings_alert") * 1000; + // This is the case, that we are in unclear sensor reading, but for small time, so there is no call + Log.i(TAG, "No active alert exists. returning Long.MAX_VALUE"); + return Long.MAX_VALUE; } else { // This alert is snoozed // reminder - userNotification.timestamp is the time that the alert should be played again @@ -446,8 +446,11 @@ private void ArmTimer(Context ctx, boolean unclearAlert) { if(wakeTime < now || wakeTime >= now + 6 * 60000 ) { - Log.e("Notifications" , "ArmTimer recieved a negative time, will fire in 6 minutes"); - wakeTime = now + 6 * 60000; + Log.e("Notifications" , "ArmTimer recieved a negative time, will fire in 6 minutes"); + wakeTime = now + 6 * 60000; + } else if (wakeTime == now) { + Log.e("Notifications", "should arm right now, waiting one more second to avoid infinitue loop"); + wakeTime = now + 1; } AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);