程蔚,周蘭江,王紅斌,黃銀閣
?
基于Android的旅行翻譯語音情景助手APP設計與實現(xiàn)
程蔚,周蘭江,王紅斌,黃銀閣
翻譯APP在出國旅行人群中有很大的需求。傳統(tǒng)翻譯APP輸入方式單一只有文本輸入,存在一定的不便利性,且缺乏特定情景下的翻譯參考例句,缺少一些實用性?;贏ndroid系統(tǒng)結合SpeechKit.framework,Android-async-http以及JSONObject,設計實現(xiàn)一款旅行翻譯語音情景助手APP,除文本輸入功能外,還具備語音輸入功能和情景例句功能,用以解決傳統(tǒng)翻譯APP存在的問題,帶來良好的便利性和實用性。測試表明APP可以流暢運行,具備良好的便利性和實用性。
語音識別;Android;翻譯;情景例句
越來越多的國民開始選擇出國游,對外交流日益加強,傳統(tǒng)翻譯APP[1][2][3]只提供文本輸入方式,當用戶不便進行文字輸入時,單一的輸入方式就顯得不夠便利;當用戶在國外用餐、問路等特定情景下不知道如何表達時,傳統(tǒng)翻譯APP沒有為用戶提供一些翻譯參考。近年來語音識別技術發(fā)展迅速[4][5],將語音作為一種輸入方式無疑更加便利,同時為用戶提供特定情景下的翻譯例句作為參考會使用戶的對外交流更加順暢容易。
Android平臺具有開源、免費等特點,應用層采用JAVA語言開發(fā),使用廣泛[6]。本APP將結合Android系統(tǒng),SpeechKit.framework,Android-async-http以及JSONObject設計實現(xiàn)一款旅行翻譯語音情景助手App,著重解決單一輸入方式和缺少情景翻譯參考例句的問題。
借助Android平臺通過SpeechKit.framework實現(xiàn)語音識別,完成語音轉換文字,進而實現(xiàn)語音輸入功能,這種輸入方式可以帶來更好的便利性;利用JSONObject解析JSON數(shù)據(jù)獲取情景例句,實現(xiàn)情景例句功能,為用戶提供翻譯參考,更具實用性;利用Android-async-http開源項目構建網(wǎng)絡通信組件與服務器通信獲取翻譯結果,使APP具備良好的通信性能。
1.1 客戶端功能設計
(1)目標語言切換功能。該功能主要是選擇切換不同目標語言,設置中文為源語言。可以滿足不同語言國家下的交流需求。由于目前出國游主要集中在日本、韓國、泰國以及英語國家[7],所以本APP設置4種目標語言分別是日語、韓語、泰語及英語。
(2)語音輸入功能。該功能是錄入用戶的語音信息,SpeechKit.framework語音識別技術準確迅速,所以利用SpeechKit.framework實現(xiàn)語音識別功能,將錄音轉換為文字,將其翻譯成目標語言。
(3)文本輸入功能。提供文字輸入功能,將輸入文本翻譯成目標語言。
(4)情景例句功能。提供給用戶一系列情景下的常用語翻譯,比如問候、交通、購物、銀行、餐飲等。因為JSON的數(shù)據(jù)格式是純文本的,具有良好的跨平臺性,易于解析和生成[8][9],所以情景例句以JSON文件形式存放,利用JSONObject類解析得到情景例句并展示,為用戶提供相關情景翻譯參考。整個APP的功能模塊圖如圖1所示:
圖1 Android客戶端功能模塊圖
1.2 網(wǎng)絡通信設計
Android-async-http是一個開源庫,它采用異步請求方式,所有請求都在主線程之外,可以避免主線程阻塞問題,使用該庫可以獲得良好的通信體驗。
Android手機客戶端系統(tǒng)和服務器端翻譯系統(tǒng)構成了旅行翻譯助手的整體架構。用戶在翻譯界面上輸入待翻譯的信息,這些信息被封裝成數(shù)據(jù),借助Android-async-http進行網(wǎng)絡通信[10]將數(shù)據(jù)發(fā)送到服務器端。翻譯系統(tǒng)解析發(fā)送的數(shù)據(jù)并翻譯出結果,將翻譯結果返回給客戶端。整個被翻譯信息的傳輸過程圖如圖2所示:
圖2 翻譯信息傳輸過程圖
1.3 流程設計
APP使用流程是先判斷是否含有網(wǎng)絡,在有網(wǎng)絡的情況下開啟翻譯服務,啟動候選目標語言信息,然后輸入文本或者語音內(nèi)容,再通過網(wǎng)絡發(fā)送給服務器獲得翻譯結果,旅行翻譯語音情景助手業(yè)務流程圖如圖3所示:
圖3 旅行翻譯語音情景助手業(yè)務流程圖
開發(fā)中需要以下環(huán)境:首先是操作系統(tǒng),本文選擇Windows 7操作系統(tǒng);其次安裝JDK7.0版本和安裝帶有Android模擬器插件(ADT22)的Eclipse,使用的SDK版本是API 16,語音識別采用SpeechKit.framework,網(wǎng)絡通信采用Android-async-http開源項目;最后的測試環(huán)境則是LG F160S真機,運行Android4.1.2版本系統(tǒng)。
:2.1 目標語言切換模塊的設計與實現(xiàn)
在導航欄設置一個下拉菜單,點擊下拉菜單可以選擇目標語言,實現(xiàn)目標語言切換。調用函數(shù)調用函數(shù)getSupportActionBar()setListNavigationCallback(SpinnerA-dapter adapter,OnNavigationListener callback)就可以實現(xiàn)點擊導航欄彈出下拉菜單。
2.2 翻譯模塊的設計與實現(xiàn)
翻譯模塊的輸入方法設置兩種,語音輸入和文本輸入。
2.2.1 語音輸入翻譯模塊的設計與實現(xiàn)
當用戶按住語音輸入按鈕時,對著麥克風說話會調用SpeechKit.framework的onRecordingBegin(Recognizer recognizer)方法進行錄音,錄音結束后調用onRecordingDone
(Recognizer recognizer)方法就得到了完整錄音內(nèi)容,接下來調用onResults(Recognizer recognizer, Recognition results)方法將錄音內(nèi)容轉換成文字得到文本對象contentin,經(jīng)過上述幾個步驟就完成了語音識別。
當語音輸入完畢后用戶點擊翻譯,就會調用getSampleAndTranslation(String contentin)方法向服務器發(fā)送網(wǎng)絡請求獲取翻譯結果,方法內(nèi)部實現(xiàn):先創(chuàng)建AsyncHttpClient實例,將contentin與2.1設置的目標語言進行封裝,調用post方法發(fā)到服務器端,接收服務器端返回的翻譯結果,解析并顯示給用戶,這樣就完成了翻譯查詢請求功能。
實現(xiàn)語音識別功能關鍵代碼是:
//創(chuàng)建監(jiān)聽器:監(jiān)聽錄音過程
private Recognizer.Listener createListener() {
return new Recognizer.Listener() {
@Override
public void onRecordingBegin(Recognizer recognizer) {
listeningDialog.setText("Recording...");
listeningDialog.setStoppable(true);
listeningDialog.setRecording(true);
// Create a repeating task to update the audio level
Runnable r = new Runnable() {
@Override
public void run() {
if (listeningDialog != null
&& listeningDialog.isRecording()
&& currentRecognizer != null) {
listeningDialog.setLevel(Float.toString(currentRecognizer .getAudioLevel()));
handler.postDelayed(this, 500);
}
}
};
r.run();
}
@Override
public void onRecordingDone(Recognizer recognizer) {
listeningDialog.setText("Processing...");
listeningDialog.setLevel("");
listeningDialog.setRecording(false);
listeningDialog.setStoppable(false);
}
@Override
public void onError(Recognizer recognizer, SpeechError error) {
if (recognizer != currentRecognizer)
return;
if (listeningDialog.isShowing())
dismissDialog(LISTENING_DIALOG);
currentRecognizer = null;
listeningDialog.setRecording(false);
// Display the error + suggestion in the edit box
String detail = error.getErrorDetail();
String suggestion = error.getSuggestion();
if (suggestion == null)
suggestion = "";
if (m_vp.getCurrentItem() == 0)
mfragment1.getListUpdata(2, detail + " " + suggestion);
// for debugging purpose: printing out the speechkit session id
android.util.Log.d("Nuance SampleVoiceApp",
"Recognizer.Listener.onError: session id ["+ speechKit.getSessionId() + "]");
}
@Override
public void onResults(Recognizer recognizer, Recognition results) {
if (listeningDialog.isShowing())
dismissDialog(LISTENING_DIALOG);
currentRecognizer = null;
listeningDialog.setRecording(false);
int count = results.getResultCount();
//識別音頻的結果
Recognition.Result[] rs = new Recognition.Result[count];
for (int i = 0; i < count; i++) {
rs[i] = results.getResult(i);
}
EditText t = (EditText) findViewById(R.id.text_sentence);
if (t != null)
//將結果放到文本框中
t.setText(rs[0].getText());
mfragment1.getListUpdata(1, rs[0].getText());
m_vp.setCurrentItem(0);
// for debugging purpose: printing out the speechkit session id
android.util.Log.d("Nuance SampleVoiceApp",
"Recognizer.Listener.onResults: session id ["+ speechKit.getSessionId() + "]");
}
};
}
2.2.2 文本輸入翻譯模塊的設計與實現(xiàn)
用戶輸入待翻譯文本,點擊翻譯將待翻譯文本與2.1設置的目標語言一起封裝發(fā)送到服務器端,接收服務器端返回的翻譯結果解析并顯示給用戶。
文本翻譯查詢請求功能部分的代碼其實跟語音翻譯查詢請求功能部分的代碼一樣,都是通過調用2.2.1中所列出的getSampleAndTranslation(String contentin)方法,將輸入文本contentin傳入進來,得到翻譯后的結果顯示到界面中。
2.3 情景例句模塊的設計與實現(xiàn)
情景例句模塊設計了多個大類情景,每個大類又包含多個小類情景,以滿足盡可能多的情景需求同時提供語音朗讀例句功能。
情景例句以JSON文件形式放在工程res/raw文件夾里與代碼一同打包成apk,每種目標語對應一個JSON文件,存放該目標語言下的所有情景例句。當用戶選擇不同目標語言點擊某個情景類別時程序就會從raw文件夾中讀取相應目標語言的JSON文件并通過JSON解析得到例句再顯示給用戶。例如:用戶選擇了中英翻譯,點擊某個大類情景,應用就會調用openRawResource(R.raw.enzh)方法讀取英文JSON文件獲得所有的中英情景例句,根據(jù)用戶點擊的大類名稱調用getXiaoleiNames(String daleiname)方法獲取大類對應下的所有小類名稱。用戶再選擇其中一個小類會調用getLijus(String xiaoleiname, String daleiname)方法可以獲得選中的大類與小類下的所有例句。其中解析JSON數(shù)據(jù)用到的是JSONObeject類來解析。
實現(xiàn)情景例句展示功能關鍵代碼:
public String readTextFile() {
String res = "";
try {
InputStream in = null;
switch (language) {
case 0:
in = con.openRawResource(R.raw.enzh);
break;
case 1:
in = con.openRawResource(R.raw.jpzh);
break;
case 2:
in = con.openRawResource(R.raw.krzh);
break;
case 3:
in = con.openRawResource(R.raw.thzh);
break;
}
int length = in.available();
byte[] buffer = new byte[length];
in.read(buffer);
in.close();
res = EncodingUtils.getString(buffer, "UTF-8");
catch (Exception e) {
e.printStackTrace();
}
return res;
}
public ArrayList
ArrayList
String jsonfile = readTextFile();
String whole = getValuebyKey(jsonfile, "scene");
JSONObject dalei = null;
try {
dalei = new JSONObject(whole);
} catch (JSONException e) {
e.printStackTrace();
}
Iterator daleiKeys = dalei.keys();
while (daleiKeys.hasNext()) {
String daleikey = daleiKeys.next().toString();
try {
if (daleiname.equals(dalei.getJSONObject(daleikey).getString("name"))) {
JSONObject xiaolei = dalei.getJSONObject(daleikey).getJSONObject("scene");
Iterator xiaoleiKeys = xiaolei.keys();
while (xiaoleiKeys.hasNext()) {
String xiaoleikey = xiaoleiKeys.next().toString();
xiaoleinames.add(xiaolei.getJSONObject(xiaoleikey).getString("name"));
}
break;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return xiaoleinames;
}
public ArrayList
ArrayList
String jsonfile = readTextFile();
String whole = getValuebyKey(jsonfile, "scene");
JSONObject dalei = null;
try {
dalei = new JSONObject(whole);
} catch (JSONException e) {
e.printStackTrace();
}
Iterator daleiKeys = dalei.keys();
while (daleiKeys.hasNext()) {
String daleikey = daleiKeys.next().toString();
try {
if (daleiname.equals(dalei.getJSONObject(daleikey).getString("name"))) {JSONObject xiaolei = dalei.getJSONObject(daleikey).getJSONObject("scene");
Iterator xiaoleiKeys = xiaolei.keys();
while (xiaoleiKeys.hasNext()) {
String xiaoleikey = xiaoleiKeys.next().toString();
if (xiaoleiname.equals(xiaolei.getJSONObject(xiaoleikey).getString("name"))) {
JSONObject lijus = xiaolei.getJSONObject(xiaoleikey).getJSONObject("statement");
Iterator lijuKeys = lijus.keys();
while (lijuKeys.hasNext()) {
String lijukey = lijuKeys.next().toString();
JSONObject liju = lijus.getJSONObject(lijukey);
String zh = liju.getString("subject");
String en = liju.getString("text");
SampleSentenceEntityInSentencesView sse = new SampleSentenceEntityInSentencesView();
sse.setSource(zh);
sse.setTarget(en);
Lijus.add(sse);
}
break;
}
}
break;
}} catch (JSONException e) {
e.printStackTrace();
}
}
return Lijus;
}
通過實際使用測試,APP運行流暢穩(wěn)定,翻譯結果反饋及時,一般在2-4秒就會得到結果,使用語音輸入獲得翻譯,在輸入方式上很方便,而且識別準確率高。中英語音輸入翻譯結果,中英情景例句展示如圖4所示:
圖4 中英語音輸入翻譯結果
本軟件是基于Android系統(tǒng)開發(fā),結合SpeechKit.framework實現(xiàn)語音識別,Android-async-http實現(xiàn)網(wǎng)絡通信和JSONObject實現(xiàn)JSON解析,設計實現(xiàn)了一款旅行翻譯語音情景APP,經(jīng)過檢測實驗使用流暢,響應迅速,具備便利和實用性。提供了中英、中日、中韓、中泰4種語言翻譯,基本滿足出國人群的旅游翻譯語種需求。除基本的文本輸入功能外還增加了語音輸入功能,提供了更加方便的輸入方式。情景例句功能提供了銀行、問候、交通、購物等情景下的翻譯例句,為用戶提供了相關翻譯參考,增加了APP的實用性。同時,考慮到出國游上網(wǎng)費用較大,下一步工作將給APP增加離線翻譯功能,即使不聯(lián)網(wǎng)也可以獲得較準確的翻譯結果。
[1] 盛玉林.Android平臺上基于云服務的隨身翻譯工具的設計與實現(xiàn)[D]:碩士學位論文.上海:復旦大學軟件學院,2013.
[2] 浩明.基于Android平臺的手機翻譯系統(tǒng)[J].西北成人教育學院學報,2014,(5):107-109.
[3] 楊眾.基于Android平臺的新蒙文-漢文在線翻譯[D]:碩士學位論文.內(nèi)蒙古:內(nèi)蒙古大學計算機學院,2014.
[4] 何湘智.語音識別的研究與發(fā)展[J].計算機與現(xiàn)代化,2004,(03):3-6.
[5] 李書貞,施玉霞基于語音指令的遠程控制機器人[J].微型電腦應用,2008,24(11):1-3.
[6] 佘建偉,趙凱譯,Reto Meier.Android 4 高級編程[M]:第3版.北京,清華大學出版社,2013,1-3.
[7] 王曉禹,石麗.基于JSON 實現(xiàn) Android 智能終端與 Web 服務器“面向對象”的信息交換[J]. 數(shù)字技術與應用,2012,(4):224-225.
[8] 胡曉鋒.JSON與XML在網(wǎng)絡數(shù)據(jù)傳輸中的應用分析[J].電腦編程技巧與維護,2010,10:77-78.
[9] 劉平. Android手機訪問服務器的一種數(shù)據(jù)交互方法[J].電子設計工程,2010,18(9):96-98.
[10] 馬昭征.基于HTTP的安卓與服務器交互方法的實現(xiàn)[J].無線互聯(lián)科技,2015,03(3):92-96.
黃銀閣(1989-),昆明理工大學,信息工程與自動化學院,女,碩士研究生,研究方向:自然語言處理與移動嵌入式系統(tǒng)研究,昆明,650500
Design and Implementation of Travel Translator APP with Speech Scene Based on Android
Cheng Wei, Zhou Lanjiang, Wang Hongbin, Huang Yinge
(School of Information Engineering and Automation, Kunming University of Science and Technology, Kunming 650500, China)
There is a great need for the translation APP among the crowd travelling abroad. The input method of traditional translation APP is single, only for text input, which is inconvenient, and lack of reference example sentence in specific situateion and practicality. Combined SpeechKit.framework,Android-async-http and JSONObject based on Android system, it designs and implements a travel translator APP with speech scene. In addition to the text input function, it also has the function of voice input and situation sentence to solve the problems of traditional translation APP and brings good convenience and practicality. The test shows that APP can run smoothly with good convenience and practiceality.
Speech Recognition; Android; Translation; Situation Sentence
1007-757X(2016)04-0030-04
TP391
A
(2015.11.25)
云南省教育廳科學研究基金重點項目(2014Z021)
程 蔚(1989-),男,昆明理工大學,信息工程與自動化學院,副教授,碩士研究生,研究方向:自然語言處理與移動嵌入式系統(tǒng)研究,昆明,650500
周蘭江(1989-),男,昆明理工大學,信息工程與自動化學院,副教授,碩士生導師,ccf會員,研究方向:自然語言處理與移動嵌入式系統(tǒng)研究,昆明,650500
王紅斌(1983-),男,昆明理工大學,信息工程與自動化學院,講師,博士,研究方向:智能信息系統(tǒng),分布/并行計算機系統(tǒng),昆明,650500