TTS-UtteranceProgressListener not being called
Asked Answered
I

4

48

I don't want to put all my code here, so I'm just putting the relevant pieces. If you need more, feel free to ask.

I'm using Text To Speech (TTS) which leads to a speech listener after it asks a question... I found through Log outputs that TTS's onInit is being called, but the UtteranceProgressListener is not and I can't figure out why. Any help is appreciated.

// ---Initialize TTS variables---

        // Implement Text to speech feature
        tts = new TextToSpeech(this, new ttsInitListener());

        // set listener to the TTS engine
        tts.setOnUtteranceProgressListener(new ttsUtteranceListener());

        if (!tts.isSpeaking()) {
            tts.speak("Speak to me", TextToSpeech.QUEUE_FLUSH, null);
        }

// --- TEXT TO SPEECH && SPEECH TO TEXT METHODS ---

class ttsInitListener implements OnInitListener {

    @Override
    public void onInit(int status) {

        if (status == TextToSpeech.SUCCESS) {
            tts.setLanguage(Locale.getDefault());

        } else {
            tts = null;
            Toast.makeText(mContext, "Failed to initialize TTS engine.",
                    Toast.LENGTH_SHORT).show();
        }
    }
}

class ttsUtteranceListener extends UtteranceProgressListener {

    @Override
    public void onDone(String utteranceId) {
        if (processStart) {
            speech.startListening(intent);
        } else {
            ...
        }

    }

    @Override
    public void onError(String utteranceId) {
    }

    @Override
    public void onStart(String utteranceId) {
    }    
}

I added log outputs to all of the my TTS and Speech methods. UtteranceProgressListener's onStart isn't even being called:

11-30 00:38:37.299: D/OpenGLRenderer(15842): Enabling debug mode 0
11-30 00:38:39.782: I/TextToSpeech(15842): Connected to ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService}
11-30 00:38:39.782: I/TextToSpeech(15842): Set up connection to ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService}
11-30 00:38:39.782: D/LOOK AT ME!!!(15842): ttsInitListener - onInit
Isobelisocheim answered 30/11, 2013 at 5:10 Comment(3)
have to made a logcat print output on utterance progress listener in onstartLike
I just stopped out. Will be back in about 20 minutes, I'll add and paste the logs thenIsobelisocheim
@AndroidVenkatesh I added the output to the OPIsobelisocheim
I
109

found the answer...

Turns out that the TTS resources I found online were using a single TTS string source, so the third parameter in tts.speak(String text, int queueMode, HashMap params) was set to null.

to anybody having this issue in the future:

if you set the third param to null, there's no ID for the UtteranceProgressListener to track. The fix was creating and initializing a hashmap, then adding to the included array for each new TTS with a new ID could be tracked. Here's the code:

HashMap<String, String> map = new HashMap<String, String>();

then, before calling tts.speak...

map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "UniqueID");

then you can call speak with all params...

tts.speak(text, TextToSpeech.QUEUE_FLUSH, map);
Isobelisocheim answered 30/11, 2013 at 6:4 Comment(1)
That unique ID also prevents your app's TTS and SpeechRecognition (not depicted here) from interfering with the recording and audio playback from other apps.Tigges
S
36

To append to WizardKnight's good answer:

The new API prefers a Bundle so replace the HashMap with a Bundle

Bundle params = new Bundle();
params.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "");

then when you make the speak call

tts.speak(text, TextToSpeech.QUEUE_FLUSH, params, "UniqueID");

The key is to use the ID in the speak call. You can put it in the Bundle, but it will do nothing more for you. It has to be in the speak call to trigger the listener.

Saylor answered 28/8, 2015 at 16:0 Comment(1)
Setting the utteranceId fixed the issueValladolid
M
4

I have a wired solution for detecting weather tts has finished speaking.

Step 1: Create this class in your code.

class Waiter extends AsyncTask<Void,Void,Void>{
        @Override
        protected Void doInBackground(Void... voids) {
            while (tts.isSpeaking()){
                try{Thread.sleep(1000);}catch (Exception e){}
            }
            return null;
        }
        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            //TTS has finished speaking. WRITE YOUR CODE HERE
        }
    }

Step 2: Call it when calling tts.speak(...)

tts.speak(...);
new Waiter().execute();
Mcdonald answered 18/9, 2017 at 20:6 Comment(2)
check: while (tts! =null && tts.isSpeaking())Floranceflore
This may work, but setting a TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID as described above, is less painful.Edo
V
1

Just use this simple code:

mTTS.speak(text, TextToSpeech.QUEUE_FLUSH, null, "MyUniqueUtteranceId");
Vermis answered 17/7, 2020 at 5:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.