Prevent subsequent alarms from snoozing; make pre-alarm an hour earlier; correct boot receiver bug.
This commit is contained in:
parent
571df2f2c2
commit
20f99f2b5f
@ -8,10 +8,11 @@
|
||||
</facet>
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="release" />
|
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleRelease" />
|
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileReleaseJava" />
|
||||
<option name="SOURCE_GEN_TASK_NAME" value="generateReleaseSources" />
|
||||
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugJava" />
|
||||
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
|
||||
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
|
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
||||
@ -21,21 +22,26 @@
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/build/classes/release" />
|
||||
<output url="file://$MODULE_DIR$/build/classes/debug" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/r/release" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/release" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/release" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/release" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/release" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/release/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/release/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/release/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/release/assets" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/release/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/release/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/release/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/r/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/r/test/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/test/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/test/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/test/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/test/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
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;
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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 (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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -53,7 +53,9 @@
|
||||
|
||||
<string name="alarmSetToast">HypoAlarm set to </string>
|
||||
|
||||
<string name="alarmCancelToast">HypoAlarm text message cancelled</string>
|
||||
<string name="alarmCancelToast">HypoAlarm cancelled</string>
|
||||
|
||||
<string name="graceCancelToast">HypoAlarm text message cancelled</string>
|
||||
|
||||
<string name="defaultMessage">Hi, I haven\'t responded to my alarm today. Please contact me to make sure I\'m awake.</string>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user