0

I'm trying to take some action after a TextToSpeech object in my Android app finishes speaking a sentence, but my UtteranceProgressListener.onDone() method is never called. I tried many things, including the suggestions from this post, but nothing has worked. Relevant code from my app is posted below. The TextToSpeech object correctly speaks the sentence I give it, but none of the callback functions in UtteranceProgressListener are called. Can someone please help me identify what's wrong? For example, should the utterance ID I provide to the TextToSpeech.speak() function need to be in some special format that I'm missing?

mtts = new TextToSpeech(myAct, new TextToSpeech.OnInitListener() {
    @Override
    public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS) {
            mtts.setLanguage(Locale.US);
        }
    }
});

mtts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
    @Override
    public void onDone(String utteranceId) {
        Toast.makeText(myAct, "OnDone called", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onError(String utteranceId) {
        Toast.makeText(myAct, "OnError called", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onStart(String utteranceId) {
        Toast.makeText(myAct, "OnStart called", Toast.LENGTH_LONG).show();
    }
});

Bundle params = new Bundle();
params.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "");
myAct.mtts.speak(myText, TextToSpeech.QUEUE_FLUSH, params, "MyID");
  • Register the ProgressListener once `onInit` has completed successfully. – brandall Jan 15 '18 at 17:58
  • @brandall You mean by putting the registration inside "if (status == TextToSpeech.SUCCESS)"? I tried that without success. – Fijoy Vadakkumpadan Jan 15 '18 at 19:06
  • Are you recreating the TTS Object in `onResume` or anywhere else and not re-registering the ProgressListener? – brandall Jan 15 '18 at 19:23
  • No, I'm creating it only once. – Fijoy Vadakkumpadan Jan 16 '18 at 14:01
  • 1
    You are referencing two different Activities - myAct & drawAct. You shouldn't be using an Activity Context at all. If mtts is initialised with the myAct context, why is the speech accessed via drawAct.mtts? Your code is entangled here somehow and is no doubt the cause of the issue. – brandall Jan 17 '18 at 06:46
  • Sorry, that was a typo in the question here. There is only one activity in my code. Editing the question. If I shouldn't be using an activity context, what should be the first parameter to the TextToSpeech() constructor? – Fijoy Vadakkumpadan Jan 17 '18 at 23:04

2 Answers2

1

Look at logcat, your code has probably fired: android.view.ViewRootImpl$CalledFromWrongThreadException

If you want to do some GUI-thread stuff, use handler and runnable like this:

public void onDone(String utteranceId) {
  Log.v(TAG, "Speaking done"); // this is OK
  // This is GUI-thread part
  final View v = findViewById(R.id.txtStatus);
  v.getHandler().post(new Runnable() {
    @Override
    public void run() {
      txtStatus.setText("Speaking done");
    }
  });
}

And to start TTS speaking:

tts.speak("bla bla bla", TextToSpeech.QUEUE_FLUSH, null, "1");
0

If you want to add the call back UtteranceProgressListener, you have to give TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID as the utteranceId

It would look like this:

myAct.mtts.speak(myText, TextToSpeech.QUEUE_FLUSH, null, TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID);

See this post: UtteranceProgressListener does not return error message

and check the engine web site: TTS Engine

ladytoky0
  • 588
  • 6
  • 16