編輯:關於Android編程
本文實例講述了Android自動朗讀TTS用法。分享給大家供大家參考,具體如下:
TextToSpeech簡稱 TTS,是自Android 1.6版本開始比較重要的新功能。將所指定的文本轉成不同語言音頻輸出。它可以方便的嵌入到游戲或者應用程序中,增強用戶體驗。
在講解TTS API和將這項功能應用到你的實際項目中的方法之前,先對這套TTS引擎有個初步的了解。
對TTS資源的大體了解:
TTS engine依托於當前Android Platform所支持的幾種主要的語言:English、French、German、Italian和Spanish五大語言(暫時沒有我們偉大的中文,至少google的 科學家們還沒有把中文玩到爐火純青的地步,先易後難也是理所當然。)TTS可以將文本隨意的轉換成以上任意五種語言的語音輸出。與此同時,對於個別的語言 版本將取決於不同的時區,例如:對於English,在TTS中可以分別輸出美式和英式兩種不同的版本(由此看出Google的做事風格真夠細致,而正因 為如此估計Google不加入中文的另外一種理由是中文的方言太多了)。
能支持如此龐大的數據量,TTS 引擎對於資源的優化采取預加載的方法。根據一系列的參數信息(參數的用法將在後邊有詳細的介紹)從庫中提取相應的資源,並加載到當前系統中。
盡管當前大部分加載有Android操作系統的設備都通過這套引擎來提供TTS功能,但由於一些設備的存儲空間非常有限而影響到TTS無法最大限度的發 揮功能,算是當前的一個瓶頸。為此,開發引入了檢測模塊,讓利用這項技術的應用程序或者游戲針對於不同的設備可以有相應的優化調整,從而避免由於此項功能 的限制,影響到整個應用程序的使用。比較穩妥的做法是讓用戶自行選擇是否有足夠的空間或者需求來加載此項資源,下邊給出一個標准的檢測方法:
Intent checkIntent = new Intent(); checkIntent.setAction(TextToSpeech.Engine.ACTION_C HECK_TTS_DATA); startActivityForResult(checkIntent, MY_DATA_CHECK_CODE);
如果當前系統允許創建一個 “android.speech.tts.TextToSpeech” 的彩虹簡譜字庫 下載Object, 說明已經提供TTS功能的支持,將檢測返回結果中給出“ CHECK_VOICE_DATA_PASS ” 的標記。如果系統不支持這項功能,那麼用戶可以選擇是否加載這項功能,從而讓設備支持輸出多國語言的語音功能“Multi-lingual Talking”。“ACTION_INSTALL_TTS_DATA” intent將用戶引入Android market中的TTS下載界面。下載完成後將自動完成安裝,下邊是實現這一過程的完整代碼 (androidres) :
private TextToSpeech mTts; protected void onActivityResult( int requestCode, int resultCode, Intent data) { if (requestCode == MY_DATA_CHECK_CODE) { if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) { // sess, create the TTS instance mTts = new TextToSpeech(this, this); } else { // missing data, install it Intent installIntent = new Intent(); installIntent.setAction( TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA); startActivity(installIntent); } } }
TextToSpeech實體和OnInitListener都需要引用當前Activity的Context作為構造參數。 OnInitListener()的用處是通知系統當前TTS Engine已經加載完成,並處於可用狀態。
根據需求設置語言參數:
早在Google I/O大會上,官方給出了一段關於應用這項功能的鮮活體驗,將翻譯結果直接通過五種不同國家語言的語音輸出。加載語言的方法非常簡單:
mTts.setLanguage(Locale.US);
上邊代碼表示當前TTS實體加載美式英語。其參數並沒有指示某種語言的名稱,而是利用國家代碼來表示,這樣做的好處是不但可以確定語言的選擇,而且可以 根據地區的不同而有所區別。例如:英語作為最廣泛被應用的語種,在多個不同的地區都有一定的差別。判斷當前系統是否支持某個地區的語言資源,可以通過調用 isLanguageAvailable()方法的返回值,根據返回值的描述來選擇正確的處理方式。讓應用某些絢麗功能的應用程序更加健壯,這個是貫穿整 個開發過程都要考慮的技術環節。下邊是一些應用實例 (androidres) :
mTts.isLanguageAvailable(Locale.UK)) mTts.isLanguageAvailable(Locale.FRANCE)) mTts.isLanguageAvailable(new Locale("spa", "ESP")))
如果返回值是“ TextToSpeech.LANG_COUNTRY_AVAILABLE ” 說明所選擇的地區被包含在當前TTS系統中。如果系統中已經創建了TTS實體,那麼可以利用isLanguageAvailable()方法來替代 Start “ACTION_CHECK_TTS_DATA ” intent 檢測。當無法找到任何可用資源匹配所指定的參數時,將會返回“ TextToSpeech.LANG_MISSING_DATA ”的結果。下邊給出另外兩個返回其它不同狀態信息的例子:
mTts.isLanguageAvailable(Locale.CANADA_FRENCH)) mTts.isLanguageAvailable(new Locale("spa"))
兩個語句的返回值均為“ TextToSpeech.LANG_AVAILABLE ” 。第一個是檢測當前系統是否支持加拿*****語,由於系統在資源庫中無法找到這個地區的法語分支,其含義是僅支持這項語言(法語),而不支持當前紫光 v4.0下載地區的語言分支。
另外,相比於上面強制用戶應用預定的語音設置,更加提倡利用Locale.getDefault() 方法根據用戶默認的地區設置來選擇合適的語言庫。
執行Speak的具體方法:
根據上邊的介紹,基本實現了 TextToSpeech的初始化和參數配置。下面是一個有關鬧鐘的應用實例,利用Speak()方法可以直接在應用程序中發揮強大的語音功能。沒錯,用起來就是這麼簡單:
String myText1 = "This Translation is from androidRes"; String myText2 = "I hope so, because it's time to wake up."; mTts.speak(myText1, TextToSpeech.QUEUE_FLUSH, null); mTts.speak(myText2, TextToSpeech.QUEUE_ADD, null);
TTS Engine的工作原理:
每個獨立的應用程序都可以單獨創建一個TTS實體,而他們需要執行的語音消息列隊(Queue)都統一由TTS Engine管理和語音合成。
名詞解釋:
synthesize [snθsaz] DJ ['snθsaz] KK:to produce sounds, music or speech using electronic equipment (音響)合成
utterances [trns] DJ [trns] KK :說話方式,語音/語調。
每個獨立的TTS實例管理語音消息列隊請求的優先級和順序等。當引用 “TextToSpeech.QUEUE_FLUSH” 調用Speak()方法時,會中斷當前實例正在運行的任務(也可以理解為清除當前語音任務,轉而執行新的列隊任務)。引用 “TextToSpeech.QUEUE_ADD”標簽的發音任務將被添加到當前任務列隊之後。
為語音任務關聯Stream Type:
在Android操作系統中所有的AudioStream任務都是通過AudioManager類來實現,而它會針對不同的StreamType來改變語音的播放模式。StreamType可以理解為語音的播放屬性,這個屬性是用戶根據自己的需要在系統中配置的應用方案。如果將語音任務都 清楚的分門別類,可以方便的統一管理相同類別任務的屬性。基於上一個Alarm Clock例子的基礎上,將Speak()方法的最後一個Null參數替換成具有實際含義的數值。這個參數的類型是HashMap,如果希望將當前的 Stream Type設置為系統中Alarm類型,對上一個例子稍作改動:
HashMap myHashAlarm = new HashMap(); myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_STRE AM, String.valueOf(AudioManager.STREAM_ALARM)); mTts.speak(myText1, TextToSpeech.QUEUE_FLUSH, myHashAlarm); mTts.speak(myText2, TextToSpeech.QUEUE_ADD, myHashAlarm);
應用語音功能的Completion Callback:
TTS中的Speak()的是異步調用,無論應用QUEUE_FLUSH 或者QUEUE_ADD作為參數都可以通過定義Listener監聽當前任務的完成狀態。可以利用這個方法追加Speak()執行之後的一些額外操作。下 接下來的例子中,當完成第二次Speak()方法調用之後,利用OnUtteranceCompletedListener接口來調用其它方法:
mTts.setOnUtteranceCompletedListener(this); myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_STRE AM, String.valueOf(AudioManager.STREAM_ALARM)); mTts.speak(myText1, TextToSpeech.QUEUE_FLUSH, myHashAlarm); myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_UTTE RANCE_ID, "end of wakeup message ID"); // myHashAlarm now contains two optional parameters mTts.speak(myText2, TextToSpeech.QUEUE_ADD, myHashAlarm);
下邊是定義Listener的代碼,類似與監聽按 CuteFTP Home 8.3.3.0054下載鈕或者其它View Events的方法。在這裡將會把Speak()中HashMap參數傳進Listener中,作為條件的判斷依據:
public void onUtteranceCompleted(String uttId) { if (uttId == "end of wakeup message ID") { playAnnoyingMusic(); } }
“烘焙”當前實時的語音數據:
看到烘焙兩個字,就會讓人聯想到香噴噴的面包。軟件開發要關注於是否可以最大限度的實現資源的復用,特別是針對資源有限的手機應用平台。那麼對於TTS 這麼奢侈的應用如何才能更高效的使用資源呢?這次一起來體驗比烘焙面包更加讓人激動的功能,將TTS Engine輸出的Audio Stream作為永久的音頻文件保存在當前的存儲空間中(SDCard)。這樣可以對需要重復播放的某些語音內容實現快速的回放功能,從而實現國際倡導的 “減排”目的,能省就省吧!在下邊的例子用通過TTS的synthesizeToFile方法,將合成的語音Stream保存在參數所指定的地址中。
HashMap myHashRender = new HashMap(); String wakeUpText = "Are you up yet?"; String destFileName = "/sdcard/myAppCache/wakeUp.wav"; myHashRender.put(TextToSpeech.Engine.KEY_PARAM_UTT ERANCE_ID, wakeUpText); mTts.synthesizeToFile(wakuUpText, myHashRender, destFileName);
當完成以上操作之後會收到系統的完成通知,同時可以像其它音頻資源一樣,通過 android.media.MediaPlayer方法來播放。但這有悖於TextToSpeech的應用流程,可以將剛剛輸出的語音資源通過 addSpeech()的方法將其語音和文字描述一同存儲於TTS庫中。
mTts.addSpeech(wakeUpText, destFileName);
在當前的TTS Instance中,任何利用Speak()方法執行相同內容的調用都將復用剛剛所生成的音頻文件。如果資源丟失或者SDCard等存儲設備移除,那麼系統將再次通過TTS Engine合成所指定的語音內容。
mTts.speak(wakeUpText, TextToSpeech.QUEUE_ADD, myHashAlarm);
回收TTS:
當確定應用程序不再需要TTS的相關功能後,可以在Activity的OnDestroy()方法中調用shutDown()釋放當前TTS實體所占用的資源。
更多關於Android相關內容感興趣的讀者可查看本站專題:《Android數據庫操作技巧總結》、《Android編程之activity操作技巧總結》、《Android文件操作技巧匯總》、《Android編程開發之SD卡操作方法匯總》、《Android開發入門與進階教程》、《Android資源操作技巧匯總》、《Android視圖View技巧總結》及《Android控件用法總結》
希望本文所述對大家Android程序設計有所幫助。
sina刷新 這種下拉刷新的方式是比較簡單的。上個圖: 這種刷新方式的思路是這樣的: 首先是需要一個HeaderVIew也就是刷新時頭部所顯示出來的數據。這個view的
本人使用Win8系統時間久了系統垃圾一大堆 ,後來重裝了Win8系統,再用ADT(adt-bunlde-windows),總會出現ddms初始化錯誤,logcat也無法
因為Android的編譯系統不同於Linux Kernel的遞歸式的編譯系統,它的編譯系統是一種稱之為independent的模式,每個模塊基本獨立(它有可能依賴其他模塊
前言最近Android studio(下文簡稱AS)官方發布了正式版,目前火得不行。個人認為主要是因為android是google自家的產品,AS也是他自己搞的IDE,以