Получать доступные локали для текста в речь (TTS)

Я работаю над реализацией программы для флеш-карт. Текст на разных языках должен быть зачитан. Чтобы сделать это правильно, пользователь должен выбрать язык прочитанного текста (будет сохранен и использован позже без вопросов).

Есть ли возможность получить доступные языки TTS в системе Android? Если нет, есть ли возможность получить все доступные локали в системе?


Я предполагаю, что получил: getAvailableLocales() и tts.isLocaleAvailable(locale)

    Вы можете найти все доступные локали устройства, используя следующую функцию.

     Locale loc = new Locale("en"); Log.i("-------------",Arrays.toString(loc.getAvailableLocales())); 

    Вывод

     I/-------------( 4390): [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] - I/-------------( 4390): [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] 

    Кто-то еще проделал тяжелую работу, http://kaviddiss.com/2012/08/12/android-text-to-speech-languages/

    Чтобы сэкономить ваше время, вот их код

     TextToSpeech tts = ... // let's assume tts is already inited at this point: Locale[] locales = Locale.getAvailableLocales(); List localeList = new ArrayList(); 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 

    Результаты зависят от того, какой двигатель TTS выбран. Например, один из моих телефонов включает в себя движки Pico-TTS и Google-text-to-speech.

    Q-Smart (вьетнамский телефон с Google TTS как выбранный движок)

     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 

    И с выбранным Пико

     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 

    Примечание. Португальский язык не указан в пользовательском интерфейсе настроек TTS. Когда я выбираю португальский программно в своем приложении, он говорит с португальским акцентом! FWIW вот мой код, чтобы выбрать португальский (он принимает бразильский и португальский языки).

     if (locale.getDisplayName().startsWith("Portuguese")) { Log.i(SPEAK_REPEATEDLY, "Setting Locale to: " + locale.toString()); tts.setLanguage(locale); } } 

    Поскольку разные двигатели TTS возвращают разные результаты для isLanguageAvailable , я обнаружил, что следующее решение работает лучше всего на нескольких обычных двигателях TTS.

    Также обратите внимание, что начиная с Android Lollipop в TextToSpeech есть простой метод, называемый getAvailableLanguages который делает это легко для вас (если на устройстве работает API 21 или новее).

    Вам необходимо вызвать следующие методы в методе OnInitListener вашего OnInitListener назначенного объекту TextToSpeech .

     ArrayList languages; TextToSpeech initTTS; private void initSupportedLanguagesLollipop() { Set 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()); } } } 

    Начиная с Android 5.0 (уровень API 21), TextToSpeech.getAvailableLanguages добавлен для получения набора всех локалей, поддерживаемых движком TTS.

     TextToSpeech tts; // assume this is initialized tts.getAvailableLanguages(); // returns a set of available locales 

    Я также заметил, что набор локалей, возвращаемых TextToSpeech.getAvailableLanguages может быть не строгим подмножеством Locale.getAvailableLocales , т. Locale.getAvailableLocales Может существовать языковой стандарт, поддерживаемый механизмом TTS, который не поддерживается системой.

    Interesting Posts
    Давайте будем гением компьютера.