Wie man verfügbare TTS-Engines nach verfügbaren Sprachen abfragt, ohne sie einzeln zu instanziieren und auf init @ zu wart

Ich muss ein TextToSpeech-Objekt instanziieren und eine bestimmte Sprache festlegen (die programmgesteuert festgelegt wird und variieren kann). Ich weiß, dass ich setLanguage () verwenden kann, aber das funktioniert nur, wenn die Sprache in der TTS-Engine verfügbar ist, die von der jeweiligen TextToSpeech-Instanz verwendet wird. Ich weiß, dass ich mithilfe von myTTS.isLanguageAvailable () überprüfen kann, ob eine Sprache verfügbar ist. Dadurch erfahre ich jedoch nur, ob die Sprache auf der aktuellen Engine verfügbar ist.

Das Problem ist, dass der Benutzer möglicherweise mehr als eine TTS-Engine installiert hat und die gewünschte Sprache möglicherweise in einer von ihnen verfügbar ist, jedoch nicht in der Standardsprache. In diesem Fall möchte ich die Engine finden, sie verwenden und die Sprache einstellen.

So muss ich die verfügbaren TTS-Engines durchlaufen und jeden fragen, ob die gewünschte Sprache verfügbar ist.

Ich habe es versucht:

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

Das Problem ist, dass ich systematisch -2 als Ergebnis von isLanguageAvailable erhalte:

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

Ich denke, es liegt daran, dass ich auf das init-Ereignis des TTS warten muss, bevor ich eine verfügbare Sprache abfrage.

Das wäre umständlich. Gibt es eine Möglichkeit, vorhandene TTS-Engines zu durchlaufen und zu überprüfen, ob eine Sprache in jedem von ihnen verfügbar ist (oder eine Liste aller verfügbaren Sprachen pro Engine zu erhalten), ohne ein TextToSpeech-Objekt für jede Engine zu instanziieren und darauf zu warten, dass es initialisiert wird?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage