Java 如何在美式英语和英式英语之间切换TextToSpeech语言?

Java 如何在美式英语和英式英语之间切换TextToSpeech语言?,java,android,locale,text-to-speech,Java,Android,Locale,Text To Speech,我正在构建一个文本到语音的应用程序。在应用程序中,用户可以选择使用美式英语还是英式英语。因此,我创建了一个UserSettings类,从共享首选项中获取一些数据 UserSettings有一个名为getPrefTTS的方法,该方法返回配置为用户首选项(音调、速率和语音)的TextToSpeech。这是一节课: public final class UserSettings { private UserSettings () {} private static final St

我正在构建一个文本到语音的应用程序。在应用程序中,用户可以选择使用美式英语还是英式英语。因此,我创建了一个
UserSettings
类,从共享首选项中获取一些数据

UserSettings
有一个名为
getPrefTTS
的方法,该方法返回配置为用户首选项(音调、速率和语音)的
TextToSpeech
。这是一节课:

public final class UserSettings {
    private  UserSettings () {}

    private static final String SP_KEY_RATE = "rate";
    private static final String SP_KEY_PITCH = "pitch";
    private static final String SP_KEY_VOICE = "voice";

    public static String getPrefVoice(Context c) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences (c);
        return sp.getString (SP_KEY_VOICE, "GB");
    }

    //irrelevant
    public static float getPrefRate(Context c) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences (c);
        return sp.getFloat (SP_KEY_RATE, 1.0f);
    }

    //irrelevant
    public static float getPrefPitch(Context c) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences (c);
        return sp.getFloat (SP_KEY_PITCH, 1.0f);
    }

    public static TextToSpeech getPrefTTS(Context c) {
        TextToSpeech tts = new TextToSpeech (c, null);
        tts.setLanguage (new Locale ("en", getPrefVoice (c)));
        tts.setPitch (getPrefPitch (c));
        tts.setSpeechRate (getPrefRate (c));

        return tts;
    }
}
如您所见,对于
setLanguage
方法,我传入存储在SharedReferences中的国家/地区。这将是
GB
US

因为我还没有在SharedReferences中输入任何内容,所以使用了默认值
GB

但当我运行应用程序时,一个中国人的声音用拼音大声说出了文本!我想这是因为我的设备的语言设置为中文。但那是不对的!我明确地将语言设置为英语

因此,我将
getPrefTTS
方法更改为this,以检查
setLanguage
调用的结果

public static TextToSpeech getPrefTTS(Context c) {
    TextToSpeech tts = new TextToSpeech (c, null);
    int result = tts.setLanguage (new Locale ("en", getPrefVoice (c)));
    tts.setPitch (getPrefPitch (c));
    tts.setSpeechRate (getPrefRate (c));

    switch (result) {
        case TextToSpeech.LANG_AVAILABLE:
            Toast.makeText (c, "Language Available", Toast.LENGTH_LONG).show ();
            break;
        case TextToSpeech.LANG_COUNTRY_AVAILABLE:
            Toast.makeText (c, "Country Available", Toast.LENGTH_LONG).show ();
            break;
        case TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE:
            Toast.makeText (c, "Country Variable Available", Toast.LENGTH_LONG).show ();
            break;
        case TextToSpeech.LANG_MISSING_DATA:
            Toast.makeText (c, "Missing Data", Toast.LENGTH_LONG).show ();
            break;
        case TextToSpeech.LANG_NOT_SUPPORTED:
            Toast.makeText (c, "Language Not Supported", Toast.LENGTH_LONG).show ();
            break;
    }

    return tts;
}
“不支持的语言”出现在祝酒词中

我想这是因为
GB
不是有效的国家代码,所以我尝试了
UK
US
,但它们都显示
语言不受支持

我应该用什么来创建英国和美国的地区

另外,我知道在
Locale
类中有常量,但我想知道我到底做错了什么。我的代码似乎很合理

编辑:


我决定使用
Locale
UK
US
)中定义的常量,但它仍然说“语言不受支持”!发生了什么事?是因为我的设备吗?

我想你选择了正确的地区代码:美式英语是“en-US”,英式英语是“en-GB”,但你的tts实例没有连接到tts服务

您为什么错过了OnInitListener?此侦听器将连接到设备系统的TTS服务。试试这个:

    private static TextToSpeech tts;
    public static TextToSpeech getPrefTTS(Context c) {
        tts = new TextToSpeech(c, ttsInit);
//        tts = new TextToSpeech(c, ttsInit, "specific.tts.package.name.that.you.want.to.use");
    }

    private static TextToSpeech.OnInitListener ttsInit = new TextToSpeech.OnInitListener() {
        @Override
        public void onInit(int status) {
            if (status == TextToSpeech.SUCCESS) {
                int result = tts.setLanguage(new Locale("en", getPrefVoice(c)));
                tts.setPitch(getPrefPitch(c));
                tts.setSpeechRate(getPrefRate(c));

                switch (result) {
                    case TextToSpeech.LANG_AVAILABLE:
                        Toast.makeText(c, "Language Available", Toast.LENGTH_LONG).show();
                        break;
                    case TextToSpeech.LANG_COUNTRY_AVAILABLE:
                        Toast.makeText(c, "Country Available", Toast.LENGTH_LONG).show();
                        break;
                    case TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE:
                        Toast.makeText(c, "Country Variable Available", Toast.LENGTH_LONG).show();
                        break;
                    case TextToSpeech.LANG_MISSING_DATA:
                        Toast.makeText(c, "Missing Data", Toast.LENGTH_LONG).show();
                        break;
                    case TextToSpeech.LANG_NOT_SUPPORTED:
                        Toast.makeText(c, "Language Not Supported", Toast.LENGTH_LONG).show();
                        break;
                }
            }
        }
    };
此外,
OnInitListener
是异步操作的。因此,您可以在完成
OnInitListener
后处理tts实例

提示:
Locale
参考页之后,Locale代码由
ISO 639-1
定义的语言代码和
ISO 3166-1
定义的国家代码组成


查看此页面了解更多详细信息:

看看这个@SmashCode。我按照帖子所说的做了,但它仍然使用设备的语言(中文)来表达单词。但更有趣的是,当我将设备的语言更改为英语时,它会说英语!我想我的代码一定有问题。这不是设备自身TTS资源的问题。你们知道为什么会发生这种情况吗?在手机中,你们只能选择一种语言来将文字转换成语音,那个么为什么不试着在你们的代码中对其进行内部更改,就像在手机上切换语言一样,而不是在代码中。