Unser AE Android Kochbuch: Notizen App und TextToSpeech Probleme. Unter Android11 und davor bleibt der Lautsprecher stumm…
Die Notizen App und Text To Speech
Im Teil 3 erstellte ich ein kleines Notizbuch mit dem ich Texte schreiben, speichern und laden konnte. Darüber hinaus gab es einen kleinen Bonus: auf Tastendruck hat mir das Notizbuch einen Text vorgelesen. Basis hierfür ist die TextToSpeech Funktion, die Android bereits seit Urzeiten anbietet.
Das mit dem Vorlesen funktioniert wohl auch ganz gut, solange Android 12 oder höher im Gerät verwendet werden. Bei älteren Versionen von Android wie Android 10 oder 11 blieben die Lautsprecher aber stumm. Manchmal stürzte sogar das ganze Gerät ab. Zumindest auf einigen Geräten und Konfigurationen, die ich im Device Konfigurator selbst ausprobierte.
Ich habe mich dann mal auf die Suche gemacht und einen Work Around gebastelt, damit das mit dem Vorlesen auch auf Android 11 und Android 10 klappt. Hier das Ergebnis.
Absturzursache beseitigen – Manifest erweitern
Die Android Doku empfiehlt den TTS_Service für Android 10 ins Manifest aufzunehmen. Das ist schnell gemacht: Im Projekt Explorer das Manifest öffnen und unter queries das Intent einfügen:
…hier ist der application teil... </application> <queries> <intent> <action android:name="android.intent.action.TTS_SERVICE" /> </intent> </queries>
Mit dieser Änderung habe ich den Absturz erst einmal behoben. Trotzdem kommt noch kein Vorlesetext.
TextToSpeech in den Hardwareeinstellungen prüfen
Unter Android – Einstellungen – Anpassungen – Sprache / Ton prüfen, ob TextToSpeech generell aktiviert ist und eine Sprache geladen wurde! Je nach Gerät gibt es hier wohl die Möglichkeit, das generell auszuschalten. Ich habe allerdings noch kein Gerät gefunden, wo das NICHT aktiviert war. Aber wer weiß – eine mögliche Fehlerursache könnte es trotzdem sein!
Debugging – Text To Speech onInit
Um zu sehen, wo Probleme auftreten, habe ich die onInit Methode um Log Meldungen in Log.d. erweitert. Ich lasse mir im Logcat die Status Variable und auch den String anzeigen, der verlesen werden soll.
//---------------------------------------------------------------------- @Override public void onInit(int status) { Log.d("000000", "Value: " + String.valueOf(status)); if (status == TextToSpeech.SUCCESS) { String S1 = etEingabe1.getText().toString(); Log.d("111111", S1); tts.setLanguage(Locale.GERMAN); tts.speak(S1, TextToSpeech.QUEUE_FLUSH, null); } }
Programmierung besteht bekanntlich zu großen Teilen aus Tests und Fehlersuche, wenn etwas Unerwartetes passiert. Nutzen wir also die Instrumente, die dafür vorgesehen sind und ich schaue mir das Logcat für die laufende Anwendung an:
Wenn alles richtig läuft, bringt TextToSpeech drei Einträge in das Logcat:
-) Sucessfully bound …
-) Connected to …
-) Set up connection …
Anschließend folgen meine beiden Debug Ausgaben.
Bei Nutzung von Android10 und 11 sieht das Logcat hingegen anders aus: es kommt nur der Eintrag Sucessfully bound – sonst nichts mehr.
Meine Schlussfolgerung: TextToSpeech OnInit wird bei Android11 und kleiner entweder nicht korrekt aktiviert und kann nicht richtig arbeiten.
Button Vorlesen – Aufruf modifizieren
Ursache dürfte darin liegen, dass der Leseprozess von TextToSpeech in der Methode onInit mittels asychronem Task stattfindet. Der ist schlichtweg einfach noch nicht korrekt durchgelaufen, wenn schon der Shutdown kommt und die Ressourcen wieder frei gibt.
Ich bastele etwas herum und schmeisse mal den tts.shutdown aus der Anwendung! Und siehe da, es funktioniert. Fleißig und emsig wird mein Text vorgelesen.
Also baue ich den Startcode im Button etwas um und frage auf die Android Version ab. Wenn diese kleiner Android 12 ist, lasse ich den Shutdown an dieser Stelle einfach weg.
if (v.getId() == R.id.buttonVorlesen) { //Aktionen fuer Button Vorlesen tts = new TextToSpeech(this, this); //Moegliche Probleme < Android12: shutdown ausschalten! if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { tts.shutdown(); } else { //der Shutdown muss woanders hin } }
Fairerweise sei erwähnt, dass der tts.shutdown die Ressourcen von TextToSpeech freigeben soll. Ihr solltet das also an anderer geeigneter Stelle irgendwo einbauen, z.B. wenn ihr mit dem Button Laden einen neuen Text holt oder mit dem Löschen Button die Eingabebox löscht. Ich habe das durch den Kommentar „der Shutdown muss woanders hin“ verdeutlicht – der an dieser Stelle natürlich technisch keinen Sinn macht!
Fazit
Mit diesem Workaround lässt sich die Vorlesefunktion auch unter Android10 und 11 nutzen.
Das Video zu diesem Beitrag:
Text und Entwurf. (c) AE SYSTEME Testcenter, Hans-J. Walter
Hans-J. Walter ist Programmierer für Windows DOT.NET / C# und Android und als eingetragener, unabhängiger Journalist verantwortlich für Fachberichte und Schulungstexte über Technik u. Entwicklung. hjw@terminal-systems.de
Für diese und alle nachfolgenden Seiten gilt ebenso der obligatorische Hinweis: Alle Angaben ohne Gewähr. Bilder und Codes zeigen Beispiele. Diese Beschreibung bezieht sich auf unsere Installation und stellt keine Bewertung der verwendeten Techniken da. Fehler und Irrtümer vorbehalten!