Send intent with start/pause action from StopwatchFragment to StopwatchNotificationService
This commit is contained in:
parent
9d0b00d5e7
commit
0f16cebd7c
@ -42,6 +42,7 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
static final String KEY_PAUSE_TIME = "pause_time";
|
static final String KEY_PAUSE_TIME = "pause_time";
|
||||||
static final String KEY_CHRONOMETER_RUNNING = "chronometer_running";
|
static final String KEY_CHRONOMETER_RUNNING = "chronometer_running";
|
||||||
|
|
||||||
|
// TODO: See if we can remove these? Since we save prefs in the notif. service.
|
||||||
private long mStartTime;
|
private long mStartTime;
|
||||||
private long mPauseTime;
|
private long mPauseTime;
|
||||||
private Lap mCurrentLap;
|
private Lap mCurrentLap;
|
||||||
@ -105,7 +106,7 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
// would have hidden the mini FABs, if not for us already setting its
|
// would have hidden the mini FABs, if not for us already setting its
|
||||||
// visibility to invisible in XML. We haven't initialized the WeakReference to
|
// visibility to invisible in XML. We haven't initialized the WeakReference to
|
||||||
// our Activity's FAB yet, so this call does nothing with the FAB.
|
// our Activity's FAB yet, so this call does nothing with the FAB.
|
||||||
updateMiniFabs();
|
setMiniFabsVisible(isStopwatchRunning());
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +137,7 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
// The reason when you open up the app for the first time and scrolling to page 2
|
// The reason when you open up the app for the first time and scrolling to page 2
|
||||||
// doesn't prematurely change the icon is the savedInstanceState is null, and so
|
// doesn't prematurely change the icon is the savedInstanceState is null, and so
|
||||||
// this call would be filtered out sufficiently just from the first check.
|
// this call would be filtered out sufficiently just from the first check.
|
||||||
updateFab();
|
syncFabIconWithStopwatchState(isStopwatchRunning());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +220,12 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFabClick() {
|
public void onFabClick() {
|
||||||
if (mChronometer.isRunning()) {
|
final Intent serviceIntent = new Intent(getActivity(), StopwatchNotificationService.class);
|
||||||
|
|
||||||
|
final boolean running = mChronometer.isRunning();
|
||||||
|
syncFabIconWithStopwatchState(!running/*invert the current state*/);
|
||||||
|
|
||||||
|
if (running) {
|
||||||
mPauseTime = SystemClock.elapsedRealtime();
|
mPauseTime = SystemClock.elapsedRealtime();
|
||||||
mChronometer.stop();
|
mChronometer.stop();
|
||||||
mCurrentLap.pause();
|
mCurrentLap.pause();
|
||||||
@ -239,6 +245,9 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
// we can't start until we compute mStartTime
|
// we can't start until we compute mStartTime
|
||||||
mCurrentLap = new Lap();
|
mCurrentLap = new Lap();
|
||||||
mUpdateHandler.asyncInsert(mCurrentLap);
|
mUpdateHandler.asyncInsert(mCurrentLap);
|
||||||
|
setMiniFabsVisible(true);
|
||||||
|
// Handle the default action, i.e. post the notification for the first time.
|
||||||
|
getActivity().startService(serviceIntent);
|
||||||
}
|
}
|
||||||
mStartTime += SystemClock.elapsedRealtime() - mPauseTime;
|
mStartTime += SystemClock.elapsedRealtime() - mPauseTime;
|
||||||
mPauseTime = 0;
|
mPauseTime = 0;
|
||||||
@ -255,17 +264,15 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
// if (mProgressAnimator != null) {
|
// if (mProgressAnimator != null) {
|
||||||
// mProgressAnimator.resume();
|
// mProgressAnimator.resume();
|
||||||
// }
|
// }
|
||||||
getActivity().startService(new Intent(getActivity(), StopwatchNotificationService.class));
|
|
||||||
}
|
}
|
||||||
savePrefs();
|
serviceIntent.setAction(StopwatchNotificationService.ACTION_START_PAUSE);
|
||||||
// TOneverDO: Precede savePrefs(), or else we don't save false to KEY_CHRONOMETER_RUNNING
|
getActivity().startService(serviceIntent);
|
||||||
/// and updateFab will update the wrong icon.
|
|
||||||
updateAllFabs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPageSelected() {
|
public void onPageSelected() {
|
||||||
updateAllFabs();
|
setMiniFabsVisible(mStartTime > 0);
|
||||||
|
syncFabIconWithStopwatchState(mStartTime > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -300,6 +307,7 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
// This would end up being called twice: here, and in onLoadFinished(), because the
|
// This would end up being called twice: here, and in onLoadFinished(), because the
|
||||||
// table updates will prompt us to requery.
|
// table updates will prompt us to requery.
|
||||||
// startNewProgressBarAnimator();
|
// startNewProgressBarAnimator();
|
||||||
|
// TODO: Start service with ACTION_ADD_LAP
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.stop)
|
@OnClick(R.id.stop)
|
||||||
@ -321,62 +329,23 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
mProgressAnimator.end();
|
mProgressAnimator.end();
|
||||||
}
|
}
|
||||||
mProgressAnimator = null;
|
mProgressAnimator = null;
|
||||||
|
setMiniFabsVisible(false);
|
||||||
|
syncFabIconWithStopwatchState(false);
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------
|
// Remove the notification. This will also write to prefs and clear the laps table.
|
||||||
// TOneverDO: Leave these up to StopwatchNotificationService for ACTION_STOP.
|
|
||||||
// Even though the service calls these for us, we MUST still keep these here;
|
|
||||||
// otherwise, updateAllFabs() won't restore the activity FAB icon back to the start icon.
|
|
||||||
// Possible reasons for why this happens:
|
|
||||||
// * BOTH SharedPreferences.Editor#apply() and #commit() return before the prefs are actually
|
|
||||||
// written to file, so updateAllFabs() is still reading the old value of KEY_CHRONOMETER_RUNNING.
|
|
||||||
// But doesn't #commit() block until the write is complete?
|
|
||||||
// * The SharedPreferences instances between this Fragment and the Service were created with
|
|
||||||
// different Contexts, so editing an instance applies the changes to that Context only. It
|
|
||||||
// is only until a "refresh" occurs (e.g. app restart) that the values are synced between
|
|
||||||
// Contexts?
|
|
||||||
// * Different thread execution orders between the thread used by the Service and the main
|
|
||||||
// thread here? But isn't the Service's handleStopAction() being called by the main thread?
|
|
||||||
// The only worker thread is for updating the notification periodically...
|
|
||||||
mUpdateHandler.asyncClear();
|
|
||||||
savePrefs();
|
|
||||||
// ---------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------
|
|
||||||
// TOneverDO: Precede savePrefs(), or else we don't save false to KEY_CHRONOMETER_RUNNING
|
|
||||||
// and updateFab will update the wrong icon.
|
|
||||||
updateAllFabs();
|
|
||||||
// ---------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Remove the notification. This will also write to prefs and clear the laps table again,
|
|
||||||
// but we probably won't notice a performance penalty...
|
|
||||||
Intent stop = new Intent(getActivity(), StopwatchNotificationService.class)
|
Intent stop = new Intent(getActivity(), StopwatchNotificationService.class)
|
||||||
.setAction(StopwatchNotificationService.ACTION_STOP);
|
.setAction(StopwatchNotificationService.ACTION_STOP);
|
||||||
getActivity().startService(stop);
|
getActivity().startService(stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateAllFabs() {
|
private void setMiniFabsVisible(boolean visible) {
|
||||||
updateMiniFabs();
|
int vis = visible ? View.VISIBLE : View.INVISIBLE;
|
||||||
// TODO: If we're calling this method, then chances are we are visible.
|
|
||||||
// You can verify this yourself by finding all usages.
|
|
||||||
// isVisible() is good for filtering out calls to this method when this Fragment
|
|
||||||
// isn't actually visible to the user; however, a side effect is it also filters
|
|
||||||
// out calls to this method when this Fragment is rotated. Fortunately, we don't
|
|
||||||
// make any calls to this method after a rotation.
|
|
||||||
if (isVisible()) {
|
|
||||||
updateFab();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateMiniFabs() {
|
|
||||||
boolean started = mStartTime > 0;
|
|
||||||
int vis = started ? View.VISIBLE : View.INVISIBLE;
|
|
||||||
mNewLapButton.setVisibility(vis);
|
mNewLapButton.setVisibility(vis);
|
||||||
mStopButton.setVisibility(vis);
|
mStopButton.setVisibility(vis);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateFab() {
|
private void syncFabIconWithStopwatchState(boolean running) {
|
||||||
Log.d(TAG, "Running? " + isStopwatchRunning());
|
mActivityFab.get().setImageDrawable(running ? mPauseDrawable : mStartDrawable);
|
||||||
mActivityFab.get().setImageDrawable(isStopwatchRunning() ? mPauseDrawable : mStartDrawable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startNewProgressBarAnimator() {
|
private void startNewProgressBarAnimator() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user