diff --git a/HypoAlarm/HypoAlarm-HypoAlarm.iml b/HypoAlarm/HypoAlarm-HypoAlarm.iml
index 70b00c6..978d53d 100644
--- a/HypoAlarm/HypoAlarm-HypoAlarm.iml
+++ b/HypoAlarm/HypoAlarm-HypoAlarm.iml
@@ -8,10 +8,11 @@
-
-
-
-
+
+
+
+
+
@@ -21,21 +22,26 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/AlarmAlertActivity.java b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/AlarmAlertActivity.java
index 56cafd9..b558b0f 100644
--- a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/AlarmAlertActivity.java
+++ b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/AlarmAlertActivity.java
@@ -11,7 +11,7 @@ import android.view.WindowManager;
import net.frakbot.glowpadbackport.GlowPadView;
public class AlarmAlertActivity extends Activity {
- public static Activity alertActivity;
+ public static Activity alertActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
diff --git a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/AlarmChangeReceiver.java b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/AlarmChangeReceiver.java
index 7a9589a..9aab468 100644
--- a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/AlarmChangeReceiver.java
+++ b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/AlarmChangeReceiver.java
@@ -16,10 +16,10 @@ public class AlarmChangeReceiver extends BroadcastReceiver {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED") ||
intent.getAction().equals("android.intent.action.TIMEZONE_CHANGED") ||
intent.getAction().equals("android.intent.action.TIME_SET")) {
- String alarmTimeStr = sharedPref.getString(context.getString(R.string.AlarmTimePref), null);
+ String alarmTimeStr = sharedPref.getString(context.getString(R.string.AlarmTimePref), MainActivity.defaultTimeStr);
Calendar cal = MainActivity.TimeStringToCalendar(alarmTimeStr);
Log.d("AlarmChangeReceiver", intent.getAction() + ": resetting alarm for " + MainActivity.debugDate(cal));
- MainActivity.resetAlarm(context, cal);
+ MainActivity.setAlarm(context, cal);
}
}
}
diff --git a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/AlarmNotify.java b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/AlarmNotify.java
index aed664d..e1bf047 100644
--- a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/AlarmNotify.java
+++ b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/AlarmNotify.java
@@ -42,7 +42,7 @@ public class AlarmNotify extends Service {
Log.d("AlarmNotify", "Notification started.");
//final String phoneNumber = sharedPref.getString(getString(R.string.PhoneNumberPref), null);
- final int gracePeriod = sharedPref.getInt(getString(R.string.GracePeriodPref), 60);
+ final int gracePeriod = sharedPref.getInt(getString(R.string.GracePeriodPref), MainActivity.defaultGracePeriod);
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_grey);
final NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
diff --git a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/AlarmService.java b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/AlarmService.java
index c6058ce..0d96458 100644
--- a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/AlarmService.java
+++ b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/AlarmService.java
@@ -1,5 +1,6 @@
package za.org.treehouse.hypoalarm;
+import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
@@ -18,7 +19,7 @@ import java.util.Calendar;
public class AlarmService extends Service {
private static final int SNOOZE_TIME = 1000*60*5; // Snooze for 5 minutes if need be
- private static final int ALERT_LIFE = 1000*60*1; // 2 minutes
+ private static final int ALERT_LIFE = 1000*60*2; // 2 minutes
private static PowerManager.WakeLock wl;
private static AlarmManager alarmManager;
private static Intent alarmServiceIntent, alertActivityIntent, notifyIntent;
@@ -36,13 +37,15 @@ public class AlarmService extends Service {
// Ensure that CPU runs while the service is running, so we don't miss an alert or snooze
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AlarmService");
+ // TODO: wake lock?
//wl.acquire();
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
+
}
@Override
public void onDestroy() {
- Log.d("AlarmService", "Destroying alarm");
+ Log.d("AlarmService", "Destroying alarm (alarmStarted: " + alarmStarted + ")");
if (alarmStarted) {
stopAlert(getApplicationContext());
alarmStarted = false;
@@ -56,9 +59,9 @@ public class AlarmService extends Service {
public int onStartCommand(Intent intent, int flags, int startId) {
alarmServiceIntent = intent;
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
- final Boolean alarmActive = sharedPref.getBoolean(getString(R.string.AlarmActivePref), true);
- final int gracePeriod = sharedPref.getInt(getString(R.string.GracePeriodPref), 60);
- final String alarmTimeStr = sharedPref.getString(getString(R.string.AlarmTimePref), null);
+ final Boolean alarmActive = sharedPref.getBoolean(getString(R.string.AlarmActivePref), MainActivity.defaultActive);
+ final String alarmTimeStr = sharedPref.getString(getString(R.string.AlarmTimePref), MainActivity.defaultTimeStr);
+ final int gracePeriod = sharedPref.getInt(getString(R.string.GracePeriodPref), MainActivity.defaultGracePeriod);
if (alarmActive) {
// Cancel the pre-alarm notification, if it exists
@@ -79,23 +82,22 @@ public class AlarmService extends Service {
// if nothing else happens, assume the alert was ignored.
alarmStatus = ALARM_RUNNING;
- // If dialing, active in a phone call, or on hold, don't bother with the alarm, just reset it for tomorrow
+ // Reset for tomorrow; as of API 19, setRepeating() is inexact, so we use setExact()
+ Calendar cal = MainActivity.TimeStringToCalendar(alarmTimeStr);
+ // Advance the calendar to tomorrow (and make sure the calendar hasn't already been advanced)
+ if (cal.before(Calendar.getInstance())) {
+ cal.add(Calendar.DAY_OF_MONTH, 1);
+ }
+
+ MainActivity.setAlarm(getApplicationContext(), cal);
+ Log.d("AlarmService", "Alarm reset for next period");
+
+ // If dialing, active in a phone call, or on hold, don't bother with today's alarm, just reset it for tomorrow
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyManager.getCallState() != TelephonyManager.CALL_STATE_OFFHOOK) {
- // Set a grace period alarm to send SMS
- Calendar graceCal = Calendar.getInstance();
- graceCal.set(Calendar.SECOND, 0);
- graceCal.add(Calendar.MINUTE, gracePeriod);
- Intent graceIntent = new Intent(this, GraceReceiver.class);
- PendingIntent gracePendingIntent = PendingIntent.getBroadcast(this, MainActivity.GRACE_REQUEST, graceIntent, 0);
- alarmManager.cancel(gracePendingIntent);
- if (Build.VERSION.SDK_INT >= 19) {
- alarmManager.setExact(AlarmManager.RTC_WAKEUP, graceCal.getTimeInMillis(), gracePendingIntent);
- } else {
- alarmManager.set(AlarmManager.RTC_WAKEUP, graceCal.getTimeInMillis(), gracePendingIntent);
- }
- Log.d("AlarmService", "Setting grace alarm for " + MainActivity.debugDate(graceCal));
+ // set grace period, which sends the text message upon firing
+ MainActivity.setGraceAlarm(getApplicationContext());
// Calculate when the grace period (converted from minutes to milliseconds) ends
graceEndTime = System.currentTimeMillis() + (gracePeriod * 60 * 1000);
@@ -103,22 +105,6 @@ public class AlarmService extends Service {
// Allow user to acknowledge alarm and cancel grace alarm
startAlert(this);
}
-
- // Reset for tomorrow; as of API 19, setRepeating() is inexact, so we use setExact()
- Calendar cal = MainActivity.TimeStringToCalendar(alarmTimeStr);
- // Advance the calendar to tomorrow if it's in the past
- if (cal.before(Calendar.getInstance())) {
- cal.add(Calendar.DAY_OF_MONTH, 1);
- }
-
- PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(this, MainActivity.ALARM_REQUEST, intent, 0);
- alarmManager.cancel(alarmPendingIntent);
- if (Build.VERSION.SDK_INT >= 19) {
- alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), alarmPendingIntent);
- } else {
- alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), alarmPendingIntent);
- }
- Log.d("AlarmService", "Resetting alarm for " + MainActivity.debugDate(cal));
}
return super.onStartCommand(intent, flags, startId);
}
@@ -134,12 +120,13 @@ public class AlarmService extends Service {
// Turn off the alert activity after a period, and switch to a notification
new Handler().postDelayed(new Runnable() {
public void run() {
+ Log.d("AlarmService", "Closing alert activity, status is " + alarmStatus);
// Close the dialogue and switch to notification
// if the Activity has not been closed by the user
// (that is, snoozeAlert and dismissAlert have not been called)
if (alarmStatus.contentEquals(ALARM_DISMISSED) ||
alarmStatus.contentEquals(ALARM_SNOOZED)) {
- return;
+ // Do nothing
// Stop if we've already run the snooze alert
} else if (alarmStatus.contentEquals(ALARM_SNOOZE_RUNNING)) {
alarmStatus = ALARM_IGNORED;
@@ -156,7 +143,9 @@ public class AlarmService extends Service {
Log.d("AlarmService", "Stopping alert; status is " + alarmStatus);
if (alarmStarted) {
AlarmKlaxon.stop(context);
- AlarmAlertActivity.alertActivity.finish();
+ if (AlarmAlertActivity.alertActivity != null) {
+ AlarmAlertActivity.alertActivity.finish();
+ }
if (!alarmStatus.contentEquals(ALARM_DISMISSED)) {
context.startService(notifyIntent);
}
@@ -168,9 +157,7 @@ public class AlarmService extends Service {
alarmStatus = ALARM_DISMISSED;
// Cancel the graceAlarm
- Intent graceIntent = new Intent(context, GraceReceiver.class);
- PendingIntent gracePendingIntent = PendingIntent.getBroadcast(context, MainActivity.GRACE_REQUEST, graceIntent, 0);
- alarmManager.cancel(gracePendingIntent);
+ MainActivity.cancelGraceAlarm(context);
// Stop this service, along with the alert and all notifications
context.stopService(alarmServiceIntent);
@@ -208,6 +195,7 @@ public class AlarmService extends Service {
Log.d("AlarmService", "Setting alarm status to " + status);
alarmStatus = status;
}
+
@Override
public IBinder onBind(Intent intent) {
return null;
diff --git a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/CancelAlarmReceiver.java b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/CancelAlarmReceiver.java
index ea097e1..29e5793 100644
--- a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/CancelAlarmReceiver.java
+++ b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/CancelAlarmReceiver.java
@@ -17,30 +17,25 @@ public class CancelAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
- String alarmTimeStr = sharedPref.getString(context.getString(R.string.AlarmTimePref), null);
+ String alarmTimeStr = sharedPref.getString(context.getString(R.string.AlarmTimePref), MainActivity.defaultTimeStr);
- AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- Intent alarmIntent = new Intent(context, AlarmReceiver.class);
- PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(context, MainActivity.ALARM_REQUEST, alarmIntent, 0);
- alarmManager.cancel(alarmPendingIntent);
- Log.d("CancelAlarmReceiver", "Cancelled grace alarm");
+ // Cancel alarm. This isn't technically necessary, as it'll happen in setAlarm
+ MainActivity.cancelAlarm(context);
+
+ // Reset for tomorrow. setAlarm will also advance the day, but
+ // make it explicit here.
+ Calendar cal = MainActivity.TimeStringToCalendar(alarmTimeStr);
+ cal.add(Calendar.DAY_OF_MONTH, 1);
// Reset alarm for tomorrow
-
- // Reset for tomorrow; as of API 19, setRepeating() is inexact, so we use setExact()
- Calendar cal = MainActivity.TimeStringToCalendar(alarmTimeStr);
- // Set for tomorrow
- cal.add(Calendar.DAY_OF_MONTH, 1);
- if (Build.VERSION.SDK_INT >= 19) {
- alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), alarmPendingIntent);
- } else {
- alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), alarmPendingIntent);
- }
- Log.d("CancelAlarmReceiver", "Resetting alarm for " + MainActivity.debugDate(cal));
+ MainActivity.setAlarm(context, cal);
// Display toast
Toast.makeText(context, context.getString(R.string.alarmCancelToast), Toast.LENGTH_LONG).show();
+ // Stop any snoozed/existing alarms that may have started
+ context.stopService(new Intent(context, AlarmService.class));
+
// Remove notification
context.stopService(new Intent(context, PreAlarmNotify.class));
diff --git a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/CancelGraceReceiver.java b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/CancelGraceReceiver.java
index ba8dd13..0963b21 100644
--- a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/CancelGraceReceiver.java
+++ b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/CancelGraceReceiver.java
@@ -11,20 +11,13 @@ import android.widget.Toast;
public class CancelGraceReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
- AlarmManager graceManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- Intent graceIntent = new Intent(context, GraceReceiver.class);
- PendingIntent gracePendingIntent = PendingIntent.getBroadcast(context, MainActivity.GRACE_REQUEST, graceIntent, 0);
- graceManager.cancel(gracePendingIntent);
- Log.d("CancelGraceReceiver", "Cancelled grace alarm");
-
// Ensure that any snoozes that are pending never happen.
AlarmService.setAlarmStatus(AlarmService.ALARM_DISMISSED);
context.stopService(new Intent(context, AlarmService.class));
- // Remove notification
- context.stopService(new Intent(context, AlarmNotify.class));
+ MainActivity.cancelGraceAlarm(context);
// Display toast
- Toast.makeText(context, context.getString(R.string.alarmCancelToast), Toast.LENGTH_LONG).show();
+ Toast.makeText(context, context.getString(R.string.graceCancelToast), Toast.LENGTH_LONG).show();
}
}
\ No newline at end of file
diff --git a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/GraceReceiver.java b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/GraceReceiver.java
index 54d83f5..69f4081 100644
--- a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/GraceReceiver.java
+++ b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/GraceReceiver.java
@@ -30,7 +30,7 @@ public class GraceReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
- Boolean alarmActive = sharedPref.getBoolean(context.getString(R.string.AlarmActivePref), true);
+ Boolean alarmActive = sharedPref.getBoolean(context.getString(R.string.AlarmActivePref), MainActivity.defaultActive);
phoneNumber = sharedPref.getString(context.getString(R.string.PhoneNumberPref), null);
message = sharedPref.getString(context.getString(R.string.MessagePref), context.getString(R.string.defaultMessage));
@@ -70,17 +70,23 @@ public class GraceReceiver extends BroadcastReceiver {
);
locationClient.connect();
} else {
- Log.e("GraceReceiver", "No Google Play Services. Sending text message anyway.");
+ Log.e("GraceReceiver", "Google Play Services is not available. Sending text message anyway.");
sendText(context);
}
}
}
private void sendText(Context context) {
SmsManager sms = SmsManager.getDefault();
- if (!MainActivity.HYPOALARM_DEBUG) {
- sms.sendTextMessage(phoneNumber, null, message, null, null);
+ if (phoneNumber == null || phoneNumber.isEmpty()) {
+ message = "You have not specified a phone number. No text message will be sent.";
+ Toast.makeText(context, message, Toast.LENGTH_LONG).show();
+ Log.e("GraceReceiver", "ERROR: " + message);
+ } else {
+ if (!MainActivity.HYPOALARM_DEBUG) {
+ sms.sendTextMessage(phoneNumber, null, message, null, null);
+ }
+ Toast.makeText(context, message, Toast.LENGTH_LONG).show();
+ Log.d("GraceReceiver", "Sending sms to " + phoneNumber + " with message: " + message);
}
- Toast.makeText(context, message, Toast.LENGTH_LONG).show();
- Log.d("GraceReceiver", "Sending sms to " + phoneNumber + " with message: " + message);
}
}
diff --git a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/MainActivity.java b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/MainActivity.java
index 808f6c6..c7d96d6 100644
--- a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/MainActivity.java
+++ b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/MainActivity.java
@@ -1,5 +1,6 @@
package za.org.treehouse.hypoalarm;
+import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -65,6 +66,9 @@ public class MainActivity extends ActionBarActivity {
public static final int CANCEL_ALARM_REQUEST = 5;
public static final int PHONE_NUMBER_REQUEST = 6;
public static final int RINGTONE_REQUEST = 7;
+ public static final String defaultTimeStr = "09:00";
+ public static final int defaultGracePeriod = 60;
+ public static final Boolean defaultActive = true;
public static final Boolean HYPOALARM_DEBUG = false;
@@ -98,7 +102,6 @@ public class MainActivity extends ActionBarActivity {
super.onStart();
// Set alarm time
- final String defaultTimeStr = "09:00";
String alarmTimeStr = verifyTimeString(sharedPref.getString(getString(R.string.AlarmTimePref), defaultTimeStr));
final Button alarmTimeButton = (Button) getActivity().findViewById(R.id.alarm_time);
@@ -119,7 +122,7 @@ public class MainActivity extends ActionBarActivity {
});
// Allow alarm to activate
- Boolean alarmActive = sharedPref.getBoolean(getString(R.string.AlarmActivePref), true);
+ Boolean alarmActive = sharedPref.getBoolean(getString(R.string.AlarmActivePref), defaultActive);
final CompoundButton alarmActiveSwitch = (CompoundButton) getActivity().findViewById(R.id.alarm_active_switch);
alarmActiveSwitch.setChecked(alarmActive);
alarmActiveSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@@ -130,23 +133,24 @@ public class MainActivity extends ActionBarActivity {
editor.commit();
if (!active) {
+ // Stop any snoozed alerts, and cancel any alarms
+ getActivity().stopService(new Intent(getActivity(), AlarmService.class));
cancelAllAlarms(getActivity());
Toast.makeText(getActivity(), getString(R.string.alarmCancelled), Toast.LENGTH_SHORT).show();
} else {
String alarmTimeStr = verifyTimeString(sharedPref.getString(getString(R.string.AlarmTimePref), defaultTimeStr));
Calendar cal = TimeStringToCalendar(alarmTimeStr);
- resetAlarm(getActivity(), cal);
+ setAlarm(getActivity(), cal);
}
}
});
- // Activate the time (after setting alarmActive) when starting the app.
+ // Activate the time (after setting alarmActive) when starting the app (but don't cancel any existing grace period alarms)
Calendar cal = TimeStringToCalendar(alarmTimeStr);
- resetAlarm(getActivity(), cal);
+ setAlarm(getActivity(), cal);
// Set grace period
- final int defaultGrace = 60;
- int gracePeriod = sharedPref.getInt(getString(R.string.GracePeriodPref), defaultGrace);
+ int gracePeriod = sharedPref.getInt(getString(R.string.GracePeriodPref), defaultGracePeriod);
final Spinner gracePeriodSpinner = (Spinner) getActivity().findViewById(R.id.grace_period);
gracePeriodSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@@ -251,6 +255,14 @@ public class MainActivity extends ActionBarActivity {
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
});
+
+ // Set time change and boot receiver, so alarm restarts on boot
+ ComponentName bootReceiver = new ComponentName(getActivity(), AlarmChangeReceiver.class);
+ PackageManager pm = getActivity().getPackageManager();
+ pm.setComponentEnabledSetting(bootReceiver,
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP);
+ Log.d("MainActivity", "Setting boot receiver");
}
@Override
@@ -276,7 +288,13 @@ public class MainActivity extends ActionBarActivity {
}
}
- public static void cancelAllAlarms(Context context) {
+ /**
+ * Cancel main alarm, but not grace alarm.
+ * This should be run whenever the alarm is set.
+ *
+ * @param context
+ */
+ public static void cancelAlarm(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// Cancel any current alarm
@@ -284,30 +302,63 @@ public class MainActivity extends ActionBarActivity {
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(context, ALARM_REQUEST, alarmIntent, 0);
alarmManager.cancel(alarmPendingIntent);
- // Cancel any pre-alarm notification
+ // Cancel any pre-alarm notification that may fire
Intent preNotifyIntent = new Intent(context, PreAlarmReceiver.class);
PendingIntent preNotifyPendingIntent = PendingIntent.getBroadcast(context, PRE_NOTIFY_REQUEST, preNotifyIntent, 0);
alarmManager.cancel(preNotifyPendingIntent);
+ // Stop any existing pre-alarm notification that has already fired
+ context.stopService(new Intent(context, PreAlarmNotify.class));
+
+ Log.d("MainActivity", "Alarm cancelled");
+ }
+
+ /**
+ * Cancel grace alarm and notifications
+ *
+ * @param context
+ */
+ public static void cancelGraceAlarm(Context context) {
+ AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+
// Cancel any grace period
Intent graceIntent = new Intent(context, GraceReceiver.class);
PendingIntent gracePendingIntent = PendingIntent.getBroadcast(context, GRACE_REQUEST, graceIntent, 0);
alarmManager.cancel(gracePendingIntent);
- // Stop any notifications
+ // Stop any notification of grace period expiry
context.stopService(new Intent(context, AlarmNotify.class));
- context.stopService(new Intent(context, PreAlarmNotify.class));
- Log.d("MainActivity", "Alarms cancelled");
+ // Stop any active/snoozed alarms
+ context.stopService(new Intent(context, AlarmService.class));
+
+ Log.d("MainActivity", "Grace alarm cancelled");
+ }
+ /**
+ * Cancels main alarm and grace alarm
+ * This should only be run when we're disabling the alarm entirely.
+ *
+ * @param context
+ */
+ public static void cancelAllAlarms(Context context) {
+ cancelAlarm(context);
+ cancelGraceAlarm(context);
+ Log.d("MainActivity", "All alarms cancelled");
}
- public static void resetAlarm(Context context, Calendar cal) {
+ /**
+ * Set the alarm.
+ *
+ * @param context Context
+ * @param cal Time at which to fire alarm
+ */
+ public static void setAlarm(Context context, Calendar cal) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent alarmPendingIntent, preNotifyPendingIntent;
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
- Boolean alarmActive = sharedPref.getBoolean(context.getString(R.string.AlarmActivePref), true);
+ Boolean alarmActive = sharedPref.getBoolean(context.getString(R.string.AlarmActivePref), defaultActive);
- cancelAllAlarms(context);
+ cancelAlarm(context);
// Advance cal to tomorrow if setting a time earlier than now
if (cal.before(Calendar.getInstance())) {
@@ -318,7 +369,6 @@ public class MainActivity extends ActionBarActivity {
// Initialise alarm, which displays a dialog and system alert, and
// calls AlarmManager with grace_period as the delay
// which in turn, sends SMS if dialog is not exited.
- // Advance to tomorrow if setting a time earlier than now
Intent alarmIntent = new Intent(context, AlarmReceiver.class);
alarmPendingIntent = PendingIntent.getBroadcast(context, ALARM_REQUEST, alarmIntent, 0);
// Set or reset alarm
@@ -329,9 +379,9 @@ public class MainActivity extends ActionBarActivity {
}
Log.d("MainActivity", "Setting alarm for " + MainActivity.debugDate(cal));
- // Set an alarm for the pre-alarm notification, half an hour before the alarm
+ // Set an alarm for the pre-alarm notification, an hour before the alarm
Calendar preNotifyCal = (Calendar) cal.clone();
- preNotifyCal.add(Calendar.MINUTE, -30);
+ preNotifyCal.add(Calendar.MINUTE, -60);
Intent preNotifyIntent = new Intent(context, PreAlarmReceiver.class);
preNotifyPendingIntent = PendingIntent.getBroadcast(context, PRE_NOTIFY_REQUEST, preNotifyIntent, 0);
// Set or reset alarm
@@ -342,14 +392,35 @@ public class MainActivity extends ActionBarActivity {
}
Log.d("MainActivity", "Setting pre-alarm for " + MainActivity.debugDate(preNotifyCal));
- // Set time change and boot receiver, so alarm restarts on boot
- ComponentName bootReceiver = new ComponentName(context, AlarmChangeReceiver.class);
- PackageManager pm = context.getPackageManager();
- pm.setComponentEnabledSetting(bootReceiver,
- PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
- PackageManager.DONT_KILL_APP);
- Log.d("MainActivity", "Setting boot receiver");
+ }
+ }
+ /**
+ * Set the grace alarm, to fire at the end of the grace period and send a text message.
+ *
+ * @param context
+ */
+ public static void setGraceAlarm(Context context) {
+ AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
+ Boolean alarmActive = sharedPref.getBoolean(context.getString(R.string.AlarmActivePref), defaultActive);
+ int gracePeriod = sharedPref.getInt(context.getString(R.string.GracePeriodPref), MainActivity.defaultGracePeriod);
+
+ cancelGraceAlarm(context);
+
+ if (alarmActive) {
+ // Set a grace period alarm to send SMS
+ Calendar graceCal = Calendar.getInstance();
+ graceCal.set(Calendar.SECOND, 0);
+ graceCal.add(Calendar.MINUTE, gracePeriod);
+ Intent graceIntent = new Intent(context, GraceReceiver.class);
+ PendingIntent gracePendingIntent = PendingIntent.getBroadcast(context, MainActivity.GRACE_REQUEST, graceIntent, 0);
+ if (Build.VERSION.SDK_INT >= 19) {
+ alarmManager.setExact(AlarmManager.RTC_WAKEUP, graceCal.getTimeInMillis(), gracePendingIntent);
+ } else {
+ alarmManager.set(AlarmManager.RTC_WAKEUP, graceCal.getTimeInMillis(), gracePendingIntent);
+ }
+ Log.d("MainActivity", "Setting grace alarm for " + MainActivity.debugDate(graceCal));
}
}
@@ -388,8 +459,10 @@ public class MainActivity extends ActionBarActivity {
Button alarm_time = (Button) getActivity().findViewById(R.id.alarm_time);
alarm_time.setText(alarmStr);
+ // Cancel any snoozed alerts
+ getActivity().stopService(new Intent(getActivity(), AlarmService.class));
// Set actual alarm
- resetAlarm(getActivity(), cal);
+ setAlarm(getActivity(), cal);
// Display toast
CharSequence text = getString(R.string.alarmSetToast) + " " + CalendarToTimeString(cal);
@@ -562,6 +635,15 @@ public class MainActivity extends ActionBarActivity {
return remMinutes + minStr;
}
+ // TODO remove this function?
+ public static Calendar minutesAgo(int minutes) {
+ // Negate number to get minutes in the past.
+ minutes = minutes * -1;
+ Calendar cal = Calendar.getInstance();
+ cal.add(Calendar.MINUTE, minutes);
+ return cal;
+ }
+
public static String debugDate(Calendar cal) {
SimpleDateFormat print = new SimpleDateFormat("dd-MM-yyyy HH:mm:ssZ");
return print.format(cal.getTime());
diff --git a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/PreAlarmNotify.java b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/PreAlarmNotify.java
index afce195..267c683 100644
--- a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/PreAlarmNotify.java
+++ b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/PreAlarmNotify.java
@@ -40,7 +40,7 @@ public class PreAlarmNotify extends Service {
Log.d("PreAlarmNotify", "Pre-notification started.");
// Get alarm time, and convert it into something readable.
- String alarmTimeStr = sharedPref.getString(getString(R.string.AlarmTimePref), null);
+ String alarmTimeStr = sharedPref.getString(getString(R.string.AlarmTimePref), MainActivity.defaultTimeStr);
Calendar alarmCal = MainActivity.TimeStringToCalendar(alarmTimeStr);
alarmTimeStr = MainActivity.formattedTime(getApplicationContext(), alarmCal);
diff --git a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/PreAlarmReceiver.java b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/PreAlarmReceiver.java
index 9befcb6..50fee9f 100644
--- a/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/PreAlarmReceiver.java
+++ b/HypoAlarm/src/main/java/za/org/treehouse/hypoalarm/PreAlarmReceiver.java
@@ -10,7 +10,7 @@ public class PreAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
- Boolean alarmActive = sharedPref.getBoolean(context.getString(R.string.AlarmActivePref), true);
+ Boolean alarmActive = sharedPref.getBoolean(context.getString(R.string.AlarmActivePref), MainActivity.defaultActive);
if (alarmActive) {
// Create notification
diff --git a/HypoAlarm/src/main/res/values/strings.xml b/HypoAlarm/src/main/res/values/strings.xml
index b9c7869..37fabc2 100644
--- a/HypoAlarm/src/main/res/values/strings.xml
+++ b/HypoAlarm/src/main/res/values/strings.xml
@@ -53,7 +53,9 @@
HypoAlarm set to
- HypoAlarm text message cancelled
+ HypoAlarm cancelled
+
+ HypoAlarm text message cancelled
Hi, I haven\'t responded to my alarm today. Please contact me to make sure I\'m awake.