Modify StopwatchNotificationService to extend ChronometerNotificationService
This commit is contained in:
parent
31e0a71d9f
commit
e157498147
@ -236,6 +236,13 @@ public abstract class ChronometerNotificationService extends Service {
|
|||||||
mNoteBuilder.addAction(icon, actionTitle, pi);
|
mNoteBuilder.addAction(icon, actionTitle, pi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels the notification with the pair ({@link #getNoteTag() tag}, id)
|
||||||
|
*/
|
||||||
|
protected final void cancelNotification(int id) {
|
||||||
|
mNotificationManager.cancel(getNoteTag(), id);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Causes the handler thread's looper to terminate without processing
|
* Causes the handler thread's looper to terminate without processing
|
||||||
* any more messages in the message queue.
|
* any more messages in the message queue.
|
||||||
|
|||||||
@ -0,0 +1,10 @@
|
|||||||
|
package com.philliphsu.clock2.stopwatch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Phillip Hsu on 9/11/2016.
|
||||||
|
*/
|
||||||
|
public final class StopwatchController {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -36,9 +36,11 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
LapCursor,
|
LapCursor,
|
||||||
LapsAdapter> {
|
LapsAdapter> {
|
||||||
private static final String TAG = "StopwatchFragment";
|
private static final String TAG = "StopwatchFragment";
|
||||||
private static final String KEY_START_TIME = "start_time";
|
|
||||||
private static final String KEY_PAUSE_TIME = "pause_time";
|
// Exposed for StopwatchNotificationService
|
||||||
private static final String KEY_CHRONOMETER_RUNNING = "chronometer_running";
|
static final String KEY_START_TIME = "start_time";
|
||||||
|
static final String KEY_PAUSE_TIME = "pause_time";
|
||||||
|
static final String KEY_CHRONOMETER_RUNNING = "chronometer_running";
|
||||||
|
|
||||||
private long mStartTime;
|
private long mStartTime;
|
||||||
private long mPauseTime;
|
private long mPauseTime;
|
||||||
|
|||||||
@ -1,117 +1,109 @@
|
|||||||
package com.philliphsu.clock2.stopwatch;
|
package com.philliphsu.clock2.stopwatch;
|
||||||
|
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.IBinder;
|
import android.content.SharedPreferences;
|
||||||
import android.support.annotation.DrawableRes;
|
import android.os.SystemClock;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.preference.PreferenceManager;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import com.philliphsu.clock2.ChronometerNotificationThread;
|
import com.philliphsu.clock2.ChronometerNotificationService;
|
||||||
import com.philliphsu.clock2.MainActivity;
|
import com.philliphsu.clock2.MainActivity;
|
||||||
import com.philliphsu.clock2.R;
|
import com.philliphsu.clock2.R;
|
||||||
|
|
||||||
public class StopwatchNotificationService extends Service {
|
public class StopwatchNotificationService extends ChronometerNotificationService {
|
||||||
private static final String ACTION_ADD_LAP = "com.philliphsu.clock2.stopwatch.action.ADD_LAP";
|
private static final String ACTION_ADD_LAP = "com.philliphsu.clock2.stopwatch.action.ADD_LAP";
|
||||||
private static final String ACTION_START_PAUSE = "com.philliphsu.clock2.stopwatch.action.START_PAUSE";
|
|
||||||
private static final String ACTION_STOP = "com.philliphsu.clock2.stopwatch.action.STOP";
|
|
||||||
|
|
||||||
private NotificationCompat.Builder mNoteBuilder;
|
|
||||||
private NotificationManager mNotificationManager;
|
|
||||||
private AsyncLapsTableUpdateHandler mLapsTableUpdateHandler;
|
private AsyncLapsTableUpdateHandler mLapsTableUpdateHandler;
|
||||||
private ChronometerNotificationThread mThread;
|
private SharedPreferences mPrefs;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
|
||||||
mLapsTableUpdateHandler = new AsyncLapsTableUpdateHandler(this, null);
|
mLapsTableUpdateHandler = new AsyncLapsTableUpdateHandler(this, null);
|
||||||
|
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
// Create base note
|
|
||||||
// TODO: I think we can make this a foreground service so even
|
// TODO: I think we can make this a foreground service so even
|
||||||
// if the process is killed, this service remains alive.
|
// if the process is killed, this service remains alive.
|
||||||
mNoteBuilder = new NotificationCompat.Builder(this)
|
|
||||||
.setSmallIcon(R.drawable.ic_stopwatch_24dp)
|
|
||||||
.setOngoing(true)
|
|
||||||
// .setUsesChronometer(true) // No way to pause/resume this native chronometer.
|
|
||||||
.setContentTitle(getString(R.string.stopwatch));
|
|
||||||
Intent intent = new Intent(this, MainActivity.class);
|
|
||||||
intent.putExtra(null/*TODO:MainActivity.EXTRA_SHOW_PAGE*/, 2/*TODO:MainActivity.INDEX_STOPWATCH*/);
|
|
||||||
mNoteBuilder.setContentIntent(PendingIntent.getActivity(this, 0, intent, 0));
|
|
||||||
|
|
||||||
// TODO: Move adding these actions to the default case
|
|
||||||
// TODO: Change fillColor to white, to accommodate API < 21.
|
|
||||||
// Apparently, notifications on 21+ are automatically
|
|
||||||
// tinted to gray to contrast against the native notification background color.
|
|
||||||
addAction(ACTION_ADD_LAP, R.drawable.ic_add_lap_24dp, getString(R.string.lap));
|
|
||||||
// TODO: Set icon and title according to state of stopwatch
|
|
||||||
addAction(ACTION_START_PAUSE, R.drawable.ic_pause_24dp, getString(R.string.pause));
|
|
||||||
addAction(ACTION_STOP, R.drawable.ic_stop_24dp, getString(R.string.stop));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
quitThread();
|
// After being cancelled due to time being up, sometimes the active timer notification posts again
|
||||||
|
// with a static 00:00 text, along with the Time's up notification. My theory is
|
||||||
|
// our thread has enough leeway to sneak in a final call to post the notification before it
|
||||||
|
// is actually quit().
|
||||||
|
// As such, try cancelling the notification with this (tag, id) pair again.
|
||||||
|
cancelNotification(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
protected int getSmallIcon() {
|
||||||
if (intent != null) {
|
return R.drawable.ic_stopwatch_24dp;
|
||||||
final String action = intent.getAction();
|
}
|
||||||
if (action == null) {
|
|
||||||
// TODO: Read the stopwatch's start time in shared prefs.
|
@Nullable
|
||||||
mNoteBuilder.setWhen(System.currentTimeMillis());
|
@Override
|
||||||
// TODO: Lap # content text
|
protected PendingIntent getContentIntent() {
|
||||||
mNoteBuilder.setContentText("Lap 1");
|
Intent intent = new Intent(this, MainActivity.class);
|
||||||
// Use class name as tag instead of defining our own tag constant, because
|
intent.putExtra(null/*TODO:MainActivity.EXTRA_SHOW_PAGE*/, 2/*TODO:MainActivity.INDEX_STOPWATCH*/);
|
||||||
// the latter is limited to 23 (?) chars if you also want to use it as
|
return PendingIntent.getActivity(this, 0, intent, 0);
|
||||||
// a log tag.
|
}
|
||||||
mNotificationManager.notify(getClass().getName(), 0, mNoteBuilder.build());
|
|
||||||
} else {
|
@Override
|
||||||
switch (action) {
|
protected boolean isCountDown() {
|
||||||
case ACTION_ADD_LAP:
|
return false;
|
||||||
// mLapsTableUpdateHandler.asyncInsert(null/*TODO*/);
|
}
|
||||||
break;
|
|
||||||
case ACTION_START_PAUSE:
|
@Override
|
||||||
break;
|
protected void handleDefaultAction(Intent intent, int flags, long startId) {
|
||||||
case ACTION_STOP:
|
// TODO: String resource [Stopwatch: Lap %1$s]. If no laps, just [Stopwatch]
|
||||||
// Cancels all of the notifications issued by *this instance* of the manager,
|
setContentTitle(getString(R.string.stopwatch));
|
||||||
// not those of any other instances (in this app or otherwise).
|
syncNotificationWithStopwatchState(true/*always true*/);
|
||||||
// TODO: We could cancel by (tag, id) if we cared.
|
// We don't need to write anything to SharedPrefs because if we're here, StopwatchFragment
|
||||||
mNotificationManager.cancelAll();
|
// already wrote the necessary values to file.
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
}
|
@Override
|
||||||
|
protected void handleStartPauseAction(Intent intent, int flags, long startId) {
|
||||||
|
// TODO: Tell StopwatchFragment to start/pause itself.. perhaps with an Intent?
|
||||||
|
boolean running = mPrefs.getBoolean(StopwatchFragment.KEY_CHRONOMETER_RUNNING, false);
|
||||||
|
syncNotificationWithStopwatchState(!running);
|
||||||
|
SharedPreferences.Editor editor = mPrefs.edit();
|
||||||
|
editor.putBoolean(StopwatchFragment.KEY_CHRONOMETER_RUNNING, !running);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleStopAction(Intent intent, int flags, long startId) {
|
||||||
|
// TODO: Tell StopwatchFragment to stop itself.. perhaps with an Intent?
|
||||||
|
stopSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleAction(@NonNull String action, Intent intent, int flags, long startId) {
|
||||||
|
if (ACTION_ADD_LAP.equals(action)) {
|
||||||
|
mLapsTableUpdateHandler.asyncInsert(null/*TODO*/);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("StopwatchNotificationService cannot handle action " + action);
|
||||||
}
|
}
|
||||||
return super.onStartCommand(intent, flags, startId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void syncNotificationWithStopwatchState(boolean running) {
|
||||||
public IBinder onBind(Intent intent) {
|
clearActions();
|
||||||
return null;
|
// TODO: Change fillColor to white, to accommodate API < 21.
|
||||||
}
|
// Apparently, notifications on 21+ are automatically
|
||||||
|
// tinted to gray to contrast against the native notification background color.
|
||||||
|
//
|
||||||
|
// No request code needed, so use 0.
|
||||||
|
addAction(ACTION_ADD_LAP, R.drawable.ic_add_lap_24dp, getString(R.string.lap), 0);
|
||||||
|
addStartPauseAction(running, 0);
|
||||||
|
addStopAction(0);
|
||||||
|
|
||||||
/**
|
quitCurrentThread();
|
||||||
* Builds and adds the specified action to the notification's mNoteBuilder.
|
if (running) {
|
||||||
*/
|
// TODO: Read the stopwatch's start time in shared prefs.
|
||||||
private void addAction(String action, @DrawableRes int icon, String actionTitle) {
|
startNewThread(0, SystemClock.elapsedRealtime());
|
||||||
Intent intent = new Intent(this, StopwatchNotificationService.class)
|
|
||||||
.setAction(action);
|
|
||||||
PendingIntent pi = PendingIntent.getService(this, 0/*no requestCode*/,
|
|
||||||
intent, 0/*no flags*/);
|
|
||||||
mNoteBuilder.addAction(icon, actionTitle, pi);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Causes the handler thread's looper to terminate without processing
|
|
||||||
* any more messages in the message queue.
|
|
||||||
*/
|
|
||||||
private void quitThread() {
|
|
||||||
if (mThread != null && mThread.isAlive()) {
|
|
||||||
mThread.quit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
package com.philliphsu.clock2.timers;
|
package com.philliphsu.clock2.timers;
|
||||||
|
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -97,8 +96,7 @@ public class TimerNotificationService extends ChronometerNotificationService {
|
|||||||
// our thread has enough leeway to sneak in a final call to post the notification before it
|
// our thread has enough leeway to sneak in a final call to post the notification before it
|
||||||
// is actually quit().
|
// is actually quit().
|
||||||
// As such, try cancelling the notification with this (tag, id) pair again.
|
// As such, try cancelling the notification with this (tag, id) pair again.
|
||||||
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
cancelNotification(mTimer.getIntId());
|
||||||
nm.cancel(getNoteTag(), mTimer.getIntId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user