web-dev-qa-db-ja.com

AndroidでCountDownTimerを一時停止して、アクティビティが前面にない場合

10からカウントダウンするCountDownTimerを使用するアクティビティがあります。ユーザーが電話や何かを受け取った場合など、アクティビティがフォーカスされなくなったときにタイマーを一時停止し、ユーザーがアクティビティ?これは可能ですか?

23
sfrider0

OnTickハンドラーに何かを追加して、クラスのタイマーの進行状況を保存します(残りのミリ秒数)。

アクティビティのonPause()メソッドで、タイマーのcancel()を呼び出します。

アクティビティのonResume()メソッドで、保存されたミリ秒数を残して新しいタイマーを作成します。

34
harmanjd

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;
    }
}
27

新しい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();
    }
17
worked

砂時計 を使用してみることができます

_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, "Timer finished", Toast.LENGTH_SHORT).show();


        }
    };
_

タイマーを開始するには、hourglass.startTimer();を使用します。

タイマーを一時停止および再開できるヘルパーメソッドがあります。

_hourglass.pauseTimer();
_

そして

_hourglass.resumeTimer();
_
1
Ankush

これはまさにあなたが探しているものでなければなりません。ソースは 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);
                    }
                }
            }
        }
    }
};
}
1
Shubham A.

これが以下のコードです。正常に動作するアクティビティで使用してください。

public class MainActivity extends AppCompatActivity {

    TextView textview;
    final static long INTERVAL = 1000;
    final static long TIMEOUT = 11000;
    static long millisecondsleft;
    boolean isPause =false;

    CountDownTimer countDownTimer;
    CountDownTimer countDownTimeronResume;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textview=findViewById(R.id.textviewcheck);
 }

    @Override
    protected void onResume() {
        super.onResume();

       if(isPause == false) {
           countDownTimer = new CountDownTimer(TIMEOUT, INTERVAL) {
               @Override
               public void onTick(long millisUntilFinished) {
                   millisecondsleft = millisUntilFinished;
                   textview.setText(":" + String.format("%02d", millisUntilFinished / 1000));
               }

               @Override
               public void onFinish() {

                   textview.setText("DONE!");
               }
           }.start();

       } else{
                     countDownTimeronResume = new CountDownTimer(millisecondsleft, INTERVAL) {
                       @Override
                       public void onTick(long millisUntilFinished) {
                           Toast.makeText(MainActivity.this, "ONPAUSED", Toast.LENGTH_SHORT).show();
                           millisecondsleft = millisUntilFinished;
                           textview.setText(":" + String.format("%02d", millisUntilFinished / 1000));
                       }

                       @Override
                       public void onFinish() {
                           textview.setText("DONE!");

                       }
                   }.start();
         }


    }

    @Override
    protected void onPause() {
        super.onPause();

        if(countDownTimer!=null){
            countDownTimer.cancel();
            isPause = true;
        }
       if(countDownTimeronResume!=null){
            countDownTimeronResume.cancel();
       }
    }
}
0
Getnet