Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use the UtteranceProgressListener

I have a FrameLayout with two ImageButtons (Play, Stop). By default

Play button is VISIBLE, Stop button is GONE

Clicking the Play starts the TTS Engine which reads the text. On Completion of reading the text, I want to set the Visibility of

Play to GONE, Stop to VISIBLE

Should I use the UtteranceProgressListener to serve the purpose? If not,

  • How can I perform the above action?
  • What is the purpose of UtteranceProgressListener?
like image 294
Traveller Avatar asked May 03 '16 12:05

Traveller


2 Answers

Did you perhaps mean that:

  • reading starts -> Play is gone and Stop is visible
  • reading ends -> Play is visible, Stop is gone

Anyway, the purpose of UtteranceProgressListener is exactly what you are describing. It's used to monitor the progress of the speech synthesis.

You can add an "utterance id" (here "helloText") to any text that is spoken out:

tts.speak("Hello Stack Overflow!", TextToSpeech.QUEUE_ADD, "helloText");

But that's not really necessary in your case, so the last parameter can be null:

tts.speak("Hello Stack Overflow!", TextToSpeech.QUEUE_ADD, null);

The UtteranceProgressListener should be added before calling speak(). You could do that for example in the TTS initialization callback onInit() if the TTS status is TextToSpeech.SUCCESS.

It can be a separate class or just an anonymous inner class:

speech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
        @Override
        public void onStart(String utteranceId) {
            // Speaking started. 

        }

        @Override
        public void onDone(String utteranceId) {
            // Speaking stopped.

            }

        }

        @Override
        public void onError(String utteranceId) {
            // There was an error.
        }
    });

The onStart() method is triggered when speaking starts (soon after calling speak()) so that's one possible place to switch the visible button. For example the Play button could be switched to a Stop button.

The onDone() method is triggered when speaking is finished and it's another possible place to switch the visible button. For example the Stop button could be switched to a Play button.

And as you can see the "utterance id" is available in both methods if you provided a one in the speak() method call. It would be useful if you needed to know exactly which text is being spoken/finished being spoken/failed with an error.

like image 184
Markus Kauppinen Avatar answered Oct 19 '22 19:10

Markus Kauppinen


UtteranceProgressListener can be used to identify when the TTS is completed. Try this following code which shows a toast after TTS completed.

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();

        }
    };


}
like image 28
Mohammed Javad Avatar answered Oct 19 '22 19:10

Mohammed Javad