web-dev-qa-db-fra.com

Pause CountDownTimer dans Android lorsque l'activité n'est pas en avant

J'ai une activité qui utilise un CountDownTimer qui compte à rebours à partir de 10. Comment puis-je mettre ce minuteur en pause lorsque l'activité n'est plus au point, par exemple si l'utilisateur reçoit un appel ou quelque chose, puis reprendre le minuteur lorsque l'utilisateur revient au activité? Est-ce seulement possible?

23
sfrider0

J'ajouterais quelque chose au gestionnaire onTick pour enregistrer la progression du minuteur dans votre classe (nombre de millisecondes restantes).

Dans la méthode onPause () pour l'activité, appelez cancel () sur le minuteur.

Dans la méthode onResume () de l'activité, créez une nouvelle minuterie avec le nombre de millisecondes enregistré.

34
harmanjd

Vous pouvez utiliser pause() pour mettre le minuteur en pause et plus tard démarrer ou reprendre le countDownTimer en appelant start().

/**
 * 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

Pas besoin de créer un nouveau Timer, il suffit de définir le millisUntilFinished = total. Par exemple

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

Vous pouvez essayer d'utiliser 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, "Timer finished", Toast.LENGTH_SHORT).show();


        }
    };

Utilisez hourglass.startTimer(); pour démarrer la minuterie.

Il a des méthodes d'aide qui permettent de mettre en pause et de reprendre le chronomètre.

hourglass.pauseTimer();

ET

hourglass.resumeTimer();
1
Ankush

Cela doit être exactement ce que vous recherchez. La source est ce 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.

Voici le code ci-dessous. Utilisez-le dans vos activités, cela fonctionne très bien.

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