diff --git a/app/src/main/java/com/philliphsu/clock2/alarms/AlarmViewHolder.java b/app/src/main/java/com/philliphsu/clock2/alarms/AlarmViewHolder.java index ec6dc35..65cd909 100644 --- a/app/src/main/java/com/philliphsu/clock2/alarms/AlarmViewHolder.java +++ b/app/src/main/java/com/philliphsu/clock2/alarms/AlarmViewHolder.java @@ -6,6 +6,7 @@ import android.text.SpannableString; import android.text.Spanned; import android.text.format.DateFormat; import android.text.style.RelativeSizeSpan; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.Button; @@ -22,7 +23,9 @@ import com.philliphsu.clock2.util.AlarmUtils; import java.util.Date; import butterknife.Bind; +import butterknife.OnCheckedChanged; import butterknife.OnClick; +import butterknife.OnTouch; import static android.view.View.GONE; import static android.view.View.VISIBLE; @@ -65,11 +68,24 @@ public class AlarmViewHolder extends BaseViewHolder implements AlarmCount @OnClick(R.id.dismiss) void dismiss() { + // TOneverDO: AlarmUtils.cancelAlarm() otherwise it will be called twice + mSwitch.setPressed(true); // needed so the OnCheckedChange event calls through + bindSwitch(false); // fires OnCheckedChange to do the binding for you + /* AlarmUtils.cancelAlarm(getContext(), getAlarm()); + if (!getAlarm().isEnabled()) { + // TOneverDO: mSwitch.setPressed(true); + bindSwitch(false); // will fire OnCheckedChange, but switch isn't set as pressed so nothing happens. + bindCountdown(false, -1); + } bindDismissButton(false, ""); // Will be set to correct text the next time we bind. // If cancelAlarm() modified the alarm's fields, then it will save changes for you. + */ } + // Changed in favor or OnCheckedChange + /* + @Deprecated @OnClick(R.id.on_off_switch) void toggle() { Alarm alarm = getAlarm(); @@ -85,6 +101,36 @@ public class AlarmViewHolder extends BaseViewHolder implements AlarmCount } save(); // TODO: Problem! If cancelAlarm() saves the repo, this is a redundant call! } + */ + + @OnTouch(R.id.on_off_switch) + boolean slide(MotionEvent event) { + if (event.getActionMasked() == MotionEvent.ACTION_MOVE) { + mSwitch.setPressed(true); // needed so the OnCheckedChange event calls through + } + return false; // proceed as usual + } + + @OnCheckedChanged(R.id.on_off_switch) + void toggle(boolean checked) { + if (mSwitch.isPressed()) { // needed to distinguish automatic calls when VH binds from actual presses + // don't need to toggle the switch state + Alarm alarm = getAlarm(); + alarm.setEnabled(checked); + if (alarm.isEnabled()) { + // TODO: On Moto X, upcoming notification doesn't post immediately + AlarmUtils.scheduleAlarm(getContext(), alarm); + bindCountdown(true, alarm.ringsIn()); + bindDismissButton(alarm); + } else { + AlarmUtils.cancelAlarm(getContext(), alarm); // might save repo + bindCountdown(false, -1); + bindDismissButton(false, ""); + } + save(); // TODO: Problem! If cancelAlarm() saves the repo, this is a redundant call! + mSwitch.setPressed(false); // clear the pressed focus, esp. if setPressed(true) was called manually + } + } private void bindTime(Date date) { String time = DateFormat.getTimeFormat(getContext()).format(date); diff --git a/app/src/main/java/com/philliphsu/clock2/util/AlarmUtils.java b/app/src/main/java/com/philliphsu/clock2/util/AlarmUtils.java index 917e6b5..abcd9cf 100644 --- a/app/src/main/java/com/philliphsu/clock2/util/AlarmUtils.java +++ b/app/src/main/java/com/philliphsu/clock2/util/AlarmUtils.java @@ -21,6 +21,7 @@ import static android.app.PendingIntent.FLAG_NO_CREATE; import static android.app.PendingIntent.getActivity; import static com.philliphsu.clock2.util.DateFormatUtils.formatTime; import static com.philliphsu.clock2.util.Preconditions.checkNotNull; +import static java.util.concurrent.TimeUnit.HOURS; /** * Created by Phillip Hsu on 6/3/2016. @@ -50,7 +51,7 @@ public final class AlarmUtils { // device is asleep. Otherwise, it will not go off until the device is turned back on. long ringAt = alarm.isSnoozed() ? alarm.snoozingUntil() : alarm.ringsAt(); // If snoozed, upcoming note posted immediately. - am.set(AlarmManager.RTC_WAKEUP, ringAt - hoursBeforeUpcoming(context) * 3600000, + am.set(AlarmManager.RTC_WAKEUP, ringAt - HOURS.toMillis(hoursBeforeUpcoming(context)), notifyUpcomingAlarmIntent(context, alarm, false)); am.setExact(AlarmManager.RTC_WAKEUP, ringAt, alarmIntent(context, alarm, false)); @@ -91,6 +92,12 @@ public final class AlarmUtils { save(c); } + if (a.ringsIn() <= HOURS.toMillis(hoursBeforeUpcoming(c))) { + String time = formatTime(c, a.ringsAt()); + String text = c.getString(R.string.upcoming_alarm_dismissed, time); + Toast.makeText(c, text, Toast.LENGTH_LONG).show(); + } + // If service is not running, nothing happens // TODO: Since RingtoneService is a bound service, will this destroy the service after returning? // Note that if a stopped service still has ServiceConnection objects bound to it with the diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 075615b..91eda26 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -36,6 +36,8 @@ %1$dh %2$dm <1m + + %1$s alarm dismissed.