I need to instantiate a TextToSpeech object and set a given language (which is set programmatically and may vary).
I know I can use setLanguage() but that will only work if the language is available in the TTS engine that partictual TextToSpeech instance is using.
I know I can check whether a language is available by means of myTTS.isLanguageAvailable() but that will only tell me whether the language is available on the current engine.
The problem is that the user may have more than one TTS engine installed and the desired language may be available in one of them but not in the default one. In that case I want to find the engine, use it and set the language.
So I need to loop through the available TTS engines and "ask" each one whether it has the desired language available.
I have tried this:
mUserLocale=new Locale("it-IT"); //just an example
mTextToSpeech=new TextToSpeech(getApplicationContext(), this);
if (mTextToSpeech.isLanguageAvailable(mUserLocale)<0) {
List<TextToSpeech.EngineInfo> engines=mTextToSpeech.getEngines();
int currentmatchquality=-1;
String defaultTTSEngine=mTextToSpeech.getDefaultEngine();
mTextToSpeech.shutdown();
mTextToSpeech=null;
for (int i=0; i<engines.size(); i++) {
TextToSpeech.EngineInfo engineinfo=engines.get(i);
Log.d("MainActivity", "Examining TTS engine "+engineinfo.name);
if (engineinfo.name.equals(defaultTTSEngine)) {
Log.d("MainActivity", "Skipping default TTS engine "+engineinfo.name);
continue;
}
TextToSpeech candidateTTS=new TextToSpeech(getApplicationContext(),this,engineinfo.name);
int matchquality=candidateTTS.isLanguageAvailable(mUserLocale);
if (matchquality>currentmatchquality) {
Log.d("MainActivity", "Selecting TTS engine "+engineinfo.name);
mTextToSpeech.shutdown();
mTextToSpeech=candidateTTS;
mTTSEngine=engineinfo.name;
currentmatchquality=matchquality;
}
else {
Log.d("MainActivity", " "+mUserLocale.toString()+" not available on this engine: "+matchquality);
}
}
if (mTTSEngine==null) mTTSEngine=defaultTTSEngine;
mTextToSpeech=new TextToSpeech(getApplicationContext(),this,mTTSEngine);
}
if (mTextToSpeech.isLanguageAvailable(mUserLocale)>=0) mTextToSpeech.setLanguage(mUserLocale);
The problem is that I systematically get -2 as the result from isLanguageAvailable:
D/MainActivity﹕ Examining TTS engine com.google.android.tts
I/TextToSpeech﹕ Sucessfully bound to com.google.android.tts
W/TextToSpeech﹕ isLanguageAvailable failed: not bound to TTS engine
D/MainActivity﹕ it-it not available on this engine: -2
I guess it's because I need to wait for the init event of the TTS before I query it for an available language.
That would be cumbersome.
Is there a way to loop through existing TTS engines and check whether a language is available in each of them (or get a list of all available languages per engine) without instantiating a TextToSpeech object for each engine and waiting for it to be initialized??
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…