package org.kevoree.library.text2speech.android; import android.speech.tts.TextToSpeech; import org.kevoree.android.framework.helper.UIServiceHandler; import org.kevoree.android.framework.service.KevoreeAndroidService; import org.kevoree.annotation.*; import org.kevoree.framework.AbstractComponentType; import java.util.Locale; /** * @author cdiehlwa */ @Library(name = "Android") @Provides({ @ProvidedPort(name = "text", type = PortType.MESSAGE) }) @DictionaryType({ @DictionaryAttribute(name = "lang", defaultValue = "en", optional = true) }) @ComponentType public class androidtts extends AbstractComponentType implements TextToSpeech.OnInitListener { KevoreeAndroidService uiService = null; Object bundle; private TextToSpeech mTts; private Boolean ttsReady = false; private Locale lang = getLocaleFromString("en"); @Start public void start() { updateFromDictionnary(); uiService = UIServiceHandler.getUIService(); //create the TTS instance // The OnInitListener (second argument) is called after initialization completes. mTts = new TextToSpeech(uiService.getRootActivity(), this); } @Stop public void stop() { ttsReady = false; if (mTts != null) { mTts.stop(); mTts.shutdown(); } } @Update public void update() { updateFromDictionnary(); setTtsLanguage(lang); } @Port(name = "text") public void triggerText(final Object textMsg) { if (ttsReady) { mTts.speak(textMsg.toString(), TextToSpeech.QUEUE_FLUSH, // Drop all pending entries in the playback queue. null); } // if tts is not ready drop the message } // Implements TextToSpeech.OnInitListener. public void onInit(int status) { // status can be either TextToSpeech.SUCCESS or TextToSpeech.ERROR. if (status == TextToSpeech.SUCCESS) { ttsReady = true; setTtsLanguage(lang); mTts.speak("hello", TextToSpeech.QUEUE_FLUSH, // Drop all pending entries in the playback queue. null); } else { ttsReady = false; System.out.println("Could not initialize TextToSpeech."); } } private void setTtsLanguage(Locale lang) { // no return code : don't care if lang is not an available language if (mTts.isLanguageAvailable(lang) == TextToSpeech.LANG_AVAILABLE) { int result = mTts.setLanguage(lang); if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { System.out.println("Language data not available."); } } } private void updateFromDictionnary() { Object o; if ((o = getDictionary().get("lang")) != null) { lang = getLocaleFromString(o.toString()); } } /** * Convert a string based locale into a Locale Object. * Assumes the string has form "{language}_{country}_{variant}". * Examples: "en", "de_DE", "_GB", "en_US_WIN", "de__POSIX", "fr_MAC" * * @param localeString The String * @return the Locale */ private static Locale getLocaleFromString(String localeString) { if (localeString == null) { return null; } localeString = localeString.trim(); if (localeString.toLowerCase().equals("default")) { return Locale.getDefault(); } // Extract language int languageIndex = localeString.indexOf('_'); String language = null; if (languageIndex == -1) { // No further "_" so is "{language}" only return new Locale(localeString, ""); } else { language = localeString.substring(0, languageIndex); } // Extract country int countryIndex = localeString.indexOf('_', languageIndex + 1); String country = null; if (countryIndex == -1) { // No further "_" so is "{language}_{country}" country = localeString.substring(languageIndex + 1); return new Locale(language, country); } else { // Assume all remaining is the variant so is "{language}_{country}_{variant}" country = localeString.substring(languageIndex + 1, countryIndex); String variant = localeString.substring(countryIndex + 1); return new Locale(language, country, variant); } } }