2016-02-21 110 views
1

我正在構建一個文本到語音應用程序。在應用程序中,用戶可以選擇是否使用美式英語或英式英語。所以我創建了一個UserSettings類,它從Shared Preferences中獲取一些數據。如何在美式英語和英式英語之間切換TextToSpeech的語言?

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)中定義的常量,但它仍然說「語言不支持」!發生什麼事?是因爲我的設備嗎?

+0

看看這個http://android-developers.blogspot.in/2009/09/introduction-to-text-to-speech-in.html – SmashCode

+0

@SmashCode我做了帖子說的內容,但它仍然使用設備的語言(中文)說話。但更有趣的是,當我將設備的語言更改爲英語時,它會說英語!我認爲我的代碼一定有問題。這不是設備自己的TTS資源的問題。你知道爲什麼發生這種情況嗎? – Sweeper

+0

在手機中,您只能選擇1種語言將文本轉換爲語音,那麼爲什麼不嘗試在您的代碼內部進行更改,如在手機上而不是在代碼中切換語言。 – SmashCode

回答

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

+0

感謝您的答案!有用! – Sweeper

相關問題