1

I'm writing a workout app and am trying to implement a rest timer in the Train activity. CountDownTimer located within Train and is called when the user presses a start button.

public CountDownTimer createTimer(long timerDuration) {

    Log.d("new timer duration:", "value: " + timerDuration);
    return new CountDownTimer(timerDuration, 1000) {

        @Override
        public void onTick(long millisUntilFinished) {
            int progress = (int) (millisUntilFinished / 1000);
            secondsLeftOnTimer = progress;  // update variable for rest of app to access

            // Update the output text
            breakTimerOutput.setText(secondsToString(progress));
        }

        @Override
        public void onFinish() { // Play a beep on timer finish
            breakTimerOutput.setText(secondsToString(timerDurationSeconds));
            playAlertSound();  // TODO: Fix the delay before playing beep.
        }
    }.start();
}

The timer works, as long as the user stays in the Train activity. If you switch to another activity, the timer continues to run in the background (the beep still occurs), which is what I want. If you go back to the Train activity, however, the breakTimerOutput TextView is no longer updated by onTick.

How can I "reconnect" breakTimerOutput to onTick when the user re-enters the Train activity?

Here is the full code for the activity, just in case.

Ross Wardrup
  • 311
  • 1
  • 9
  • 26
  • Have you consider onPause and onResume of your Train Activity? – Gilbert Mendoza Dec 30 '16 at 14:26
  • I haven't, but that's an idea. Would I essentially be storing the timer when leaving the activity? I'm new to Android programming so I'm a little rusty on how one would typically handle something like this. – Ross Wardrup Dec 30 '16 at 14:42

1 Answers1

1

I would like to suggest to keep the timer inside a Service and use BroadcastReceiver to receive the tick to update the TextView in your TrainActivity.

You need to start the CountDownTimer from the Service. So in the onCreate method of your Service you need to initialize a LocalBroadcastManager.

broadcastManager = LocalBroadcastManager.getInstance(this);

So on each tick on your timer (i.e. onTick method), you might consider calling a function like this.

static final public String UPDATE_TIME = "UPDATE_TIME";
static final public String UPDATED_TIME = "UPDATED_TIME";

public void updateTextView(String time) {
    Intent intent = new Intent(UPDATE_TIME);
    if(time != null)
        intent.putExtra(UPDATED_TIME, time);
    broadcastManager.sendBroadcast(intent);
}

Now in your TrainActivity create a BroadcastReceiver.

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    super.setContentView(R.layout.copa);
    receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String time = intent.getStringExtra(YourService.UPDATED_TIME);
            // Update your TextView here.
        }
    };
}

And additionally you need to register and unregister the BroadcastReceiver.

@Override
protected void onStart() {
    super.onStart();
    LocalBroadcastManager.getInstance(this).registerReceiver((receiver), 
        new IntentFilter(YourService.UPDATE_TIME)
    );
}

@Override
protected void onStop() {
    LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
    super.onStop();
}
Reaz Murshed
  • 23,691
  • 13
  • 78
  • 98
  • Thanks! This looks good. I'll give it a shot. Am I correct in assuming that the code in your last stanza goes in `Train` activity? – Ross Wardrup Dec 30 '16 at 15:11
  • Yes, the `Receiver` and the `onStart` and `onStop` belongs to `TrainActivity`. – Reaz Murshed Dec 30 '16 at 15:16
  • Thanks! Lastly, I'm to define `receiver` as `BroadcastReceiver receiver`, correct? Doing so seems to cause an issue with your last bit of code, `LocalBroadcastManager.getInstance(this).registerReceiver(receiver), new IntentFilter(BreakTimer.UPDATE_TIME);` – Ross Wardrup Dec 30 '16 at 15:17
  • Yes. You need to create a variable first which is named `receiver`. – Reaz Murshed Dec 30 '16 at 15:21
  • I hate to bug you. I really appreciate your help, but I can't seem to figure it out. I've added the code for the countdown timer to the service but cannot figure out how to start it from the activity. I've never used a service so I don't really know how to access it. [Here's the service](https://gist.github.com/minorsecond/03e392dc8a74462fe4fb9cf3a31e197d). – Ross Wardrup Dec 30 '16 at 15:43