Галочка обратного отсчета андроида не точна

Я использую таймер обратного отсчета для звукового уведомления … и это не точно с самого начала …

С использованием начальных параметров

private final long startCountDown; private final long intervalCountDown; ... startCountDown = 180 * 1000; // 3 mns - to be set from Preferences later intervalCountDown = 60 * 1000; // 1 mns - to be set from Preferences later ... public void onTick(long millisUntilFinished) { Log.d(TAG, "notify countDown: " + millisUntilFinished + " msecs"); } countDownTimer = new SwimCountDownTimer(startCountDown,intervalCountDown); .... public void startCountDown() { Log.d(TAG, "start countDown for " + startCountDown + " msecs" ); countDownTimer.start(); } 

Я вижу в журнале, что начальный обратный отсчет правильно установлен на 180000, но следующий должен быть 120000, и он установлен в 119945 !!!

 04-27 14:50:42.146: I/SWIMMER(8670): notify countDown: 180000 msecs 04-27 14:51:42.206: I/SWIMMER(8670): notify countDown: 119945 msecs 

Это довольно раздражает, так как звуковой уведомитель ожидает сказать только «2 минуты», а не «1 минута и пятьдесят девять секунд» …, почему интервал не прав …? Я могу сделать это, установив текст К строке речи … но есть ли способ получить правильные данные?

Спасибо за предложения

Я знаю, что это старый вопрос, но я также столкнулся с этой проблемой и думал, что поделюсь своим решением.

Apperantly CountDownTimer не очень точен, поэтому я решил реализовать более длительный таймер обратного отсчета, используя java.util.Timer:

 public abstract class PreciseCountdown extends Timer { private long totalTime, interval, delay; private TimerTask task; private long startTime = -1; private boolean restart = false, wasCancelled = false, wasStarted = false; public PreciseCountdown(long totalTime, long interval) { this(totalTime, interval, 0); } public PreciseCountdown(long totalTime, long interval, long delay) { super("PreciseCountdown", true); this.delay = delay; this.interval = interval; this.totalTime = totalTime; this.task = getTask(totalTime); } public void start() { wasStarted = true; this.scheduleAtFixedRate(task, delay, interval); } public void restart() { if(!wasStarted) { start(); } else if(wasCancelled) { wasCancelled = false; this.task = getTask(totalTime); start(); } else{ this.restart = true; } } public void stop() { this.wasCancelled = true; this.task.cancel(); } // Call this when there's no further use for this timer public void dispose(){ cancel(); purge(); } private TimerTask getTask(final long totalTime) { return new TimerTask() { @Override public void run() { long timeLeft; if (startTime < 0 || restart) { startTime = scheduledExecutionTime(); timeLeft = totalTime; restart = false; } else { timeLeft = totalTime - (scheduledExecutionTime() - startTime); if (timeLeft <= 0) { this.cancel(); startTime = -1; onFinished(); return; } } onTick(timeLeft); } }; } public abstract void onTick(long timeLeft); public abstract void onFinished(); } 

Пример использования:

 this.countDown = new PreciseCountdown(totalTime, interval, delay) { @Override public void onTick(long timeLeft) { // update.. // note that this runs on a different thread, so to update any GUI components you need to use Activity.runOnUiThread() } @Override public void onFinished() { onTick(0); // when the timer finishes onTick isn't called // count down is finished } }; 

Для начала обратного отсчета просто вызовите countDown.start (). CountDown.stop () останавливает countDown, который можно перезапустить с помощью countDown.restart ().

Надеюсь, что это любая помощь для любого в будущем.