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/Models/AlertType.java b/app/src/main/java/com/eveningoutpost/dexdrip/Models/AlertType.java index 7732537180..ff4a22a204 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; @@ -163,20 +164,7 @@ public static AlertType get_highest_active_alert(Context context, double bg) { 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!!"); - 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); @@ -427,7 +415,6 @@ public static void CreateStaticAlerts() { public static void testAll(Context context) { - 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); 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 923683d225..d70e17068a 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java @@ -1216,11 +1216,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; @@ -1250,11 +1245,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; @@ -1311,18 +1301,38 @@ private static boolean checkForDropRiseAllert(float MaxSpeed, boolean drop) { return true; } - private static boolean IsUnclearTime(Context context) { + // 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) { - 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"); + UserNotification.DeleteNotificationByType("bg_unclear_readings_alert"); + 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; } + + 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; + } + return false; } /* @@ -1338,11 +1348,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/Models/UserNotification.java b/app/src/main/java/com/eveningoutpost/dexdrip/Models/UserNotification.java index 7d86d69627..d06d171776 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; @@ -146,7 +160,7 @@ public static UserNotification create(String message, String type) { 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; } 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..f7004b2ea6 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, "bg_missed_alerts") * 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,16 @@ static public int readPerfsInt(SharedPreferences prefs, String name, int default return defaultValue; } } + + static public long getOtherAlertReraiseSec(Context context, String alertName) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + boolean enableAlertsReraise = prefs.getBoolean(alertName + "_enable_alerts_reraise" , false); + if(enableAlertsReraise) { + return readPerfsInt(prefs, alertName + "_reraise_sec", 60); + } else { + 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 04e2380c55..4a492900c5 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,33 @@ 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")) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + boolean enableAlertsReraise = prefs.getBoolean(alertType + "_enable_alerts_reraise", false); + if(enableAlertsReraise) { + // Only snooze these alert if it the reraise function is enabled. + snoozeOtherAlert(alertType); + } + 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); + } + + private void snoozeBgAlert() { AlertType activeBgAlert = ActiveBgAlert.alertTypegetOnly(); int snooze = 30; @@ -42,4 +70,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 19db3753eb..6bdcd7873f 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java @@ -44,7 +44,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; @@ -53,6 +53,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; @@ -120,6 +121,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); + boolean unclearReading = false; try { Log.d("Notifications", "Running Notifications Intent Service"); final Context context = getApplicationContext(); @@ -129,8 +131,8 @@ protected void onHandleIntent(Intent intent) { } ReadPerfs(context); - notificationSetter(context); - ArmTimer(context); + unclearReading = notificationSetter(context); + ArmTimer(context, unclearReading); context.startService(new Intent(context, MissedReadingService.class)); @@ -204,6 +206,7 @@ private void FileBasedNotifications(Context context) { // TODO: tzachi what is the time of this last bgReading + // TODO Tzachi: remove sensor != null once sensor data code is checked in. // 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. @@ -297,7 +300,8 @@ boolean trendingToAlertEnd(Context context, Boolean newAlert, AlertType Alert) { * ***************************************************************************************************************** */ - private void notificationSetter(Context context) { + // 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); @@ -308,11 +312,19 @@ private void notificationSetter(Context context) { } if (prefs.getLong("alerts_disabled_until", 0) > new Date().getTime()) { Log.d("NOTIFICATIONS", "Notifications are currently disabled!!"); - return; + return false; } - FileBasedNotifications(context); - BgReading.checkForDropAllert(context); - BgReading.checkForRisingAllert(context); + + boolean unclearReading = BgReading.getAndRaiseUnclearReading(context); + + if (unclearReading) { + AlertPlayer.getPlayer().stopAlert(context, false, true); + } else { + FileBasedNotifications(context); + BgReading.checkForDropAllert(context); + BgReading.checkForRisingAllert(context); + } + // TODO: Add this alerts as well to depend on unclear sensor reading. BgReading.checkForPersistentHigh(); evaluateLowPredictionAlarm(); reportNoiseChanges(); @@ -324,10 +336,10 @@ private void notificationSetter(Context context) { 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); @@ -360,28 +372,72 @@ private void notificationSetter(Context context) { } else { clearAllCalibrationNotifications(); } + return unclearReading; } - 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) { + // 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 + 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 @@ -403,24 +459,22 @@ 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 ) { - Log.e("Notifications" , "ArmTimer recieved a negative time, will fire in 6 minutes"); - wakeTime = now + 6 * 60000; + if(wakeTime < now || 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); @@ -669,7 +723,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); @@ -681,7 +735,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); @@ -693,7 +747,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); @@ -702,15 +756,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, "bg_unclear_readings_alert"); + OtherAlert(context, "bg_unclear_readings_alert", "Unclear Sensor Readings" + " (@" + JoH.hourMinuteString() + ")", uncleanAlertNotificationId, true, 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, "bg_missed_alerts"); + OtherAlert(context, "bg_missed_alerts", "BG Readings Missed" + " (@" + JoH.hourMinuteString() + ")", missedAlertNotificationId, true, otherAlertReraiseSec); } public static void RisingAlert(Context context, boolean on) { @@ -724,7 +776,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); } @@ -747,7 +799,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); } @@ -761,7 +813,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); @@ -769,14 +821,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, 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); - 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(); @@ -785,7 +837,9 @@ 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 intent = new Intent(context, Home.class); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context) @@ -793,6 +847,11 @@ private static void OtherAlert(Context context, String type, String message, int .setContentTitle(message) .setContentText(message) .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/java/com/eveningoutpost/dexdrip/utils/Preferences.java b/app/src/main/java/com/eveningoutpost/dexdrip/utils/Preferences.java index 9701f7df9b..cc4fb90eb9 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); @@ -1607,20 +1606,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,12 +187,6 @@ android:defaultValue="false" android:key="other_alerts_override_silent" android:title="Override Silent mode on these alerts" /> - -