Ross Wardrup
Ross Wardrup

Reputation: 321

Updating TextView with timer onTick after leaving and returning to activity

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.

Upvotes: 1

Views: 633

Answers (1)

Reaz Murshed
Reaz Murshed

Reputation: 24211

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();
}

Upvotes: 1

Related Questions