基于Android的旅行翻译语音情景助手APP设计与实现

2016-11-09 08:21程蔚周兰江王红斌黄银阁
微型电脑应用 2016年4期
关键词:语音输入目标语言例句

程蔚,周兰江,王红斌,黄银阁



基于Android的旅行翻译语音情景助手APP设计与实现

程蔚,周兰江,王红斌,黄银阁

翻译APP在出国旅行人群中有很大的需求。传统翻译APP输入方式单一只有文本输入,存在一定的不便利性,且缺乏特定情景下的翻译参考例句,缺少一些实用性。基于Android系统结合SpeechKit.framework,Android-async-http以及JSONObject,设计实现一款旅行翻译语音情景助手APP,除文本输入功能外,还具备语音输入功能和情景例句功能,用以解决传统翻译APP存在的问题,带来良好的便利性和实用性。测试表明APP可以流畅运行,具备良好的便利性和实用性。

语音识别;Android;翻译;情景例句

0 引言

越来越多的国民开始选择出国游,对外交流日益加强,传统翻译APP[1][2][3]只提供文本输入方式,当用户不便进行文字输入时,单一的输入方式就显得不够便利;当用户在国外用餐、问路等特定情景下不知道如何表达时,传统翻译APP没有为用户提供一些翻译参考。近年来语音识别技术发展迅速[4][5],将语音作为一种输入方式无疑更加便利,同时为用户提供特定情景下的翻译例句作为参考会使用户的对外交流更加顺畅容易。

Android平台具有开源、免费等特点,应用层采用JAVA语言开发,使用广泛[6]。本APP将结合Android系统,SpeechKit.framework,Android-async-http以及JSONObject设计实现一款旅行翻译语音情景助手App,着重解决单一输入方式和缺少情景翻译参考例句的问题。

1 系统设计

借助Android平台通过SpeechKit.framework实现语音识别,完成语音转换文字,进而实现语音输入功能,这种输入方式可以带来更好的便利性;利用JSONObject解析JSON数据获取情景例句,实现情景例句功能,为用户提供翻译参考,更具实用性;利用Android-async-http开源项目构建网络通信组件与服务器通信获取翻译结果,使APP具备良好的通信性能。

1.1 客户端功能设计

(1)目标语言切换功能。该功能主要是选择切换不同目标语言,设置中文为源语言。可以满足不同语言国家下的交流需求。由于目前出国游主要集中在日本、韩国、泰国以及英语国家[7],所以本APP设置4种目标语言分别是日语、韩语、泰语及英语。

(2)语音输入功能。该功能是录入用户的语音信息,SpeechKit.framework语音识别技术准确迅速,所以利用SpeechKit.framework实现语音识别功能,将录音转换为文字,将其翻译成目标语言。

(3)文本输入功能。提供文字输入功能,将输入文本翻译成目标语言。

(4)情景例句功能。提供给用户一系列情景下的常用语翻译,比如问候、交通、购物、银行、餐饮等。因为JSON的数据格式是纯文本的,具有良好的跨平台性,易于解析和生成[8][9],所以情景例句以JSON文件形式存放,利用JSONObject类解析得到情景例句并展示,为用户提供相关情景翻译参考。整个APP的功能模块图如图1所示:

图1 Android客户端功能模块图

1.2 网络通信设计

Android-async-http是一个开源库,它采用异步请求方式,所有请求都在主线程之外,可以避免主线程阻塞问题,使用该库可以获得良好的通信体验。

Android手机客户端系统和服务器端翻译系统构成了旅行翻译助手的整体架构。用户在翻译界面上输入待翻译的信息,这些信息被封装成数据,借助Android-async-http进行网络通信[10]将数据发送到服务器端。翻译系统解析发送的数据并翻译出结果,将翻译结果返回给客户端。整个被翻译信息的传输过程图如图2所示:

图2 翻译信息传输过程图

1.3 流程设计

APP使用流程是先判断是否含有网络,在有网络的情况下开启翻译服务,启动候选目标语言信息,然后输入文本或者语音内容,再通过网络发送给服务器获得翻译结果,旅行翻译语音情景助手业务流程图如图3所示:

图3 旅行翻译语音情景助手业务流程图

2.模块详细设计与实现

开发中需要以下环境:首先是操作系统,本文选择Windows 7操作系统;其次安装JDK7.0版本和安装带有Android模拟器插件(ADT22)的Eclipse,使用的SDK版本是API 16,语音识别采用SpeechKit.framework,网络通信采用Android-async-http开源项目;最后的测试环境则是LG F160S真机,运行Android4.1.2版本系统。

:2.1 目标语言切换模块的设计与实现

在导航栏设置一个下拉菜单,点击下拉菜单可以选择目标语言,实现目标语言切换。调用函数调用函数getSupportActionBar()setListNavigationCallback(SpinnerA-dapter adapter,OnNavigationListener callback)就可以实现点击导航栏弹出下拉菜单。

2.2 翻译模块的设计与实现

翻译模块的输入方法设置两种,语音输入和文本输入。

2.2.1 语音输入翻译模块的设计与实现

当用户按住语音输入按钮时,对着麦克风说话会调用SpeechKit.framework的onRecordingBegin(Recognizer recognizer)方法进行录音,录音结束后调用onRecordingDone

(Recognizer recognizer)方法就得到了完整录音内容,接下来调用onResults(Recognizer recognizer, Recognition results)方法将录音内容转换成文字得到文本对象contentin,经过上述几个步骤就完成了语音识别。

当语音输入完毕后用户点击翻译,就会调用getSampleAndTranslation(String contentin)方法向服务器发送网络请求获取翻译结果,方法内部实现:先创建AsyncHttpClient实例,将contentin与2.1设置的目标语言进行封装,调用post方法发到服务器端,接收服务器端返回的翻译结果,解析并显示给用户,这样就完成了翻译查询请求功能。

实现语音识别功能关键代码是:

//创建监听器:监听录音过程

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 文本输入翻译模块的设计与实现

用户输入待翻译文本,点击翻译将待翻译文本与2.1设置的目标语言一起封装发送到服务器端,接收服务器端返回的翻译结果解析并显示给用户。

文本翻译查询请求功能部分的代码其实跟语音翻译查询请求功能部分的代码一样,都是通过调用2.2.1中所列出的getSampleAndTranslation(String contentin)方法,将输入文本contentin传入进来,得到翻译后的结果显示到界面中。

2.3 情景例句模块的设计与实现

情景例句模块设计了多个大类情景,每个大类又包含多个小类情景,以满足尽可能多的情景需求同时提供语音朗读例句功能。

情景例句以JSON文件形式放在工程res/raw文件夹里与代码一同打包成apk,每种目标语对应一个JSON文件,存放该目标语言下的所有情景例句。当用户选择不同目标语言点击某个情景类别时程序就会从raw文件夹中读取相应目标语言的JSON文件并通过JSON解析得到例句再显示给用户。例如:用户选择了中英翻译,点击某个大类情景,应用就会调用openRawResource(R.raw.enzh)方法读取英文JSON文件获得所有的中英情景例句,根据用户点击的大类名称调用getXiaoleiNames(String daleiname)方法获取大类对应下的所有小类名称。用户再选择其中一个小类会调用getLijus(String xiaoleiname, String daleiname)方法可以获得选中的大类与小类下的所有例句。其中解析JSON数据用到的是JSONObeject类来解析。

实现情景例句展示功能关键代码:

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 getXiaoleiNames(String daleiname) {

ArrayList xiaoleinames = new 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 getLijus(String xiaoleiname, String daleiname) {

ArrayList Lijus = new 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;

}

3.APP测试

通过实际使用测试,APP运行流畅稳定,翻译结果反馈及时,一般在2-4秒就会得到结果,使用语音输入获得翻译,在输入方式上很方便,而且识别准确率高。中英语音输入翻译结果,中英情景例句展示如图4所示:

图4 中英语音输入翻译结果

4.总结

本软件是基于Android系统开发,结合SpeechKit.framework实现语音识别,Android-async-http实现网络通信和JSONObject实现JSON解析,设计实现了一款旅行翻译语音情景APP,经过检测实验使用流畅,响应迅速,具备便利和实用性。提供了中英、中日、中韩、中泰4种语言翻译,基本满足出国人群的旅游翻译语种需求。除基本的文本输入功能外还增加了语音输入功能,提供了更加方便的输入方式。情景例句功能提供了银行、问候、交通、购物等情景下的翻译例句,为用户提供了相关翻译参考,增加了APP的实用性。同时,考虑到出国游上网费用较大,下一步工作将给APP增加离线翻译功能,即使不联网也可以获得较准确的翻译结果。

参考文献:

[1] 盛玉林.Android平台上基于云服务的随身翻译工具的设计与实现[D]:硕士学位论文.上海:复旦大学软件学院,2013.

[2] 浩明.基于Android平台的手机翻译系统[J].西北成人教育学院学报,2014,(5):107-109.

[3] 杨众.基于Android平台的新蒙文-汉文在线翻译[D]:硕士学位论文.内蒙古:内蒙古大学计算机学院,2014.

[4] 何湘智.语音识别的研究与发展[J].计算机与现代化,2004,(03):3-6.

[5] 李书贞,施玉霞基于语音指令的远程控制机器人[J].微型电脑应用,2008,24(11):1-3.

[6] 佘建伟,赵凯译,Reto Meier.Android 4 高级编程[M]:第3版.北京,清华大学出版社,2013,1-3.

[7] 王晓禹,石丽.基于JSON 实现 Android 智能终端与 Web 服务器“面向对象”的信息交换[J]. 数字技术与应用,2012,(4):224-225.

[8] 胡晓锋.JSON与XML在网络数据传输中的应用分析[J].电脑编程技巧与维护,2010,10:77-78.

[9] 刘平. Android手机访问服务器的一种数据交互方法[J].电子设计工程,2010,18(9):96-98.

[10] 马昭征.基于HTTP的安卓与服务器交互方法的实现[J].无线互联科技,2015,03(3):92-96.

黄银阁(1989-),昆明理工大学,信息工程与自动化学院,女,硕士研究生,研究方向:自然语言处理与移动嵌入式系统研究,昆明,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-),男,昆明理工大学,信息工程与自动化学院,副教授,硕士研究生,研究方向:自然语言处理与移动嵌入式系统研究,昆明,650500

周兰江(1989-),男,昆明理工大学,信息工程与自动化学院,副教授,硕士生导师,ccf会员,研究方向:自然语言处理与移动嵌入式系统研究,昆明,650500

王红斌(1983-),男,昆明理工大学,信息工程与自动化学院,讲师,博士,研究方向:智能信息系统,分布/并行计算机系统,昆明,650500

猜你喜欢
语音输入目标语言例句
中国大学生对越南语虚词的误用
语音输入法,会异化新闻文本吗?
语音输入,如何才能“出口成章”?
教材插图在英语课堂阅读教学中的运用及实例探讨
好词好句
好词好句
好词好句
好词好句
多媒体英语学习法