Android 获取文本到语音(TTS)的可用区域设置

Android 获取文本到语音(TTS)的可用区域设置,android,locale,text-to-speech,Android,Locale,Text To Speech,我正在研究一个flashcard程序的文本到语音的实现。应读出不同语言的文本。为了正确执行此操作,用户必须选择要阅读的文本语言(稍后将毫无疑问地存储和使用) 是否有可能在Android系统上获得可用的TTS语言?如果没有,是否有可能获取系统上所有可用的区域设置 我想,我明白了:getAvailableLocales()和tts.isLocaleAvailable(locale)使用以下函数查找设备上所有可用的tts locale Locale.getAvailableLocales() 的输

我正在研究一个flashcard程序的文本到语音的实现。应读出不同语言的文本。为了正确执行此操作,用户必须选择要阅读的文本语言(稍后将毫无疑问地存储和使用)

是否有可能在Android系统上获得可用的TTS语言?如果没有,是否有可能获取系统上所有可用的区域设置



我想,我明白了:
getAvailableLocales()
tts.isLocaleAvailable(locale)

使用以下函数查找设备上所有可用的tts locale

Locale.getAvailableLocales()
的输出:Arrays.toString(Locale.getAvailableCales())


至少有人做了这项艰苦的工作

为了节省时间,下面是他们的代码摘录

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
选择了Pico

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设置UI中。当我在我的应用程序中以编程方式选择葡萄牙语时,它会带着葡萄牙语口音说话!FWIW这里是我选择葡萄牙语的代码(它同时接受巴西和葡萄牙地区)


由于不同的TTS引擎为
isLanguageAvailable
返回不同的结果,我发现以下解决方案在几种常见的TTS引擎上效果最好

还请注意,从Android棒棒糖开始,在
TextToSpeech
中有一个简单的方法调用,可以很容易地为您实现这一点(如果设备运行的是API 21或更高版本)

您需要在分配给
TextToSpeech
对象的
OnInitListener
onInit
方法中调用以下方法

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());
        }
    }
}
ArrayList语言;
texttospeechinittts;
私有void initSupportedLanguagesLollipop()
{
Set availablecales=initTTS.getAvailableLanguages();
用于(区域设置:可用范围)
{
添加(语言环境);
}
}
private void initSupportedLanguagesLegacy()
{
Locale[]allLocales=Locale.getAvailableLocales();
for(区域设置:所有区域设置)
{
尝试
{
int res=initTTS.isLanguageAvailable(语言环境);
布尔hasVariant=(null!=locale.getVariant()&&locale.getVariant().length()>0);
布尔值hasCountry=(null!=locale.getCountry()&&locale.getCountry().length()>0);
布尔值IsLocalSupported=
false==hasVariant&&false==hasCountry&&res==TextToSpeech.LANG\u可用||
false==hasVariant&&true==hasCountry&&res==TextToSpeech.LANG\u COUNTRY\u可用||
res==TextToSpeech.LANG\u COUNTRY\u VAR\u可用;
Log.d(标记,“TextToSpeech引擎isLanguageAvailable”+locale+“(受支持的=“+isLocaleSupported+”,res=“+res+”,country=“+locale.getCountry()+”,variant=“+locale.getVariant()+”);
if(true==IsLocalSupported)
{
添加(语言环境);
}
}
捕获(例外情况除外)
{
Log.e(标记,“错误检查语言是否可用于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.getAvailableLanguages
的严格子集,也就是说,系统可能不支持TTS引擎支持的区域设置。

根据文档,getAvailableLanguages()是静态的,因此,不需要创建区域设置对象。使用“Locale.getAvailableLocales()”是使用此方法的适当方式。tts是否支持所有可用的区域设置?@Abhinav当然不支持。我无法理解为什么OP会接受这个答案。你知道如何强迫男性声音而不是女性声音吗?使用URL参数?
GetAvailableCales()
在棒棒糖出现之前无法使用。请尝试
isLanguageAvailable()
注意:这不适用于所有设备和所有TTS引擎,因为它不匹配。您应该使用
res>=TextToSpeech.LANG\u COUNTRY\u AVAILABLE
if (locale.getDisplayName().startsWith("Portuguese")) {
    Log.i(SPEAK_REPEATEDLY, "Setting Locale to: " + locale.toString());
    tts.setLanguage(locale);
    }
}
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());
        }
    }
}
TextToSpeech tts;              // assume this is initialized
tts.getAvailableLanguages();   // returns a set of available locales