How to know when TTS is finished?
Asked Answered
L

8

42

I'm implementing an Interactive Voice Response application on Android. I would like to know how to determine when the tts.speak() function has done talking so I can call my speech recognizer function.

Laraelaraine answered 11/1, 2011 at 13:59 Comment(3)
you can check this answer this is working for me https://mcmap.net/q/391566/-android-tts-onutterancecompleted-callback-isn-39-t-getting-calledFill
you can visit this website: dev.to/charfaouiyounes/… to see more information about TTSParasitize
Don't forget to setup utteranceId. Without this id listener is not called. textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null, "utteranceId")Jackelinejackelyn
M
49
public class TTSActivity extends Activity implements OnInitListener, OnUtteranceCompletedListener, ... {
private TextToSpeech mTts;
...........
private void speak(String text) {
   if(text != null) {
      HashMap<String, String> myHashAlarm = new HashMap<String, String>();
      myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_ALARM));
      myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "SOME MESSAGE");
      mTts.speak(text, TextToSpeech.QUEUE_FLUSH, myHashAlarm);
   }
}
// Fired after TTS initialization
public void onInit(int status) {
    if(status == TextToSpeech.SUCCESS) {
        mTts.setOnUtteranceCompletedListener(this);
    }
}
// It's callback
public void onUtteranceCompleted(String utteranceId) {
   Log.i(TAG, utteranceId); //utteranceId == "SOME MESSAGE"
   }
...........
}

Read A good tutorial

Muzzleloader answered 11/1, 2011 at 15:18 Comment(4)
one question, why does the onUtteranceCompleted() method doesn't get called? I'm trying to do it and I cannot get it fired. Thanks.Laraelaraine
This method is fired when the finished sound synthesis. This is callback method.So you don't need call this method. It's a listenerMuzzleloader
Now OnUtteranceProgress is suggested instead of OnUtteranceCompletedCrock
@Muzzleloader can you tell me how can i determine single word in tts i want to display each single word which is being speaking.Grande
B
27

The setOnUtteranceCompletedListener is deprecated since API level 15. Instead, use setOnUtteranceProgressListener.

I found a code snippet (here) that made it really easy for me to know when text to speech is finished:

@Override
public void onInit(int status) {
    if (status == TextToSpeech.SUCCESS) {
        myTTS.setOnUtteranceProgressListener(new UtteranceProgressListener() {
            @Override
            public void onDone(String utteranceId) {
                // Log.d("MainActivity", "TTS finished");
            }

            @Override
            public void onError(String utteranceId) {
            }

            @Override
            public void onStart(String utteranceId) {
            }
        });
    } else {
        Log.e("MainActivity", "Initilization Failed!");
    }
}

http://www.codota.com/android/scenarios/52fcbd34da0ae25e0f855408/android.speech.tts.TextToSpeech?tag=dragonfly

Blacklist answered 23/11, 2015 at 7:9 Comment(0)
S
8

To know when TTS is finished you have to call the setOnUtteranceProgressListener which has 3 call back methods onStart,onDone and onError then include a Utterance Id to the speak method

Code Snippet

textToSpeech=new TextToSpeech(this, new TextToSpeech.OnInitListener() {
    @Override
    public void onInit(int status) {
        if (status==TextToSpeech.SUCCESS){
            int result=textToSpeech.setLanguage(Locale.ENGLISH);

            if (result==TextToSpeech.LANG_MISSING_DATA||result==TextToSpeech.LANG_NOT_SUPPORTED){
                Log.i("TextToSpeech","Language Not Supported");
            }

            textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
                @Override
                public void onStart(String utteranceId) {
                    Log.i("TextToSpeech","On Start");
                }

                @Override
                public void onDone(String utteranceId) {
                    Log.i("TextToSpeech","On Done");
                }

                @Override
                public void onError(String utteranceId) {
                    Log.i("TextToSpeech","On Error");
                }
            });

        }else {
            Log.i("TextToSpeech","Initialization Failed");
        }
    }
});


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        textToSpeech.speak(text,TextToSpeech.QUEUE_FLUSH,null,TextToSpeech.ACTION_TTS_QUEUE_PROCESSING_COMPLETED);
    }
Stinkweed answered 16/11, 2019 at 20:37 Comment(0)
L
5

I noticed that there are people having problems in the use of TextToSpeech to ask that the solution to you

How to know when TTS is finished? without use setOnUtteranceCompletedListener

public void isTTSSpeaking(){

    final Handler h =new Handler();

    Runnable r = new Runnable() {

        public void run() {

            if (!tts.isSpeaking()) {
                onTTSSpeechFinished();
            }

            h.postDelayed(this, 1000);
        }
    };

    h.postDelayed(r, 1000);
}
Locomotor answered 5/4, 2014 at 1:44 Comment(0)
O
2

Try this following code which shows a toast after TTS completed. Replace toast with your own action.

public class MainActivity extends AppCompatActivity implements TextToSpeech.OnInitListener{


private boolean initialized;
private String queuedText;
private String TAG = "TTS";
private TextToSpeech tts;




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



    tts = new TextToSpeech(this /* context */, this /* listener */);
    tts.setOnUtteranceProgressListener(mProgressListener);


    speak("hello world");

}




public void speak(String text) {

    if (!initialized) {
        queuedText = text;
        return;
    }
    queuedText = null;

    setTtsListener(); // no longer creates a new UtteranceProgressListener each time
    HashMap<String, String> map = new HashMap<String, String>();
    map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "MessageId");
    tts.speak(text, TextToSpeech.QUEUE_ADD, map);
}


private void setTtsListener() {

}





@Override
public void onInit(int status) {
    if (status == TextToSpeech.SUCCESS) {
        initialized = true;
        tts.setLanguage(Locale.ENGLISH);

        if (queuedText != null) {
            speak(queuedText);
        }
    }
}



private abstract class runnable implements Runnable {
}




private UtteranceProgressListener mProgressListener = new UtteranceProgressListener() {
    @Override
    public void onStart(String utteranceId) {
    } // Do nothing

    @Override
    public void onError(String utteranceId) {
    } // Do nothing.

    @Override
    public void onDone(String utteranceId) {

        new Thread()
        {
            public void run()
            {
                MainActivity.this.runOnUiThread(new runnable()
                {
                    public void run()
                    {

                        Toast.makeText(getBaseContext(), "TTS Completed", Toast.LENGTH_SHORT).show();

                    }
                });
            }
        }.start();

    }
}; }
Obliteration answered 20/1, 2018 at 8:46 Comment(1)
This works for me. OnDone method of TTS Listerner need runOnUIThred to show case popup, dialogs, toast on UI.Accidental
Z
0

With this code I solved the problem. I wanted the start button to stay lit as long as someone was speaking. Maybe this will help someone.

    public void _tts_speak_lenght() {
    t2 = new TimerTask() {
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (TTS.isSpeaking()) {
                        isSpeaking = true;
                    }
                    else {
                        if (!TTS.isSpeaking()) {
                            t2.cancel();
                            isSpeaking = false;
                            imgBtn_startReader.setImageResource(R.drawable.ic_start_off);
                        }
                    }
                }
            });
        }
    };
    _timer.scheduleAtFixedRate(t2, (int)(0), (int)(100));
}
Zelikow answered 26/2, 2023 at 9:55 Comment(0)
S
0

use this listener :

    textToSpeech.setOnUtteranceProgressListener(
        object : UtteranceProgressListener() {
            override fun onStart(utteranceId: String?) {
                Handler(Looper.getMainLooper()).post {
                    //if you want update ui you should use handler
                }
            }

            override fun onDone(utteranceId: String?) {
                Handler(Looper.getMainLooper()).post {
                    //if you want update ui you should use handler
                }
            }

            @Deprecated("Deprecated in Java")
            override fun onError(utteranceId: String?) {
                Handler(Looper.getMainLooper()).post {
                    //if you want update ui you should use handler
                }
            }
        }
    )
Swaddle answered 12/4, 2023 at 8:5 Comment(0)
D
-1

use a SpeakableListener when do text to speak.

private volatile boolean finished;

private SpeakableListener listener = new SpeakableListener() {

    @Override
    public void markerReached(SpeakableEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void speakableCancelled(SpeakableEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void speakableEnded(SpeakableEvent arg0) {
        TestSpeaker.this.finished = true;

    }

    @Override
    public void speakablePaused(SpeakableEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void speakableResumed(SpeakableEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void speakableStarted(SpeakableEvent arg0) {
        TestSpeaker.this.finished = false;

    }

    @Override
    public void topOfQueue(SpeakableEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void wordStarted(SpeakableEvent arg0) {
        // TODO Auto-generated method stub

    }
};

/** Speak the following string. */
public void sayIt(String str) {
    System.out.print(" " + str + " ");
    /* The the synthesizer to speak. */
    synthesizer.speakPlainText(str, listener);
Daybreak answered 22/5, 2017 at 5:2 Comment(3)
what are you talking about? what SpeakableListener?Cylindroid
how to use SpeakableListener ?Lacking
this is not available in AndroidKingly

© 2022 - 2024 — McMap. All rights reserved.