How come millisUntilFinished cannot detect exact C

2019-01-20 13:53发布

问题:

Hey all, so there is a rather small but annoying problem with the CountDownTimer.. Currently I have an interval set to 1000. And I am trying to detect the amount of milliseconds left in my

onTick()

method. So that I can use Text To Speech when there are 20 seconds left, 10 seconds left, etc. Well if I use:

//Speak when 20 seconds left
if (millisUntilFinished == 20000) {
    tts.speak("You have 20 seconds left.", TextToSpeech.QUEUE_FLUSH, null);
}

The timer is not able to detect the 20000 milliseconds exactly.

So I have to resort to using:

//Speak when 20 seconds left
if (millisUntilFinished < 20999) {
    if (millisUntilFinished > 19999) {
       tts.speak("You have 20 seconds left.", TextToSpeech.QUEUE_FLUSH, null);
     } 
}

The problem with that is that sometimes the text to speech will come on twice during that interval. Is there any way to detect the milliseconds exactly so I dont have to use greater than or less than?

回答1:

Is there any way to detect the milliseconds exactly so I dont have to use greater than or less than?

Of course not. Android is not a RTOS. Timing will be approximate, simply due to the main application thread being possibly occupied with other duties at any given moment.



回答2:

If you want more flexibility you can also try something like

int secondsLeft = 0; 

new CountDownTimer(30000, 100) {
    public void onTick(long ms) {
        if (Math.round((float)ms / 1000.0f) != secondsLeft)
        {  
            secondsLeft = Math.floor((float)ms / 1000.0f);
            if (secondsLeft == 20) {
                tts.speak("You have 20 seconds left.", TextToSpeech.QUEUE_FLUSH, null);
            }
        }
    }

    public void onFinish() {
    }
}.start();

from https://stackoverflow.com/a/6811744/1189831



回答3:

You could use a trick. If you use an Chronometer widget instead of TexView, you could make something like that:

int time = 30;

Chronometer chrono = (Chronometer) findViewById(R.id.your_chronometer_id);

chrono.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {

    @Override
    public void onChronometerTick(Chronometer chronometer) {

        chronometer.setText(String.valueOf(_time));

        if(_time == 20) tts.speak("You have 20 seconds left.", TextToSpeech.QUEUE_FLUSH, null);

        if(_time == 0){

            //Time finished, make your stuff

            chronometer.stop();     

        }else{

            _time--;

        }

    }

});