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

时间:2016-02-21 05:52:08

标签: java android locale text-to-speech

我正在构建一个文本到语音的应用程序。在应用程序中,用户可以选择是否要使用美式英语或英式英语。所以我创建了一个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方法,我传入存储在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;
}

"语言不支持"出现在祝酒词中。

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

我应该使用什么来创建英国和美国的区域设置?

P.S。我知道Locale课程中有常量,但我想知道我到底做错了什么。我的代码似乎很合理。

编辑:

我决定使用LocaleUKUS)中定义的常量,但它仍然说"语言不支持"!怎么了?是因为我的设备吗?

1 个答案:

答案 0 :(得分:1)

我认为你选择了正确的语言环境代码:美国英语是" 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定义的语言代码和ISO 3166-1定义的国家/地区代码组成。

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