当活动不在前面时,在Android中暂停CountDownTimer

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当活动不在前面时,在Android中暂停CountDownTimer相关的知识,希望对你有一定的参考价值。

我有一个使用从10开始倒计时的CountDownTimer的活动。当活动不再处于焦点时如何暂停该计时器,如用户接到电话或其他内容,然后在用户返回时恢复计时器活动?这甚至可能吗?

答案

我会在onTick处理程序中添加一些东西来保存你的类中的计时器进度(剩下的毫秒数)。

在onPause()方法中为活动调用计时器上的cancel()。

在活动的onResume()方法中,创建一个新的计时器,保留剩余的毫秒数。

另一答案

您可以使用pause()暂停计时器,稍后通过调用start()启动或恢复countDownTimer。

/**
 * This class uses the native CountDownTimer to 
 * create a timer which could be paused and then
 * started again from the previous point. You can 
 * provide implementation for onTick() and onFinish()
 * then use it in your projects.
 */
public abstract class CountDownTimerPausable {
    long millisInFuture = 0;
    long countDownInterval = 0;
    long millisRemaining =  0;

    CountDownTimer countDownTimer = null;

    boolean isPaused = true;

    public CountDownTimerPausable(long millisInFuture, long countDownInterval) {
        super();
        this.millisInFuture = millisInFuture;
        this.countDownInterval = countDownInterval;
        this.millisRemaining = this.millisInFuture;
    }
    private void createCountDownTimer(){
        countDownTimer = new CountDownTimer(millisRemaining,countDownInterval) {

            @Override
            public void onTick(long millisUntilFinished) {
                millisRemaining = millisUntilFinished;
                CountDownTimerPausable.this.onTick(millisUntilFinished);

            }

            @Override
            public void onFinish() {
                CountDownTimerPausable.this.onFinish();

            }
        };
    }
    /**
     * Callback fired on regular interval.
     * 
     * @param millisUntilFinished The amount of time until finished. 
     */
    public abstract void onTick(long millisUntilFinished);
    /**
     * Callback fired when the time is up. 
     */
    public abstract void onFinish();
    /**
     * Cancel the countdown.
     */
    public final void cancel(){
        if(countDownTimer!=null){
            countDownTimer.cancel();
        }
        this.millisRemaining = 0;
    }
    /**
     * Start or Resume the countdown. 
     * @return CountDownTimerPausable current instance
     */
    public synchronized final CountDownTimerPausable start(){
        if(isPaused){
            createCountDownTimer();
            countDownTimer.start();
            isPaused = false;
        }
        return this;
    }
    /**
     * Pauses the CountDownTimerPausable, so it could be resumed(start)
     * later from the same point where it was paused.
     */
    public void pause()throws IllegalStateException{
        if(isPaused==false){
            countDownTimer.cancel();
        } else{
            throw new IllegalStateException("CountDownTimerPausable is already in pause state, start counter before pausing it.");
        }
        isPaused = true;
    }
    public boolean isPaused() {
        return isPaused;
    }
}
另一答案

无需创建新的Timer,只需设置millisUntilFinished = total即可。例如

private CountDownTimer cdTimer;
private long total = 30000;

        ...
        toggleButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view){
                if(toggleButton.isChecked()) {
                    startCountDownTimer();
                }else{
                    cdTimer.cancel();
                }
            }
        });
        ...

    private void startCountDownTimer() {
        cdTimer = new CountDownTimer(total, 1000) {
            public void onTick(long millisUntilFinished) {
                //update total with the remaining time left
                total = millisUntilFinished;
                nTimeLabel.setText("seconds remaining: " +  millisUntilFinished/ 1000);
            }
            public void onFinish() {
                nTimeLabel.setText("done!");
            }
        }.start();
    }
另一答案

这一定是你正在寻找的。来源是this Gist.

package alt.android.os;

import android.os.Handler;
import android.os.SystemClock;
import android.os.Message;

public abstract class CountDownTimer {

/**
 * Millis since epoch when alarm should stop.
 */
private final long mMillisInFuture;

/**
 * The interval in millis that the user receives callbacks
 */
private final long mCountdownInterval;

private long mStopTimeInFuture;

private long mPauseTime;

private boolean mCancelled = false;

private boolean mPaused = false;

/**
 * @param millisInFuture The number of millis in the future from the call
 *   to {@link #start()} until the countdown is done and {@link #onFinish()}
 *   is called.
 * @param countDownInterval The interval along the way to receive
 *   {@link #onTick(long)} callbacks.
 */
public CountDownTimer(long millisInFuture, long countDownInterval) {
    mMillisInFuture = millisInFuture;
    mCountdownInterval = countDownInterval;
}

/**
 * Cancel the countdown.
 *
 * Do not call it from inside CountDownTimer threads
 */
public final void cancel() {
    mHandler.removeMessages(MSG);
    mCancelled = true;
}

/**
 * Start the countdown.
 */
public synchronized final CountDownTimer start() {
    if (mMillisInFuture <= 0) {
        onFinish();
        return this;
    }
    mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
    mHandler.sendMessage(mHandler.obtainMessage(MSG));
    mCancelled = false;
    mPaused = false;
    return this;
}

/**
 * Pause the countdown.
 */
public long pause() {
    mPauseTime = mStopTimeInFuture - SystemClock.elapsedRealtime();
    mPaused = true;
    return mPauseTime;
}

/**
 * Resume the countdown.
 */
public long resume() {
    mStopTimeInFuture = mPauseTime + SystemClock.elapsedRealtime();
    mPaused = false;
    mHandler.sendMessage(mHandler.obtainMessage(MSG));
    return mPauseTime;
}

/**
 * Callback fired on regular interval.
 * @param millisUntilFinished The amount of time until finished.
 */
public abstract void onTick(long millisUntilFinished);

/**
 * Callback fired when the time is up.
 */
public abstract void onFinish();


private static final int MSG = 1;


// handles counting down
private Handler mHandler = new Handler() {

    @Override
    public void handleMessage(Message msg) {

        synchronized (CountDownTimer.this) {
            if (!mPaused) {
                final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();

                if (millisLeft <= 0) {
                    onFinish();
                } else if (millisLeft < mCountdownInterval) {
                    // no tick, just delay until done
                    sendMessageDelayed(obtainMessage(MSG), millisLeft);
                } else {
                    long lastTickStart = SystemClock.elapsedRealtime();
                    onTick(millisLeft);

                    // take into account user's onTick taking time to execute
                    long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();

                    // special case: user's onTick took more than interval to
                    // complete, skip to next interval
                    while (delay < 0) delay += mCountdownInterval;

                    if (!mCancelled) {
                        sendMessageDelayed(obtainMessage(MSG), delay);
                    }
                }
            }
        }
    }
};
}
另一答案

你可以尝试使用Hourglass

Hourglass hourglass = new Hourglass(50000, 1000) {
        @Override
        public void onTimerTick(long timeRemaining) {
            // Update UI
            Toast.show(MainActivity.this, String.valueOf(timeRemaining), Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onTimerFinish() {
            // Timer finished
            Toast.show(MainActivity.this, "Time

以上是关于当活动不在前面时,在Android中暂停CountDownTimer的主要内容,如果未能解决你的问题,请参考以下文章

使用完成按钮单击关闭 android 活动(完全,甚至不在后台)

当我的活动不可见时,如何在 Android WebView 中暂停 Flash 内容?

android的生命周期

当活动暂停时,如何正确停止倒数计时器中的媒体播放器?

Android - 如何在应用程序内保持音乐播放?

在 android Studio 中,我希望当我点击按钮时,下一个活动/片段应该来自右侧