Notification actions created for active alarm in RingtoneService

This commit is contained in:
Phillip Hsu 2016-06-06 16:52:51 -07:00
parent 9441b5da10
commit dab8e1f4a5
4 changed files with 67 additions and 12 deletions

View File

@ -17,15 +17,12 @@ import static com.philliphsu.clock2.util.Preconditions.checkNotNull;
public class UpcomingAlarmReceiver extends BroadcastReceiver { public class UpcomingAlarmReceiver extends BroadcastReceiver {
private static final String TAG = "UpcomingAlarmReceiver"; 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 public static final String ACTION_CANCEL_NOTIFICATION = "com.philliphsu.clock2.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 ACTION_SHOW_SNOOZING public static final String EXTRA_ALARM_ID = "com.philliphsu.clock2.extra.ALARM_ID";
= "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";
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {

View File

@ -11,12 +11,14 @@ import android.util.Log;
import android.view.View; import android.view.View;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.Button; import android.widget.Button;
import android.widget.Toast;
import com.philliphsu.clock2.Alarm; import com.philliphsu.clock2.Alarm;
import com.philliphsu.clock2.R; import com.philliphsu.clock2.R;
import com.philliphsu.clock2.editalarm.AlarmUtils; import com.philliphsu.clock2.editalarm.AlarmUtils;
import com.philliphsu.clock2.model.AlarmsRepository; import com.philliphsu.clock2.model.AlarmsRepository;
import static com.philliphsu.clock2.util.DateFormatUtils.formatTime;
import static com.philliphsu.clock2.util.Preconditions.checkNotNull; import static com.philliphsu.clock2.util.Preconditions.checkNotNull;
/** /**
@ -125,7 +127,7 @@ public class RingtoneActivity extends AppCompatActivity implements RingtoneServi
} }
@Override @Override
public void onAutoSilence() { public void onServiceFinish() {
dismiss(); dismiss();
} }
@ -133,6 +135,9 @@ public class RingtoneActivity extends AppCompatActivity implements RingtoneServi
mAlarm.snooze(1); // TODO: Read snooze duration from prefs mAlarm.snooze(1); // TODO: Read snooze duration from prefs
AlarmUtils.scheduleAlarm(this, mAlarm); AlarmUtils.scheduleAlarm(this, mAlarm);
AlarmsRepository.getInstance(this).saveItems(); 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(); dismiss();
} }

View File

@ -2,6 +2,7 @@ package com.philliphsu.clock2.ringtone;
import android.app.Notification; import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service; import android.app.Service;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -18,6 +19,8 @@ import android.util.Log;
import com.philliphsu.clock2.Alarm; import com.philliphsu.clock2.Alarm;
import com.philliphsu.clock2.R; 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.DateFormatUtils.formatTime;
import static com.philliphsu.clock2.util.Preconditions.checkNotNull; 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 public class RingtoneService extends Service { // TODO: abstract this, make subclasses
private static final String TAG = "RingtoneService"; 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 AudioManager mAudioManager;
private Ringtone mRingtone; private Ringtone mRingtone;
private Alarm mAlarm; 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. // All clients must be unbound before stopSelf() (and stopService()?) will succeed.
// See https://developer.android.com/guide/components/bound-services.html#Lifecycle // See https://developer.android.com/guide/components/bound-services.html#Lifecycle
// Figure 1 regarding the lifecycle of started and bound services. // 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 // If Alarms and Timers will have distinct settings for this, then consider doing this
// operation in the respective subclass of this service. // 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 @Override
public void onDestroy() { public void onDestroy() {
Log.d(TAG, "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 .setSmallIcon(R.mipmap.ic_launcher) // TODO: alarm icon
.setContentTitle(title) .setContentTitle(title)
.setContentText(mNormalRingTime) .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(); .build();
startForeground(R.id.ringtone_service_notification, note); // TOneverDO: Pass 0 as the first argument 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 { public interface RingtoneCallback {
void onAutoSilence(); void onServiceFinish();
} }
private void scheduleAutoSilence() { private void scheduleAutoSilence() {
@ -160,6 +200,17 @@ public class RingtoneService extends Service { // TODO: abstract this, make subc
/*int minutes = Integer.parseInt(pref.getString( /*int minutes = Integer.parseInt(pref.getString(
getString(R.string.key_silence_after), getString(R.string.key_silence_after),
"15"));*/ "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);
} }
} }

View File

@ -15,6 +15,8 @@
<string name="default_alarm_time_24h">00:00</string> <string name="default_alarm_time_24h">00:00</string>
<string name="title_snoozing_until">Snoozing until %1$s</string> <string name="title_snoozing_until">Snoozing until %1$s</string>
<string name="dismiss_now">Dismiss now</string> <string name="dismiss_now">Dismiss now</string>
<string name="dismiss">Dismiss</string>
<string name="snooze">Snooze</string>
<string name="done_snoozing">Done snoozing</string> <string name="done_snoozing">Done snoozing</string>
<string name="alarm_set_for">Alarm set for %1$s from now.</string> <string name="alarm_set_for">Alarm set for %1$s from now.</string>
<!-- ======================================================================================= --> <!-- ======================================================================================= -->