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

How can I switch the language of TextToSpeech between American English and British English?

我正在构建一个文本转语音应用程序。在应用程序中,用户可以 select 是否要使用美式英语或英式英语。所以我创建了一个 UserSettings class 从共享首选项中获取一些数据。

UserSettings 有一个名为 getPrefTTS 的方法,其中 returns 和 TextToSpeech 配置为用户的偏好(音高、速率和语音)。这是 class:

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 方法,我传入了存储在 SharedPReferences 中的国家/地区。这将是 GBUS.

因为我还没有将任何东西放入 SharedPreferences,所以使用默认值 GB

但是当我 运行 应用程序时,中文语音会用拼音大声朗读文本!我认为这是因为我的设备的语言设置为中文。但那是不对的!我将语言明确设置为英语!

所以我将 getPrefTTS 方法更改为此以检查 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;
}

并且 "Language Not Supported" 出现在吐司中。

我认为这是因为 GB 不是有效的国家代码,所以我尝试了 UKUS 但它们都显示 Language Not Supported!

我应该使用什么来创建英国和美国的语言环境?

P.S。我知道 Locale class 中有常量,但我想知道我到底做错了什么。我的代码看起来很合理。

编辑:

我决定使用 LocaleUKUS)中定义的常量,但它仍然显示 "Language Not Supported"!怎么了?是因为我的设备吗?

我认为您选择了正确的语言环境代码:美式英语是 "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 参考页面之后,区域设置代码由 ISO 639-1 定义的语言代码和 [=16] 定义的国家/地区代码组成=].

有关详细信息,请参阅此页面:http://developer.android.com/reference/java/util/Locale.html