From dab8e1f4a53f7f30ec218405e5acb97e14a0f0c1 Mon Sep 17 00:00:00 2001 From: Phillip Hsu Date: Mon, 6 Jun 2016 16:52:51 -0700 Subject: [PATCH] Notification actions created for active alarm in RingtoneService --- .../clock2/UpcomingAlarmReceiver.java | 13 ++--- .../clock2/ringtone/RingtoneActivity.java | 7 ++- .../clock2/ringtone/RingtoneService.java | 57 ++++++++++++++++++- app/src/main/res/values/strings.xml | 2 + 4 files changed, 67 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/philliphsu/clock2/UpcomingAlarmReceiver.java b/app/src/main/java/com/philliphsu/clock2/UpcomingAlarmReceiver.java index d2d56df..7cd66ed 100644 --- a/app/src/main/java/com/philliphsu/clock2/UpcomingAlarmReceiver.java +++ b/app/src/main/java/com/philliphsu/clock2/UpcomingAlarmReceiver.java @@ -17,15 +17,12 @@ import static com.philliphsu.clock2.util.Preconditions.checkNotNull; public class UpcomingAlarmReceiver extends BroadcastReceiver { private static final String TAG = "UpcomingAlarmReceiver"; + /*TOneverDO: not private*/ + private static final String ACTION_DISMISS_NOW = "com.philliphsu.clock2.action.DISMISS_NOW"; - public static final String ACTION_CANCEL_NOTIFICATION - = "com.philliphsu.clock2.action.CANCEL_NOTIFICATION"; - public static final String ACTION_SHOW_SNOOZING - = "com.philliphsu.clock2.action.SHOW_SNOOZING"; - /*TOneverDO: not private*/ private static final String ACTION_DISMISS_NOW - = "com.philliphsu.clock2.action.DISMISS_NOW"; - public static final String EXTRA_ALARM_ID - = "com.philliphsu.clock2.extra.ALARM_ID"; + public static final String ACTION_CANCEL_NOTIFICATION = "com.philliphsu.clock2.action.CANCEL_NOTIFICATION"; + public static final String ACTION_SHOW_SNOOZING = "com.philliphsu.clock2.action.SHOW_SNOOZING"; + public static final String EXTRA_ALARM_ID = "com.philliphsu.clock2.extra.ALARM_ID"; @Override public void onReceive(Context context, Intent intent) { 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 31c38e2..04615c0 100644 --- a/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneActivity.java +++ b/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneActivity.java @@ -11,12 +11,14 @@ import android.util.Log; import android.view.View; import android.view.WindowManager; import android.widget.Button; +import android.widget.Toast; import com.philliphsu.clock2.Alarm; import com.philliphsu.clock2.R; import com.philliphsu.clock2.editalarm.AlarmUtils; import com.philliphsu.clock2.model.AlarmsRepository; +import static com.philliphsu.clock2.util.DateFormatUtils.formatTime; import static com.philliphsu.clock2.util.Preconditions.checkNotNull; /** @@ -125,7 +127,7 @@ public class RingtoneActivity extends AppCompatActivity implements RingtoneServi } @Override - public void onAutoSilence() { + public void onServiceFinish() { dismiss(); } @@ -133,6 +135,9 @@ public class RingtoneActivity extends AppCompatActivity implements RingtoneServi mAlarm.snooze(1); // TODO: Read snooze duration from prefs AlarmUtils.scheduleAlarm(this, mAlarm); AlarmsRepository.getInstance(this).saveItems(); + // Display toast + String message = getString(R.string.title_snoozing_until, formatTime(this, mAlarm.snoozingUntil())); + Toast.makeText(this, message, Toast.LENGTH_LONG).show(); dismiss(); } diff --git a/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneService.java b/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneService.java index b5c6f1f..31c87dd 100644 --- a/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneService.java +++ b/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneService.java @@ -2,6 +2,7 @@ package com.philliphsu.clock2.ringtone; import android.app.Notification; import android.app.NotificationManager; +import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; @@ -18,6 +19,8 @@ import android.util.Log; import com.philliphsu.clock2.Alarm; import com.philliphsu.clock2.R; +import com.philliphsu.clock2.editalarm.AlarmUtils; +import com.philliphsu.clock2.model.AlarmsRepository; import static com.philliphsu.clock2.util.DateFormatUtils.formatTime; import static com.philliphsu.clock2.util.Preconditions.checkNotNull; @@ -33,6 +36,12 @@ import static com.philliphsu.clock2.util.Preconditions.checkNotNull; public class RingtoneService extends Service { // TODO: abstract this, make subclasses private static final String TAG = "RingtoneService"; + /* TOneverDO: not private */ + private static final String ACTION_SNOOZE = "com.philliphsu.clock2.ringtone.action.SNOOZE"; + private static final String ACTION_DISMISS = "com.philliphsu.clock2.ringtone.action.DISMISS"; + // TODO: Same value as RingtoneActivity.EXTRA_ITEM_ID. Is it important enough to define a different constant? + private static final String EXTRA_ITEM_ID = "com.philliphsu.clock2.ringtone.extra.ITEM_ID"; + private AudioManager mAudioManager; private Ringtone mRingtone; private Alarm mAlarm; @@ -52,7 +61,7 @@ public class RingtoneService extends Service { // TODO: abstract this, make subc // All clients must be unbound before stopSelf() (and stopService()?) will succeed. // See https://developer.android.com/guide/components/bound-services.html#Lifecycle // Figure 1 regarding the lifecycle of started and bound services. - mRingtoneCallback.onAutoSilence(); + mRingtoneCallback.onServiceFinish(); } } }; @@ -64,6 +73,31 @@ public class RingtoneService extends Service { // TODO: abstract this, make subc // If Alarms and Timers will have distinct settings for this, then consider doing this // operation in the respective subclass of this service. + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + // Although this is a bound service, we override this method because this class is reused for + // handling the notification actions for the presently ringing alarm. From the docs of Context#startService(): + // "Using startService() overrides the default service lifetime that is managed by + // bindService(Intent, ServiceConnection, int): it requires the service to remain running until + // stopService(Intent)* is called, regardless of whether any clients are connected to it." + // * Would stopSelf() also work? + + if (ACTION_SNOOZE.equals(intent.getAction())) { + long id = intent.getLongExtra(EXTRA_ITEM_ID, -1); + if (id < 0) throw new IllegalStateException("No item id set"); + Alarm alarm = checkNotNull(AlarmsRepository.getInstance(this).getItem(id)); + alarm.snooze(1); // TODO: read snooze duration in prefs + AlarmUtils.scheduleAlarm(this, alarm); + } + stopSelf(startId); + if (mRingtoneCallback != null) { + mRingtoneCallback.onServiceFinish(); + } + + return START_NOT_STICKY; // If killed while started, don't recreate. Should be sufficient. + } + @Override public void onDestroy() { Log.d(TAG, "onDestroy()"); @@ -108,6 +142,12 @@ public class RingtoneService extends Service { // TODO: abstract this, make subc .setSmallIcon(R.mipmap.ic_launcher) // TODO: alarm icon .setContentTitle(title) .setContentText(mNormalRingTime) + .addAction(R.mipmap.ic_launcher, + getString(R.string.snooze), + getPendingIntent(ACTION_SNOOZE, mAlarm)) + .addAction(R.mipmap.ic_launcher, + getString(R.string.dismiss), + getPendingIntent(ACTION_DISMISS, mAlarm)) .build(); startForeground(R.id.ringtone_service_notification, note); // TOneverDO: Pass 0 as the first argument @@ -151,7 +191,7 @@ public class RingtoneService extends Service { // TODO: abstract this, make subc } public interface RingtoneCallback { - void onAutoSilence(); + void onServiceFinish(); } private void scheduleAutoSilence() { @@ -160,6 +200,17 @@ public class RingtoneService extends Service { // TODO: abstract this, make subc /*int minutes = Integer.parseInt(pref.getString( getString(R.string.key_silence_after), "15"));*/ - mSilenceHandler.postDelayed(mSilenceRunnable, 10000); + mSilenceHandler.postDelayed(mSilenceRunnable, 20000); + } + + private PendingIntent getPendingIntent(@NonNull String action, Alarm alarm) { + Intent intent = new Intent(this, getClass()) + .setAction(action) + .putExtra(EXTRA_ITEM_ID, alarm.id()); + return PendingIntent.getService( + this, + alarm.intId(), + intent, + PendingIntent.FLAG_ONE_SHOT); } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1736b40..759c53e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -15,6 +15,8 @@ 00:00 Snoozing until %1$s Dismiss now + Dismiss + Snooze Done snoozing Alarm set for %1$s from now.