Get available locales for text to speech (TTS) - android
I'm working on a text-to-speech implementation of a flashcard program. Text in different languages should be read out. In order to do this properly the user has to select the language of the text to read (will be stored and used later without question).
Is there a possibility of getting the available TTS languages on an Android system? If not, is there a possibility of getting all availably locales on the system?
I guess, I got it: getAvailableLocales() and tts.isLocaleAvailable(locale)
Someone else has done the hard work, at http://kaviddiss.com/2012/08/12/android-text-to-speech-languages/
To save you time, here's their code extract
TextToSpeech tts = ...
// let's assume tts is already inited at this point:
Locale[] locales = Locale.getAvailableLocales();
List<Locale> localeList = new ArrayList<Locale>();
for (Locale locale : locales) {
int res = tts.isLanguageAvailable(locale);
if (res == TextToSpeech.LANG_COUNTRY_AVAILABLE) {
localeList.add(locale);
}
}
// at this point the localeList object will contain
// all available languages for Text to Speech
The results depend on which TTS engine has been selected. For instance, one of my phones includes both the Pico-TTS and Google-text-to-speech engines.
Q-Smart (Vietnamese Phone with Google TTS as selected engine)
D/SpeakRepeatedly( 3979): Engine Google Text-to-speech Engine:com.google.android.tts
D/SpeakRepeatedly( 3979): Engine Pico TTS:com.svox.pico
D/SpeakRepeatedly( 3979): German (Germany):German:de_DE
D/SpeakRepeatedly( 3979): English (United Kingdom):English:en_GB
D/SpeakRepeatedly( 3979): English (United States):English:en_US
D/SpeakRepeatedly( 3979): English (United States,Computer):English:en_US_POSIX
D/SpeakRepeatedly( 3979): Spanish (Spain):Spanish:es_ES
D/SpeakRepeatedly( 3979): French (France):French:fr_FR
D/SpeakRepeatedly( 3979): Italian (Italy):Italian:it_IT
D/SpeakRepeatedly( 3979): Portuguese (Brazil):Portuguese:pt_BR
D/SpeakRepeatedly( 3979): Portuguese (Portugal):Portuguese:pt_PT
And with Pico selected
D/SpeakRepeatedly( 4837): Engine Google Text-to-speech Engine:com.google.android.tts
D/SpeakRepeatedly( 4837): Engine Pico TTS:com.svox.pico
D/SpeakRepeatedly( 4837): German (Germany):German:de_DE
D/SpeakRepeatedly( 4837): English (United Kingdom):English:en_GB
D/SpeakRepeatedly( 4837): English (United States):English:en_US
D/SpeakRepeatedly( 4837): English (United States,Computer):English:en_US_POSIX
D/SpeakRepeatedly( 4837): Spanish (Spain):Spanish:es_ES
D/SpeakRepeatedly( 4837): French (France):French:fr_FR
D/SpeakRepeatedly( 4837): Italian (Italy):Italian:it_IT
Note:
Portuguese isn’t listed in the TTS Settings UI. When I select Portuguese programmatically in my app it speaks with a Portuguese accent! FWIW here's my code to select Portuguese (it accepts both Brazilian and Portuguese locales).
if (locale.getDisplayName().startsWith("Portuguese")) {
Log.i(SPEAK_REPEATEDLY, "Setting Locale to: " + locale.toString());
tts.setLanguage(locale);
}
}
Since different TTS engines return different results for isLanguageAvailable, I found that the following solution works best on several common TTS engines.
Please also note that starting with Android Lollipop, there is a simple method in TextToSpeech called getAvailableLanguages that does that easily for you (if the device is running API 21 or later).
You need to call the following methods in the onInit method of your OnInitListener assigned to the TextToSpeech object.
ArrayList<Locale> languages;
TextToSpeech initTTS;
private void initSupportedLanguagesLollipop()
{
Set<Locale> availableLocales = initTTS.getAvailableLanguages();
for (Locale locale : availableLocales)
{
languages.add(locale);
}
}
private void initSupportedLanguagesLegacy()
{
Locale[] allLocales = Locale.getAvailableLocales();
for (Locale locale : allLocales)
{
try
{
int res = initTTS.isLanguageAvailable(locale);
boolean hasVariant = (null != locale.getVariant() && locale.getVariant().length() > 0);
boolean hasCountry = (null != locale.getCountry() && locale.getCountry().length() > 0);
boolean isLocaleSupported =
false == hasVariant && false == hasCountry && res == TextToSpeech.LANG_AVAILABLE ||
false == hasVariant && true == hasCountry && res == TextToSpeech.LANG_COUNTRY_AVAILABLE ||
res == TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE;
Log.d(TAG, "TextToSpeech Engine isLanguageAvailable " + locale + " (supported=" + isLocaleSupported + ",res=" + res + ", country=" + locale.getCountry() + ", variant=" + locale.getVariant() + ")");
if (true == isLocaleSupported)
{
languages.add(locale);
}
}
catch (Exception ex)
{
Log.e(TAG, "Error checking if language is available for TTS (locale=" + locale +"): " + ex.getClass().getSimpleName() + "-" + ex.getMessage());
}
}
}
Find all available TTS Locale on the device using following function.
Locale.getAvailableLocales()
Output of: Arrays.toString(Locale.getAvailableLocales())
[ar, ar_EG, bg, bg_BG, ca, ca_ES, cs, cs_CZ, da, da_DK, de, de_AT, de_BE, de_CH, de_DE, de_LI, de_LU, el, el_CY, el_GR, en, en
_AU, en_BE, en_BW, en_BZ, en_CA, en_GB, en_HK, en_IE, en_IN, en_JM, en_MH, en_MT, en_NA, en_NZ, en_PH, en_PK, en_RH, en_SG, en_TT, en_US, en_US_POSIX,
en_VI, en_ZA, en_ZW, es, es_AR, es_BO, es_CL, es_CO, es_CR, es_DO, es_EC, es_ES, es_GT, es_HN, es_MX, es_NI, es_PA, es_PE, es_PR, es_PY, es_SV, es_US
, es_UY, es_VE, et, et_EE, eu, eu_ES, fa, fa_IR, fi, fi_FI, fr, fr_BE, fr_CA, fr_CH, fr_FR, fr_LU, fr_MC, gl, gl_ES, hr, hr_HR, hu, hu_HU, in, in_ID,
is, is_IS, it, it_CH, it_IT, iw, iw_IL, ja, ja_JP, kk, kk_KZ, ko, ko_KR, lt, lt_LT, lv, lv_LV, mk, mk_MK, ms, ms_BN, ms_MY, nl, nl_BE, nl_NL, no, no_N
O, no_NO_NY, pl, pl_PL, pt, pt_BR, pt_PT, ro, ro_RO, ru, ru_RU, ru_UA, sh, sh_BA, sh_CS, sh_YU, sk, sk_SK, sl, sl_SI, sq, sq_AL, sr, sr_BA, sr_ME, sr_
RS, sv, sv_FI, sv_SE, th, th_TH, tr, tr_TR, uk, uk_UA, vi, vi_VN, zh, zh_CN, zh_HK, zh_HANS_SG, zh_HANT_MO, zh_MO, zh_TW]
Starting from Android 5.0 (API level 21), TextToSpeech.getAvailableLanguages has been added to fetch a set of all locales supported by the TTS engine.
TextToSpeech tts; // assume this is initialized
tts.getAvailableLanguages(); // returns a set of available locales
I have also noticed that the set of locales returned by TextToSpeech.getAvailableLanguages might not be a strict subset of Locale.getAvailableLocales, i.e. there might a locale supported by the TTS engine that isn't supported by the system.
Related
If the language is english then use an another link than if it's german
how does the if condition look like? if(Locale.getDefault().equals("English")){ Log.i("Language","Englisch"); } else if(Locale.getDefault().equals("Deutsch")){ Log.i("Language","Deutsch"); } This won't work
Locale.getDefault() will return a static Locale Object, not a String. So calling Locale.getDefault().equals("English") will not work. Try this: String language = Locale.getDefault().getLanguage(); if (language.equals("en")) { // Use English link } else if (language.equals("de")) { // Use German link } public String getLanguage () Added in API level 1 Returns the language code for this Locale or the empty string if no language was set. Or: String language = Locale.getDefault().getDisplayLanguage(); if (language.equals("English")) { // Use English link } else if (...) { .... public final String getDisplayLanguage () Added in API level 1 Equivalent to getDisplayLanguage(Locale.getDefault()). Here are other possibilities: Locale.getDefault().getLanguage() ---> en Locale.getDefault().getISO3Language() ---> eng Locale.getDefault().getCountry() ---> US Locale.getDefault().getISO3Country() ---> USA Locale.getDefault().getDisplayCountry() ---> United States Locale.getDefault().getDisplayName() ---> English (United States) Locale.getDefault().toString() ---> en_US Locale.getDefault().getDisplayLanguage()---> English Documentation here.
Locale.getDefault returns a Locale, not a String. If you want to know more about that locale you call getLanguage and getCountry on the Locale. Look up ISO code for language and country. Usually, in android you solve something like this by different resources. Under res/values-en/ and res/values-de/ you can define language specific strings.
Getting Locale variant for simplified chinese
How can I get simplified chinese description (简体)? From the available locale Locale.SIMPLIFIED_CHINESE, no method seems to return this description: getDisplayLanguage() returns the correct language name, but without the variant. getDisplayName() returns the correct language name and country, but also without the variant. getDisplayVariant() returns an empty string. I've also tried to build a new Locale using the different constructors, also to no avail. new Locale("zh", "CN"); new Locale("zh", "CN", "Hans"); I've checked the Android source code for LocalePicker and I've concluded that it is loaded from the resources (special_locale_codes and special_locale_names). Any solutions besides having to hardcode/include this string in my resources?
Let me explain my process on how I tackled this. First, I found this block of code in LocalePicker.java private static String getDisplayName(Locale l, String[] specialLocaleCodes, String[] specialLocaleNames) { String code = l.toString(); for (int i = 0; i < specialLocaleCodes.length; i++) { if (specialLocaleCodes[i].equals(code)) { return specialLocaleNames[i]; } } return l.getDisplayName(l); } which takes in a Locale as you already know. Then it tries to find the locale code in the specialLocaleCodes string array. The specialLocaleNames you are seeking are obtained from arrays.xml as you've helpfully stated: <string-array translatable="false" name="special_locale_codes"> <item>ar_EG</item> <item>zh_CN</item> <item>zh_TW</item> </string-array> and the corresponding languages <string-array translatable="false" name="special_locale_names"> <item>العربية</item> <item>中文 (简体)</item> <item>中文 (繁體)</item> </string-array> Notice the code with the simplified Chinese is zh_CN and the last two characters are capitalized. However, Locale locale = new Locale("zh_CN"); System.out.println("Locale: " + locale); prints Locale: zh_cn Notice the lower case. So there is no way specialLocaleCodes[i].equals(code) will return true. So then I poked around Locale.java and, long story short, we can bypass that case-changing jumble by doing this (and you MUST keep the 3rd parameter as an empty string for this to work): Locale locale = new Locale("zh", "CN", ""); System.out.println("Locale: " + locale); Prints Locale: zh_CN With this you should be able to do this: Locale locale = new Locale("zh", "CN", ""); System.out.println("Name:" + locale.getDisplayName(locale)); Upon further inspection on Kitkat using this (thank you Andrew!) int specialLocaleNamesId = Resources.getSystem().getIdentifier("special_locale_names", "array", "android"); String[] specialLocaleNames = Resources.getSystem().getStringArray(specialLocaleNamesId); it was possible to print out العربية,中文 (简体),中文 (繁體) as expected. However, something in Kitkat is still preventing the correct string to display. Frustrating. However, in Lollipop 5.0+ and Java 1.7 this works using forLanguageTag() in Locale. Locale locale = Locale.forLanguageTag("zh-Hans"); System.out.println("getDisplayName:" + locale.getDisplayName(locale)); System.out.println("getDisplayLanguage:" + locale.getDisplayLanguage(locale)); which prints getDisplayName:中文 (简体中文) getDisplayLanguage:中文
You could probably access the android internal resource: com.android.internal.R.array.special_locale_names the same way it's done in LocalePicker: final Resources resources = context.getResources(); final String[] specialLocaleNames = resources.getStringArray(com.android.internal.R.array.special_locale_names); But it's probably safer to use your own resource here (avoiding the use of internals)
How to set Dutch Language in Text-To-Speech?
I want to set Dutch Language in my TTS object. Following is the code, #Override public void onInit(int status) { if ( status == TextToSpeech.SUCCESS ) { int result = tts.setLanguage(Locale.getDefault()); System.out.println ( "Result : " + result + " " + Locale.getDefault().getLanguage() ); if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { Toast.makeText( this , "Please Set your Language to English US.", Toast.LENGTH_LONG ).show(); } else { tts.speak( "Hoe gaat het",TextToSpeech.QUEUE_FLUSH, null ); } } } Following line sets the language in TTS int result = tts.setLanguage(Locale.getDefault()); Available Locale's in Locale. Now if my Phone's Language's is Dutch then I am able to set TTS's language as Dutch Language, but if My Phone's Language is not dutch ( for e.g. if it is English ) then there is no option to set the TTS's language as Dutch. Can anybody help me to set the Dutch language in TTS?
This should work int result = tts.setLanguage(new Locale("nl_NL"));
You are setting default Locale in setLocale. That's the reason of this issue: Now if my Phone's Language's is Dutch then I am able to set TTS's language as Dutch Language, but if My Phone's Language is not dutch ( for e.g. if it is English ) then there is no option to set the TTS's language as Dutch. You should use Locale you need instead. So replace int result = tts.setLanguage(Locale.getDefault()); with int result = tts.setLanguage(Locale.XYZ); //XYZ is Locale you want. Example: int result = tts.setLanguage(Locale.GERMAN); Referdocumentation, which includes available Locales, which you can set. DUTCH is not available there. Though this article mentions that DUTCH is available Locale. May be it is not for android, but for java, as suggested here Hope this helps.
for hindi-india newsReaderTTS.setLanguage(new Locale("hin", "IND", "variant")); for english usa newsReaderTTS.setLanguage(new Locale("eng", "USA", "variant")); where newsreaderTTS is TTS.
android tts, change languages
I’m developing an application that uses TTS for Android. I don’t seem to get something in setting the language for TTS. I have been able to set my application to speak in Italian, but not in Finnish or Russian. However, both those are shown when I output this: Log.i("-------------",Arrays.toString(Locale.getAvailableLocales())); Which gives: [ar, ar_EG, bg, bg_BG, ca, ca_ES, cs, cs_CZ, da, da_DK, de, de_AT, de_BE, de_CH, de_DE, de_LI, de_LU, el, el_CY, el_GR, en, en_AU, en_BE, en_BW, en_BZ, en_CA, en_GB, en_HK, en_IE, en_IN, en_JM, en_MH, en_MT, en_NA, en_NZ, en_PH, en_PK, en_RH, en_SG, en_TT, en_US, en_US_POSIX, en_VI, en_ZA, en_ZW, es, es_AR, es_BO, es_CL, es_CO, es_CR, es_DO, es_EC, es_ES, es_GT, es_HN, es_MX, es_NI, es_PA, es_PE, es_PR, es_PY, es_SV, es_US, es_UY, es_VE, et, et_EE, eu, eu_ES, fa, fa_IR, **fi, fi_FI**, fr, fr_BE, fr_CA, fr_CH, fr_FR, fr_LU, fr_MC, gl, gl_ES, hr, hr_HR, hu, hu_HU, in, in_ID, is, is_IS, it, it_CH, it_IT, iw, iw_IL, ja, ja_JP, kk, kk_KZ, ko, ko_KR, lt, lt_LT, lv, lv_LV, mk, mk_MK, ms, ms_BN, ms_MY, nl, nl_BE, nl_NL, no, no_NO, no_NO_NY, pl, pl_PL, pt, pt_BR, pt_PT, ro, ro_RO, **ru, ru_RU**, ru_UA, sh, sh_BA, sh_CS, sh_YU, sk, sk_SK, sl, sl_SI, sq, sq_AL, sr, sr_BA, sr_ME, sr_RS, sv, sv_FI, sv_SE, th, th_TH, tr, tr_TR, uk, uk_UA, vi, vi_VN, zh, zh_CN, zh_HK, zh_HANS_SG, zh_HANT_MO, zh_MO, zh_TW] So, what’s the problem?
Locale.getAvailableLocales() returns the locale codes understood by the device, which has no relation to the locales supported by the current text-to-speech engine. After creating a connection to a TTS engine, you can call TextToSpeech.isLanguageAvailable(Locale) to determine if a language is supported by the engine and whether data for that particular language is installed.
Using text to speech APIs in android application
I want to use TTS (Text to Speech) APIs in my android application.Now i have one quetions - Is it support TURKISH language ? I also want to highlight word in textview when that perticular word is being spoke. How can i do it ? Can anybody help me ? Thanks in advance !
Does it support TURKISH language This may vary on different handsets/flavours of Android. You can check it out for yourself using the mTTS.isLanguageAvailable(new Locale("tr", "TUR")); I also want to highlight word in textview when that particular word is being spoke. Well you have a TextToSpeech.OnUtteranceCompletedListener(), to use this you have to speak() each word, one at a time.
The TTS engine that ships with the Android platform supports a number of languages: English, French, German, Italian and Spanish. Also, depending on which side of the Atlantic you are on, American and British accents for English are both supported. http://developer.android.com/resources/articles/tts.html
You should use Locale type variable. final Locale locale = new Locale("tr", "TR"); tts = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() { #Override public void onInit(int status) { if (status == TextToSpeech.SUCCESS) { int result = tts.setLanguage(locale); if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { Log.d("class name", "tts error "); } } else { Log.d("class name", "tts error "); } } }); tts.speak("write here what you want in Turkish", TextToSpeech.QUEUE_FLUSH, null);