Restore current lap when StopwatchNotificationService is restarted. Change add lap icon fillColor to white.
This commit is contained in:
parent
698892419b
commit
90bdbf2505
@ -31,7 +31,7 @@ public final class AsyncAlarmsTableUpdateHandler extends AsyncDatabaseTableUpdat
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AlarmsTableManager getTableManager(Context context) {
|
protected AlarmsTableManager onCreateTableManager(Context context) {
|
||||||
return new AlarmsTableManager(context);
|
return new AlarmsTableManager(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@ public abstract class AsyncDatabaseTableUpdateHandler<
|
|||||||
public AsyncDatabaseTableUpdateHandler(Context context, ScrollHandler scrollHandler) {
|
public AsyncDatabaseTableUpdateHandler(Context context, ScrollHandler scrollHandler) {
|
||||||
mAppContext = context.getApplicationContext(); // to prevent memory leaks
|
mAppContext = context.getApplicationContext(); // to prevent memory leaks
|
||||||
mScrollHandler = scrollHandler;
|
mScrollHandler = scrollHandler;
|
||||||
mTableManager = getTableManager(context);
|
mTableManager = onCreateTableManager(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void asyncInsert(final T item) {
|
public final void asyncInsert(final T item) {
|
||||||
@ -63,14 +63,15 @@ public abstract class AsyncDatabaseTableUpdateHandler<
|
|||||||
}.execute();
|
}.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final TM getTableManager() {
|
||||||
|
return mTableManager;
|
||||||
|
}
|
||||||
|
|
||||||
protected final Context getContext() {
|
protected final Context getContext() {
|
||||||
return mAppContext;
|
return mAppContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Consider giving a base impl that returns our mTableManager field.
|
protected abstract TM onCreateTableManager(Context context);
|
||||||
// Subclasses will check if this base impl is null before creating and returning
|
|
||||||
// a new instance of the TableManager.
|
|
||||||
protected abstract TM getTableManager(Context context);
|
|
||||||
|
|
||||||
protected abstract void onPostAsyncDelete(Integer result, T item);
|
protected abstract void onPostAsyncDelete(Integer result, T item);
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,7 @@ public final class AsyncTimersTableUpdateHandler extends AsyncDatabaseTableUpdat
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TimersTableManager getTableManager(Context context) {
|
protected TimersTableManager onCreateTableManager(Context context) {
|
||||||
return new TimersTableManager(context);
|
return new TimersTableManager(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ public class AsyncLapsTableUpdateHandler extends AsyncDatabaseTableUpdateHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected LapsTableManager getTableManager(Context context) {
|
protected LapsTableManager onCreateTableManager(Context context) {
|
||||||
return new LapsTableManager(context);
|
return new LapsTableManager(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -43,6 +43,16 @@ public class LapsTableManager extends DatabaseTableManager<Lap> {
|
|||||||
// return cursor;
|
// return cursor;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
public LapCursor queryCurrentLap() {
|
||||||
|
// The default sort order for the laps table is ID descending.
|
||||||
|
// Normally, not specifying a where clause would return all rows.
|
||||||
|
// Here, we limit the result to 1.
|
||||||
|
// This has the effect of retrieving the row with the highest ID value.
|
||||||
|
LapCursor c = queryItems(null, "1");
|
||||||
|
c.moveToFirst();
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getTableName() {
|
protected String getTableName() {
|
||||||
return LapsTable.TABLE_LAPS;
|
return LapsTable.TABLE_LAPS;
|
||||||
|
|||||||
@ -32,10 +32,9 @@ public class StopwatchNotificationService extends ChronometerNotificationService
|
|||||||
super.onCreate();
|
super.onCreate();
|
||||||
mUpdateHandler = new AsyncLapsTableUpdateHandler(this, null);
|
mUpdateHandler = new AsyncLapsTableUpdateHandler(this, null);
|
||||||
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
// TODO: I'm afraid the base time here will be off by a considerable amount from the base time
|
|
||||||
// set in StopwatchFragment.
|
|
||||||
mDelegate.init();
|
mDelegate.init();
|
||||||
mDelegate.setShowCentiseconds(true, false);
|
mDelegate.setShowCentiseconds(true, false);
|
||||||
|
setContentTitle(getString(R.string.stopwatch));
|
||||||
// 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.
|
||||||
}
|
}
|
||||||
@ -46,10 +45,28 @@ public class StopwatchNotificationService extends ChronometerNotificationService
|
|||||||
// signifies that the service is being recreated after its process
|
// signifies that the service is being recreated after its process
|
||||||
// had ended previously.
|
// had ended previously.
|
||||||
if (intent == null) {
|
if (intent == null) {
|
||||||
// Start the ticking again, leaving everything else in the notification
|
|
||||||
// as it was.
|
|
||||||
Log.d(TAG, "Recreated service, starting chronometer again.");
|
Log.d(TAG, "Recreated service, starting chronometer again.");
|
||||||
startChronometer();
|
// Restore the current lap
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// If the service is being restarted, there is AT LEAST one lap in the table.
|
||||||
|
// This is the first lap that was inserted when the service was first started.
|
||||||
|
// The Cursor has already been moved to its first row.
|
||||||
|
mCurrentLap = mUpdateHandler.getTableManager().queryCurrentLap().getItem();
|
||||||
|
Log.d(TAG, "Restored current lap " + mCurrentLap);
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
// Start the ticking again from where we left off.
|
||||||
|
// The default actions will be set on the Builder.
|
||||||
|
//
|
||||||
|
// For simplicity, even if there were laps
|
||||||
|
// in this stopwatch before the process was destroyed, we won't be restoring
|
||||||
|
// the lap number in the title. If the user is leaving this service in the background
|
||||||
|
// long enough that the system can kill its process, they probably aren't
|
||||||
|
// recording laps. As such, a solution for this is a waste of time.
|
||||||
|
boolean running = mPrefs.getBoolean(StopwatchFragment.KEY_CHRONOMETER_RUNNING, false);
|
||||||
|
syncNotificationWithStopwatchState(running);
|
||||||
}
|
}
|
||||||
// If this service is being recreated and the above if-block called through,
|
// If this service is being recreated and the above if-block called through,
|
||||||
// then the call to super won't run any commands, because it will see
|
// then the call to super won't run any commands, because it will see
|
||||||
@ -93,8 +110,6 @@ public class StopwatchNotificationService extends ChronometerNotificationService
|
|||||||
mCurrentLap = new Lap();
|
mCurrentLap = new Lap();
|
||||||
mUpdateHandler.asyncInsert(mCurrentLap);
|
mUpdateHandler.asyncInsert(mCurrentLap);
|
||||||
}
|
}
|
||||||
// TODO: String resource [Stopwatch: Lap %1$s]. If no laps, just [Stopwatch]
|
|
||||||
setContentTitle(getString(R.string.stopwatch));
|
|
||||||
syncNotificationWithStopwatchState(true/*always true*/);
|
syncNotificationWithStopwatchState(true/*always true*/);
|
||||||
// We don't need to write anything to SharedPrefs because if we're here, StopwatchFragment
|
// We don't need to write anything to SharedPrefs because if we're here, StopwatchFragment
|
||||||
// will start this service again with ACTION_START_PAUSE, which will do the writing.
|
// will start this service again with ACTION_START_PAUSE, which will do the writing.
|
||||||
@ -175,10 +190,6 @@ public class StopwatchNotificationService extends ChronometerNotificationService
|
|||||||
|
|
||||||
private void syncNotificationWithStopwatchState(boolean running) {
|
private void syncNotificationWithStopwatchState(boolean running) {
|
||||||
clearActions();
|
clearActions();
|
||||||
// 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.
|
// No request code needed, so use 0.
|
||||||
addAction(ACTION_ADD_LAP, R.drawable.ic_add_lap_24dp, getString(R.string.lap), 0);
|
addAction(ACTION_ADD_LAP, R.drawable.ic_add_lap_24dp, getString(R.string.lap), 0);
|
||||||
addStartPauseAction(running, 0);
|
addStartPauseAction(running, 0);
|
||||||
@ -186,15 +197,17 @@ public class StopwatchNotificationService extends ChronometerNotificationService
|
|||||||
|
|
||||||
quitCurrentThread();
|
quitCurrentThread();
|
||||||
if (running) {
|
if (running) {
|
||||||
startChronometer();
|
// startChronometer();
|
||||||
|
long startTime = mPrefs.getLong(StopwatchFragment.KEY_START_TIME, SystemClock.elapsedRealtime());
|
||||||
|
startNewThread(0, startTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Reads the value of KEY_START_TIME and passes it to {@link #startNewThread(int, long)} for you.
|
// * Reads the value of KEY_START_TIME and passes it to {@link #startNewThread(int, long)} for you.
|
||||||
*/
|
// */
|
||||||
private void startChronometer() {
|
// private void startChronometer() {
|
||||||
long startTime = mPrefs.getLong(StopwatchFragment.KEY_START_TIME, SystemClock.elapsedRealtime());
|
// long startTime = mPrefs.getLong(StopwatchFragment.KEY_START_TIME, SystemClock.elapsedRealtime());
|
||||||
startNewThread(0, startTime);
|
// startNewThread(0, startTime);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,5 +5,5 @@
|
|||||||
android:width="24dp"
|
android:width="24dp"
|
||||||
android:viewportWidth="24"
|
android:viewportWidth="24"
|
||||||
android:viewportHeight="24">
|
android:viewportHeight="24">
|
||||||
<path android:fillColor="#FF000000" android:pathData="M6,3A1,1 0 0,1 7,4V4.88C8.06,4.44 9.5,4 11,4C14,4 14,6 16,6C19,6 20,4 20,4V12C20,12 19,14 16,14C13,14 13,12 11,12C8,12 7,14 7,14V21H5V4A1,1 0 0,1 6,3Z" />
|
<path android:fillColor="#FFFFFF" android:pathData="M6,3A1,1 0 0,1 7,4V4.88C8.06,4.44 9.5,4 11,4C14,4 14,6 16,6C19,6 20,4 20,4V12C20,12 19,14 16,14C13,14 13,12 11,12C8,12 7,14 7,14V21H5V4A1,1 0 0,1 6,3Z" />
|
||||||
</vector>
|
</vector>
|
||||||
Loading…
Reference in New Issue
Block a user