Implement multiple threads and chronometers. Check that StopwatchNotificationService still works.
This commit is contained in:
parent
6c1f10da8d
commit
ced47b7fbe
@ -22,20 +22,18 @@ public abstract class ChronometerNotificationService extends Service {
|
|||||||
public static final String ACTION_START_PAUSE = "com.philliphsu.clock2.timers.action.START_PAUSE";
|
public static final String ACTION_START_PAUSE = "com.philliphsu.clock2.timers.action.START_PAUSE";
|
||||||
public static final String ACTION_STOP = "com.philliphsu.clock2.timers.action.STOP";
|
public static final String ACTION_STOP = "com.philliphsu.clock2.timers.action.STOP";
|
||||||
|
|
||||||
|
public static final String EXTRA_ID = "com.philliphsu.clock2.extra.ID";
|
||||||
|
|
||||||
// TODO: I think we'll need a collection of builders too. However, we can have a common immutable
|
// TODO: I think we'll need a collection of builders too. However, we can have a common immutable
|
||||||
// builder instance with attributes that all timer notifications will have.
|
// builder instance with attributes that all timer notifications will have.
|
||||||
private NotificationCompat.Builder mNoteBuilder;
|
// private NotificationCompat.Builder mNoteBuilder;
|
||||||
private NotificationManager mNotificationManager;
|
private NotificationManager mNotificationManager;
|
||||||
@Deprecated
|
|
||||||
private ChronometerNotificationThread mThread;
|
|
||||||
@Deprecated
|
|
||||||
private final ChronometerDelegate mDelegate = new ChronometerDelegate();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default capacity of an array map is 0.
|
* The default capacity of an array map is 0.
|
||||||
* The minimum amount by which the capacity of a ArrayMap will increase
|
* The minimum amount by which the capacity of a ArrayMap will increase
|
||||||
* is currently {@link SimpleArrayMap#BASE_SIZE 4}.
|
* is currently {@link SimpleArrayMap#BASE_SIZE 4}.
|
||||||
*/
|
*/
|
||||||
|
private final SimpleArrayMap<Long, NotificationCompat.Builder> mNoteBuilders = new SimpleArrayMap<>();
|
||||||
private final SimpleArrayMap<Long, ChronometerNotificationThread> mThreads = new SimpleArrayMap<>();
|
private final SimpleArrayMap<Long, ChronometerNotificationThread> mThreads = new SimpleArrayMap<>();
|
||||||
private final SimpleArrayMap<Long, ChronometerDelegate> mDelegates = new SimpleArrayMap<>();
|
private final SimpleArrayMap<Long, ChronometerDelegate> mDelegates = new SimpleArrayMap<>();
|
||||||
|
|
||||||
@ -94,25 +92,32 @@ public abstract class ChronometerNotificationService extends Service {
|
|||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
// Create base note
|
|
||||||
mNoteBuilder = new NotificationCompat.Builder(this)
|
|
||||||
.setSmallIcon(getSmallIcon())
|
|
||||||
.setShowWhen(false)
|
|
||||||
.setOngoing(true)
|
|
||||||
.setContentIntent(getContentIntent());
|
|
||||||
if (isForeground()) {
|
if (isForeground()) {
|
||||||
|
registerNewNoteBuilder(getNoteId());
|
||||||
registerNewChronometer(getNoteId());
|
registerNewChronometer(getNoteId());
|
||||||
startForeground(getNoteId(), mNoteBuilder.build());
|
// IGNORE THE LINT WARNING ABOUT UNNECESSARY BOXING. Because getNoteId() returns an int,
|
||||||
|
// it gets boxed to an Integer. A Long and an Integer are never interchangeable, even
|
||||||
|
// if they wrap the same integer value.
|
||||||
|
startForeground(getNoteId(), mNoteBuilders.get(Long.valueOf(getNoteId())).build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerNewChronometer(long id) {
|
protected final void registerNewChronometer(long id) {
|
||||||
ChronometerDelegate delegate = new ChronometerDelegate();
|
ChronometerDelegate delegate = new ChronometerDelegate();
|
||||||
delegate.init();
|
delegate.init();
|
||||||
delegate.setCountDown(isCountDown());
|
delegate.setCountDown(isCountDown());
|
||||||
mDelegates.put(id, delegate);
|
mDelegates.put(id, delegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected final void registerNewNoteBuilder(long id) {
|
||||||
|
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
|
||||||
|
.setSmallIcon(getSmallIcon())
|
||||||
|
.setShowWhen(false)
|
||||||
|
.setOngoing(true)
|
||||||
|
.setContentIntent(getContentIntent());
|
||||||
|
mNoteBuilders.put(id, builder);
|
||||||
|
}
|
||||||
|
|
||||||
// Didn't work!
|
// Didn't work!
|
||||||
// @Override
|
// @Override
|
||||||
// public void onTrimMemory(int level) {
|
// public void onTrimMemory(int level) {
|
||||||
@ -132,8 +137,10 @@ public abstract class ChronometerNotificationService extends Service {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
// TODO: Quit all threads by iterating through the collection
|
for (int i = 0; i < mThreads.size(); i++) {
|
||||||
quitThread(); // TOneverDO: quitCurrentThread() because that posts the notification again
|
// TOneverDO: quitCurrentThread() because that posts the notification again
|
||||||
|
quitThread(mThreads.keyAt(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@CallSuper
|
@CallSuper
|
||||||
@ -171,17 +178,18 @@ public abstract class ChronometerNotificationService extends Service {
|
|||||||
* If there is a thread currently running, then this will push any notification updates
|
* If there is a thread currently running, then this will push any notification updates
|
||||||
* you might have configured in the Builder and then call the thread's {@link
|
* you might have configured in the Builder and then call the thread's {@link
|
||||||
* ChronometerNotificationThread#quit() quit()}.
|
* ChronometerNotificationThread#quit() quit()}.
|
||||||
|
* @param id the id associated with the thread to quit
|
||||||
*/
|
*/
|
||||||
// TODO: rename method to quitThread(long id)
|
public void quitCurrentThread(long id) {
|
||||||
public void quitCurrentThread() {
|
ChronometerNotificationThread thread = mThreads.get(id);
|
||||||
if (mThread != null) {
|
if (thread != null) {
|
||||||
// Display any notification updates associated with the current state
|
// Display any notification updates associated with the current state
|
||||||
// of the chronometer. If we relied on the HandlerThread to do this for us,
|
// of the chronometer. If we relied on the HandlerThread to do this for us,
|
||||||
// the message delivery would be delayed.
|
// the message delivery would be delayed.
|
||||||
mThread.updateNotification(false/*updateText*/);
|
thread.updateNotification(/*TODO:pass in id*/false/*updateText*/);
|
||||||
// If the chronometer has been set to not run, the effect is obvious.
|
// If the chronometer has been set to not run, the effect is obvious.
|
||||||
// Otherwise, we're preparing for the start of a new thread.
|
// Otherwise, we're preparing for the start of a new thread.
|
||||||
quitThread();
|
quitThread(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,116 +197,130 @@ public abstract class ChronometerNotificationService extends Service {
|
|||||||
* Instantiates a new HandlerThread and calls its {@link Thread#start() start()}.
|
* Instantiates a new HandlerThread and calls its {@link Thread#start() start()}.
|
||||||
* The calling thread will be blocked until the HandlerThread created here finishes
|
* The calling thread will be blocked until the HandlerThread created here finishes
|
||||||
* initializing its looper.
|
* initializing its looper.
|
||||||
|
* @param id
|
||||||
* @param base the new base time of the chronometer
|
* @param base the new base time of the chronometer
|
||||||
*/
|
*/
|
||||||
// TODO: Change sig to (long id, long base)
|
public void startNewThread(long id, long base) {
|
||||||
public void startNewThread(long base) {
|
|
||||||
// An instance of Thread cannot be started more than once. You must create
|
// An instance of Thread cannot be started more than once. You must create
|
||||||
// a new instance if you want to start the Thread's work again.
|
// a new instance if you want to start the Thread's work again.
|
||||||
mThread = new ChronometerNotificationThread(
|
ChronometerNotificationThread thread = new ChronometerNotificationThread(
|
||||||
mDelegate,
|
mDelegates.get(id),
|
||||||
mNotificationManager,
|
mNotificationManager,
|
||||||
mNoteBuilder,
|
mNoteBuilders.get(id),
|
||||||
getResources(),
|
getResources(),
|
||||||
getNoteId());
|
getNoteId());
|
||||||
|
mThreads.put(id, thread);
|
||||||
// Initializes this thread as a looper. HandlerThread.run() will be executed
|
// Initializes this thread as a looper. HandlerThread.run() will be executed
|
||||||
// in this thread.
|
// in this thread.
|
||||||
// This gives you a chance to create handlers that then reference this looper,
|
// This gives you a chance to create handlers that then reference this looper,
|
||||||
// before actually starting the loop.
|
// before actually starting the loop.
|
||||||
mThread.start();
|
thread.start();
|
||||||
// If this thread has been started, this method will block *the calling thread*
|
// If this thread has been started, this method will block *the calling thread*
|
||||||
// until the looper has been initialized. This ensures the handler thread is
|
// until the looper has been initialized. This ensures the handler thread is
|
||||||
// fully initialized before we proceed.
|
// fully initialized before we proceed.
|
||||||
mThread.getLooper();
|
thread.getLooper();
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
// TOneverDO: Set base BEFORE the thread is ready to begin working, or else when
|
// TOneverDO: Set base BEFORE the thread is ready to begin working, or else when
|
||||||
// the thread actually begins working, it will initially show that some time has
|
// the thread actually begins working, it will initially show that some time has
|
||||||
// passed.
|
// passed.
|
||||||
mDelegate.setBase(base);
|
ChronometerDelegate delegate = mDelegates.get(id);
|
||||||
|
delegate.setBase(base);
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to add the start/pause action to the notification's builder.
|
* Helper method to add the start/pause action to the notification's builder.
|
||||||
* @param running whether the chronometer is running
|
* @param running whether the chronometer is running
|
||||||
* @param requestCode Used to create the PendingIntent that is fired when this action is clicked.
|
* @param id The id of the notification that the action should be added to.
|
||||||
|
* Will be used as an integer request code to create the PendingIntent that
|
||||||
|
* is fired when this action is clicked.
|
||||||
*/
|
*/
|
||||||
protected final void addStartPauseAction(boolean running, int requestCode/*TODO: long id. as a request code, cast down.*/) {
|
protected final void addStartPauseAction(boolean running, long id) {
|
||||||
// TODO: Add this to the correct Builder, associated with the provided long id.
|
|
||||||
addAction(ACTION_START_PAUSE,
|
addAction(ACTION_START_PAUSE,
|
||||||
running ? R.drawable.ic_pause_24dp : R.drawable.ic_start_24dp,
|
running ? R.drawable.ic_pause_24dp : R.drawable.ic_start_24dp,
|
||||||
getString(running ? R.string.pause : R.string.resume),
|
getString(running ? R.string.pause : R.string.resume),
|
||||||
requestCode);
|
id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to add the stop action to the notification's builder.
|
* Helper method to add the stop action to the notification's builder.
|
||||||
* @param requestCode Used to create the PendingIntent that is fired when this action is clicked.
|
* @param id The id of the notification that the action should be added to.
|
||||||
|
* Will be used as an integer request code to create the PendingIntent that
|
||||||
|
* is fired when this action is clicked.
|
||||||
*/
|
*/
|
||||||
protected final void addStopAction(int requestCode/*TODO: long id. as a request code, cast down.*/) {
|
protected final void addStopAction(long id) {
|
||||||
addAction(ACTION_STOP, R.drawable.ic_stop_24dp, getString(R.string.stop), requestCode);
|
addAction(ACTION_STOP, R.drawable.ic_stop_24dp, getString(R.string.stop), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the notification builder's set actions.
|
* Clear the notification builder's set actions.
|
||||||
|
* @param id the id associated with the builder whose actions should be cleared
|
||||||
*/
|
*/
|
||||||
protected final void clearActions(/*TODO: long id*/) {
|
protected final void clearActions(long id) {
|
||||||
// TODO: Clear the actions from the correct builder.
|
|
||||||
// TODO: The source indicates mActions is hidden, so how are we able to access it?
|
// TODO: The source indicates mActions is hidden, so how are we able to access it?
|
||||||
// Will it remain accessible for all SDK versions? If not, we would have to rebuild
|
// Will it remain accessible for all SDK versions? If not, we would have to rebuild
|
||||||
// the entire notification with a new local Builder instance.
|
// the entire notification with a new local Builder instance.
|
||||||
mNoteBuilder.mActions.clear();
|
mNoteBuilders.get(id).mActions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: We'll need to change the signatures of all these to have a long id param.
|
/**
|
||||||
protected final void setBase(long base) {
|
* @param id The id associated with the chronometer that you wish to modify.
|
||||||
mDelegate.setBase(base);
|
*/
|
||||||
|
protected final void setBase(long id, long base) {
|
||||||
|
mDelegates.get(id).setBase(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final long getBase() {
|
/**
|
||||||
return mDelegate.getBase();
|
* @param id The id associated with the chronometer that you wish to modify.
|
||||||
|
*/
|
||||||
|
protected final long getBase(long id) {
|
||||||
|
return mDelegates.get(id).getBase();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final void updateNotification(boolean updateText) {
|
/**
|
||||||
mThread.updateNotification(updateText);
|
* @param id The id associated with the thread that should update the notification.
|
||||||
|
*/
|
||||||
|
protected final void updateNotification(long id, boolean updateText) {
|
||||||
|
mThreads.get(id).updateNotification(updateText);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final void setContentTitle(CharSequence title) {
|
/**
|
||||||
mNoteBuilder.setContentTitle(title);
|
* @param id The id associated with the builder that should update its content title.
|
||||||
|
*/
|
||||||
|
protected final void setContentTitle(long id, CharSequence title) {
|
||||||
|
mNoteBuilders.get(id).setContentTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the specified action to the notification's Builder.
|
* Adds the specified action to the notification's Builder.
|
||||||
|
* @param id The id of the notification that the action should be added to.
|
||||||
|
* Will be used as an integer request code to create the PendingIntent that
|
||||||
|
* is fired when this action is clicked.
|
||||||
*/
|
*/
|
||||||
protected final void addAction(String action, @DrawableRes int icon, String actionTitle, int requestCode/*TODO: long id. as a request code, cast down.*/) {
|
protected final void addAction(String action, @DrawableRes int icon, String actionTitle, long id) {
|
||||||
Intent intent = new Intent(this, getClass())
|
Intent intent = new Intent(this, getClass())
|
||||||
.setAction(action);
|
.setAction(action)
|
||||||
// TODO: We can put the requestCode as an extra to this intent, and then retrieve that extra
|
.putExtra(EXTRA_ID, id);
|
||||||
// in onStartCommand() to figure out which of the multiple timers should we apply this action to.
|
|
||||||
// .putExtra(EXTRA_TIMER, mTimer);
|
|
||||||
PendingIntent pi = PendingIntent.getService(
|
PendingIntent pi = PendingIntent.getService(
|
||||||
this, requestCode, intent, 0/*no flags*/);
|
this, (int) id, intent, 0/*no flags*/);
|
||||||
mNoteBuilder.addAction(icon, actionTitle, pi);
|
mNoteBuilders.get(id).addAction(icon, actionTitle, pi);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels the foreground notification.
|
* Cancels the notification associated with the ID.
|
||||||
*/
|
*/
|
||||||
// TODO: change sig to long id
|
protected final void cancelNotification(long id/*TODO: change to int noteId?*/) {
|
||||||
protected final void cancelNotification() {
|
mNotificationManager.cancel((int) id);
|
||||||
mNotificationManager.cancel(getNoteId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
*/
|
*/
|
||||||
// TODO: change sig to long id
|
private void quitThread(long id) {
|
||||||
private void quitThread() {
|
ChronometerNotificationThread thread = mThreads.get(id);
|
||||||
if (mThread != null && mThread.isAlive()) {
|
if (thread != null && thread.isAlive()) {
|
||||||
mThread.quit();
|
thread.quit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,7 @@ public class StopwatchNotificationService extends ChronometerNotificationService
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
setContentTitle(getString(R.string.stopwatch));
|
setContentTitle(getNoteId(), getString(R.string.stopwatch));
|
||||||
mUpdateHandler = new AsyncLapsTableUpdateHandler(this, null);
|
mUpdateHandler = new AsyncLapsTableUpdateHandler(this, null);
|
||||||
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
mDelegate.init();
|
mDelegate.init();
|
||||||
@ -72,11 +72,6 @@ public class StopwatchNotificationService extends ChronometerNotificationService
|
|||||||
return super.onStartCommand(intent, flags, startId);
|
return super.onStartCommand(intent, flags, startId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getSmallIcon() {
|
protected int getSmallIcon() {
|
||||||
return R.drawable.ic_stopwatch_24dp;
|
return R.drawable.ic_stopwatch_24dp;
|
||||||
@ -180,26 +175,23 @@ public class StopwatchNotificationService extends ChronometerNotificationService
|
|||||||
if (lapNumber == 0) {
|
if (lapNumber == 0) {
|
||||||
Log.w(TAG, "Lap number was not passed in with intent");
|
Log.w(TAG, "Lap number was not passed in with intent");
|
||||||
}
|
}
|
||||||
// Unfortunately, the ID is only assigned when retrieving a Lap instance from
|
setContentTitle(getNoteId(), getString(R.string.stopwatch_and_lap_number, lapNumber));
|
||||||
// its cursor; the value here will always be 0.
|
updateNotification(getNoteId(), true);
|
||||||
setContentTitle(getString(R.string.stopwatch_and_lap_number, lapNumber));
|
|
||||||
updateNotification(true);
|
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("StopwatchNotificationService cannot handle action " + action);
|
throw new IllegalArgumentException("StopwatchNotificationService cannot handle action " + action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void syncNotificationWithStopwatchState(boolean running) {
|
private void syncNotificationWithStopwatchState(boolean running) {
|
||||||
clearActions();
|
clearActions(getNoteId());
|
||||||
// No request code needed, so use 0.
|
addAction(ACTION_ADD_LAP, R.drawable.ic_add_lap_24dp, getString(R.string.lap), getNoteId());
|
||||||
addAction(ACTION_ADD_LAP, R.drawable.ic_add_lap_24dp, getString(R.string.lap), 0);
|
addStartPauseAction(running, getNoteId());
|
||||||
addStartPauseAction(running, 0);
|
addStopAction(getNoteId());
|
||||||
addStopAction(0);
|
|
||||||
|
|
||||||
quitCurrentThread();
|
quitCurrentThread(getNoteId());
|
||||||
if (running) {
|
if (running) {
|
||||||
long startTime = mPrefs.getLong(StopwatchFragment.KEY_START_TIME, SystemClock.elapsedRealtime());
|
long startTime = mPrefs.getLong(StopwatchFragment.KEY_START_TIME, SystemClock.elapsedRealtime());
|
||||||
startNewThread(startTime);
|
startNewThread(getNoteId(), startTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -108,7 +108,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.
|
||||||
cancelNotification();
|
cancelNotification(getNoteId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -126,7 +126,7 @@ public class TimerNotificationService extends ChronometerNotificationService {
|
|||||||
if (title.isEmpty()) {
|
if (title.isEmpty()) {
|
||||||
title = getString(R.string.timer);
|
title = getString(R.string.timer);
|
||||||
}
|
}
|
||||||
setContentTitle(title);
|
setContentTitle(mTimer.getId(), title);
|
||||||
syncNotificationWithTimerState(mTimer.isRunning());
|
syncNotificationWithTimerState(mTimer.isRunning());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,8 +150,9 @@ public class TimerNotificationService extends ChronometerNotificationService {
|
|||||||
// While the notification's countdown would automatically be extended by one minute,
|
// While the notification's countdown would automatically be extended by one minute,
|
||||||
// there is a noticeable delay before the minute gets added on.
|
// there is a noticeable delay before the minute gets added on.
|
||||||
// Update the text immediately, because there's no harm in doing so.
|
// Update the text immediately, because there's no harm in doing so.
|
||||||
setBase(getBase() + 60000);
|
long id = intent.getLongExtra(EXTRA_ID, -1);
|
||||||
updateNotification(true);
|
setBase(id, getBase(id) + 60000);
|
||||||
|
updateNotification(id, true);
|
||||||
mController.addOneMinute();
|
mController.addOneMinute();
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("TimerNotificationService cannot handle action " + action);
|
throw new IllegalArgumentException("TimerNotificationService cannot handle action " + action);
|
||||||
@ -162,8 +163,8 @@ public class TimerNotificationService extends ChronometerNotificationService {
|
|||||||
// The actions from the last time we configured the Builder are still here.
|
// The actions from the last time we configured the Builder are still here.
|
||||||
// We have to retain the relative ordering of the actions while updating
|
// We have to retain the relative ordering of the actions while updating
|
||||||
// just the start/pause action, so clear them and set them again.
|
// just the start/pause action, so clear them and set them again.
|
||||||
clearActions();
|
final long timerId = mTimer.getId();
|
||||||
final int timerId = mTimer.getIntId();
|
clearActions(timerId);
|
||||||
addAction(ACTION_ADD_ONE_MINUTE,
|
addAction(ACTION_ADD_ONE_MINUTE,
|
||||||
R.drawable.ic_add_24dp,
|
R.drawable.ic_add_24dp,
|
||||||
getString(R.string.minute),
|
getString(R.string.minute),
|
||||||
@ -171,9 +172,9 @@ public class TimerNotificationService extends ChronometerNotificationService {
|
|||||||
addStartPauseAction(running, timerId);
|
addStartPauseAction(running, timerId);
|
||||||
addStopAction(timerId);
|
addStopAction(timerId);
|
||||||
|
|
||||||
quitCurrentThread();
|
quitCurrentThread(getNoteId());
|
||||||
if (running) {
|
if (running) {
|
||||||
startNewThread(SystemClock.elapsedRealtime() + mTimer.timeRemaining());
|
startNewThread(getNoteId(), SystemClock.elapsedRealtime() + mTimer.timeRemaining());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user