You know Androids TextToSpeech-Service? It enables you to enhance your Android apps with voice output in a very convenient way. What I like most is that it runs completely in the background, so that calling myTTSService.speak("Some very long text indeed..."); does not stop your main thread from continuing which is one reason less to get an “Application not responding”-error.
So far so good, but sometimes you just need to know when the TTS-Service has finished speaking a sentence. Well, the API documentation suggests the following: Just make your calling class implement OnUtteranceCompletedListener, register it with the TTS-Service and get notified whenever a sentence is finished. Let source code speak:
public class MyAwesomeActivity
extends Activity
implements OnInitListener, OnUtteranceCompletedListener
{
private TextToSpeech myTTS
= null;
private boolean speechInitialized
= false;
@Override
protected void onCreate
(Bundle savedInstanceState
) {
super.
onCreate(savedInstanceState
);
//create the TTS-object
myTTS
= new TextToSpeech
(this,
this);
//and register ourselves, as we want to be notified on finishing...
myTTS.
setOnUtteranceCompletedListener(this);
}
/**
* Override für OnInitListener.onInit(), gets called when TTS is initialized and ready to speak
*/
@Override
public void onInit
(int status
) {
speechInitialized
= true;
speak
("FIRSTSENTENCE",
"Hello World!");
}
/**
* Gets called when TTS has finished speaking a sentence identified by utteranceID
*/
@Override
public void onUtteranceCompleted
(String utteranceId
) {
//do something, e.g. update the GUI or something like that (beware of threading)
}
/**
* Speak a sentence
*/
private void speak
(String utteranceID,
String whatToSpeak
) {
HashMap params
=new HashMap();
params.
put(TextToSpeech.
Engine.
KEY_PARAM_UTTERANCE_ID,utteranceID
);
if (myTTS
!=null) myTTS.
speak(whatToSpeak, TextToSpeech.
QUEUE_ADD, params
);
}
}
After compiling and running this code one would expect (at least I did on first try) that the TTS-Engine would
(a) be initialized
(b) would speak “Hello world”
(c) call my method onUtteranceCompleted with “FIRSTSENTENCE” as parameter.
Well, (a) and (b) happened perfectly. Not so much (c), where not so much means not at all. What happened? After trying I lot i found out that the API documentation does not mention on thing: The call myTTS.setOnUtteranceCompletedListener(this); MUST be used AFTER onInit has been called by the TTS -Service.
So changing two methods helps:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//create the TTS-object
myTTS = new TextToSpeech(this,this);
}
/**
* Override für OnInitListener.onInit(), gets called when TTS is initialized and ready to speak
*/
@Override
public void onInit(int status) {
speechInitialized = true;
//and NOW register ourselves, as we want to be notified on finishing...
myTTS.setOnUtteranceCompletedListener(this);
speak("FIRSTSENTENCE", "Hello World!");
}
Nice to know…