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)); + } + +}