diff --git a/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneActivity.java b/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneActivity.java
index a26dde1..7f76140 100644
--- a/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneActivity.java
+++ b/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneActivity.java
@@ -60,6 +60,13 @@ public class RingtoneActivity extends AppCompatActivity implements RingtoneServi
// This could be the case if we're starting a new instance of this activity after leaving the first launch.
AlarmUtils.removeUpcomingAlarmNotification(this, mAlarm);
+ // As of API 19, alarms scheduled with AlarmManager.setRepeating() are inexact. The recommended
+ // workaround is to schedule one-time exact alarms, and reschedule each time after handling
+ // an alarm delivery.
+ if (mAlarm.hasRecurrence()) {
+ AlarmUtils.scheduleAlarm(this, mAlarm);
+ }
+
Intent intent = new Intent(this, RingtoneService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
diff --git a/app/src/main/java/com/philliphsu/clock2/util/DurationUtils.java b/app/src/main/java/com/philliphsu/clock2/util/DurationUtils.java
index 526f660..9e4f731 100644
--- a/app/src/main/java/com/philliphsu/clock2/util/DurationUtils.java
+++ b/app/src/main/java/com/philliphsu/clock2/util/DurationUtils.java
@@ -12,74 +12,44 @@ import java.util.concurrent.TimeUnit;
* Created by Phillip Hsu on 6/6/2016.
*/
public class DurationUtils {
- public static final int HOURS = 0;
- public static final int MINUTES = 1;
- public static final int SECONDS = 2;
- public static final int MILLIS = 3;
+ public static final int DAYS = 0;
+ public static final int HOURS = 1;
+ public static final int MINUTES = 2;
+ public static final int SECONDS = 3;
+ public static final int MILLIS = 4;
/** Return a string representing the duration, formatted in hours and minutes.
- * TODO: Need to adapt this to represent all time fields eventually */
+ * TODO: Need to adapt this to represent all time fields eventually
+ * TODO: Since this is primarirly used for alarm set toasts, you should make different methods for
+ * different use cases. E.g. Timer's duration should have its own method.
+ * TODO: Then, rename this method to something about alarm toasts. */
public static String toString(Context context, long millis, boolean abbreviate) {
long[] fields = breakdown(millis);
- long numHours = fields[0];
- long numMins = fields[1];
- long numSecs = fields[2]; // only considered for rounding of minutes
+ long numDays = fields[DAYS];
+ long numHours = fields[HOURS];
+ long numMins = fields[MINUTES];
+ long numSecs = fields[SECONDS]; // only considered for rounding of minutes
if (numSecs >= 31) {
numMins++;
numSecs = 0; // Not totally necessary since it won't be considered any more
if (numMins == 60) {
numHours++;
numMins = 0;
+ if (numHours == 24) {
+ numDays++;
+ numHours = 0;
+ }
}
}
- @StringRes int res;
-
+ int res;
if (abbreviate) {
- if (numHours == 0) {
- if (numMins == 0) {
- res = R.string.abbrev_less_than_one_minute;
- } else {
- res = R.string.abbrev_minutes;
- }
- } else {
- if (numMins == 0) {
- res = R.string.abbrev_hours;
- } else {
- res = R.string.abbrev_hours_and_minutes;
- }
- }
+ res = getAbbreviatedStringRes(numDays, numHours, numMins);
} else {
- if (numHours == 0) {
- if (numMins == 0) {
- res = R.string.less_than_one_minute;
- } else if (numMins == 1) {
- res = R.string.minute;
- } else {
- res = R.string.minutes;
- }
- } else {
- if (numHours == 1) {
- if (numMins == 0) {
- res = R.string.hour;
- } else if (numMins == 1) {
- res = R.string.hour_and_minute;
- } else {
- res = R.string.hour_and_minutes;
- }
- } else {
- if (numMins == 0) {
- res = R.string.hours;
- } else if (numMins == 1) {
- res = R.string.hours_and_minute;
- } else {
- res = R.string.hours_and_minutes;
- }
- }
- }
+ res = getStringRes(numDays, numHours, numMins);
}
- return context.getString(res, numHours, numMins);
+ return context.getString(res, numDays, numHours, numMins);
}
/**
@@ -112,7 +82,8 @@ public class DurationUtils {
* and milliseconds in that order
*/
public static long[] breakdown(long t, @NonNull TimeUnit unit, boolean roundMillis) {
- long hours = unit.toHours(t);
+ long days = unit.toDays(t);
+ long hours = unit.toHours(t) % 24;
long minutes = unit.toMinutes(t) % 60;
long seconds = unit.toSeconds(t) % 60;
long msecs = unit.toMillis(t) % 1000;
@@ -126,11 +97,136 @@ public class DurationUtils {
if (minutes == 60) {
hours++;
minutes = 0;
+ if (hours == 24) {
+ days++;
+ hours = 0;
+ }
}
}
}
}
- return new long[] { hours, minutes, seconds, msecs };
+ return new long[] { days, hours, minutes, seconds, msecs };
}
+ @StringRes
+ private static int getStringRes(long numDays, long numHours, long numMins) {
+ int res;
+ if (numDays == 0) {
+ if (numHours == 0) {
+ if (numMins == 0) {
+ res = R.string.less_than_one_minute;
+ } else if (numMins == 1) {
+ res = R.string.minute;
+ } else {
+ res = R.string.minutes;
+ }
+ } else if (numHours == 1) {
+ if (numMins == 0) {
+ res = R.string.hour;
+ } else if (numMins == 1) {
+ res = R.string.hour_and_minute;
+ } else {
+ res = R.string.hour_and_minutes;
+ }
+ } else {
+ if (numMins == 0) {
+ res = R.string.hours;
+ } else if (numMins == 1) {
+ res = R.string.hours_and_minute;
+ } else {
+ res = R.string.hours_and_minutes;
+ }
+ }
+ } else if (numDays == 1) {
+ if (numHours == 0) {
+ if (numMins == 0) {
+ res = R.string.day;
+ } else if (numMins == 1) {
+ res = R.string.day_and_minute;
+ } else {
+ res = R.string.day_and_minutes;
+ }
+ } else if (numHours == 1) {
+ if (numMins == 0) {
+ res = R.string.day_and_hour;
+ } else if (numMins == 1) {
+ res = R.string.day_hour_and_minute;
+ } else {
+ res = R.string.day_hour_and_minutes;
+ }
+ } else {
+ if (numMins == 0) {
+ res = R.string.day_and_hours;
+ } else if (numMins == 1) {
+ res = R.string.day_hours_and_minute;
+ } else {
+ res = R.string.day_hours_and_minutes;
+ }
+ }
+ } else {
+ if (numHours == 0) {
+ if (numMins == 0) {
+ res = R.string.days;
+ } else if (numMins == 1) {
+ res = R.string.days_and_minute;
+ } else {
+ res = R.string.days_and_minutes;
+ }
+ } else if (numHours == 1) {
+ if (numMins == 0) {
+ res = R.string.days_and_hour;
+ } else if (numMins == 1) {
+ res = R.string.days_hour_and_minute;
+ } else {
+ res = R.string.days_hour_and_minutes;
+ }
+ } else {
+ if (numMins == 0) {
+ res = R.string.days_and_hours;
+ } else if (numMins == 1) {
+ res = R.string.days_hours_and_minute;
+ } else {
+ res = R.string.days_hours_and_minutes;
+ }
+ }
+ }
+ return res;
+ }
+
+ @StringRes
+ private static int getAbbreviatedStringRes(long numDays, long numHours, long numMins) {
+ int res;
+ if (numDays == 0) {
+ if (numHours == 0) {
+ if (numMins == 0) {
+ res = R.string.abbrev_less_than_one_minute;
+ } else {
+ res = R.string.abbrev_minutes;
+ }
+ } else {
+ if (numMins == 0) {
+ res = R.string.abbrev_hours;
+ } else {
+ res = R.string.abbrev_hours_and_minutes;
+ }
+ }
+ } else {
+ if (numHours == 0) {
+ if (numMins == 0) {
+ res = R.string.abbrev_days;
+ } else {
+ res = R.string.abbrev_days_and_minutes;
+ }
+ } else {
+ if (numMins == 0) {
+ res = R.string.abbrev_days_and_hours;
+ } else {
+ res = R.string.abbrev_days_hours_and_minutes;
+ }
+ }
+ }
+ return res;
+ }
+
+
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 91eda26..284f44c 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -22,19 +22,41 @@
- %1$d hour and %2$d minute
- %1$d hour and %2$d minutes
- %1$d hours and %2$d minute
- %1$d hours and %2$d minutes
- %1$d hour
- %1$d hours
- %2$d minute
- %2$d minutes
+ 1 day, 1 hour, and 1 minute
+ %1$d days, 1 hour, and 1 minute
+ %1$d days, %2$d hours, and 1 minute
+ %1$d days, 1 hours, and %3$d minutes
+ %1$d days, %2$d hours, and %3$d minutes
+ 1 day, %2$d hours, and 1 minute
+ 1 day, %2$d hours, and %3$d minutes
+ 1 day, 1 hour, and %3$d minutes
+ 1 day and 1 hour
+ %1$d days and 1 hour
+ 1 day and %2$d hours
+ %1$d days and %2$d hours
+ 1 day and 1 minute
+ %1$d days and 1 minute
+ 1 day and %3$d minutes
+ %1$d days and %3$d minutes
+ 1 hour and 1 minute
+ 1 hour and %3$d minutes
+ %2$d hours and 1 minute
+ %2$d hours and %3$d minutes
+ 1 day
+ %1$d days
+ 1 hour
+ %2$d hours
+ 1 minute
+ %3$d minutes
less than 1 minute
- %1$dh %2$dm
- %1$dh
- %2$dm
+ %1$dd %2$dh %3$dm
+ %1$dd %2$dh
+ %1$dd %3$dm
+ %2$dh %3$dm
+ %1$dd
+ %2$dh
+ %3$dm
<1m
%1$s alarm dismissed.
diff --git a/app/src/test/java/com/philliphsu/clock2/DurationUtilsTest.java b/app/src/test/java/com/philliphsu/clock2/DurationUtilsTest.java
new file mode 100644
index 0000000..f77c96e
--- /dev/null
+++ b/app/src/test/java/com/philliphsu/clock2/DurationUtilsTest.java
@@ -0,0 +1,23 @@
+package com.philliphsu.clock2;
+
+import com.philliphsu.clock2.util.DurationUtils;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by Phillip Hsu on 6/10/2016.
+ */
+public class DurationUtilsTest {
+
+ @Test
+ public void testBreakdown() {
+ long duration = TimeUnit.HOURS.toMillis(45)
+ + TimeUnit.MINUTES.toMillis(97);
+ long[] l = DurationUtils.breakdown(duration);
+ System.out.println(Arrays.toString(l));
+ }
+
+}