【Service】使用有道翻译API构建翻译服务

声明:Ryan的博客文章欢迎您的转载,但在转载的同时,请注明文章的来源出处,不胜感激! :-) 

http://my.oschina.net/ryanhoo/blog/100589

        今天我们来学习使用现有的服务构建应用的功能模块——利用有道的翻译API构建一个小的翻译程序。之前曾想用Google的翻译API来实现,后来发现这项服务是收费的,所以用有道的,免费才是王道。

        先来看看效果

    功能相当简单,主要提供英汉互译(其实参数无需传入语言,有道翻译机器人会自动识别)。

    实现步骤如下:

    申请有道翻译API KEY

    请在这个页面填写必要信息,并记录返回的Key和keyfrom,调用有道的翻译服务将需要使用它。

    在申请到Key以后,请花几分钟时间简短的浏览下有道API调用的文档,就在申请页的下面。

    请求接口非常简单:

1 http://fanyi.youdao.com/openapi.do?keyfrom=<keyfrom>&key=<key>&type=data&doctype=<doctype>&version=1.1&q=要翻译的文本

    唯一在变动的参数是翻译文本,这让我们定义AIDL变得非常容易。

    编写AIDL远程服务调用接口

    新建ITranslateService.aidl,定义一个简单的接口,只需传入一个参数——待翻译文本。

1 package com.iedgeco.ryan.translate.service;
2  
3 interface ITranslate{
4     String traslate(in String text);
5 }
     实现服务  

01 public class TranslateService extends Service {
02  
03     public static final String TAG = "TranslateService";
04      
05     //binder
06     private final ITranslate.Stub mBinder = new ITranslate.Stub() {
07         @Override
08         public String traslate(String text) throws RemoteException {
09              
10             try {
11                 return Translator.translate(text);
12             catch (Exception e) {
13                 Log.e(TAG, "Failed to translate", e);
14                 return null;
15             }
16         }
17     };
18      
19     @Override
20     public IBinder onBind(Intent intent) {
21         return mBinder;
22     }
23  
24 }
    在AIDL所在的包下实现一个Service类  TranslateService   ,实现相当的简单。因为是远程调用服务而非本地服务,后期需要使用bindService,因此我们必须返回IBinder实例。这里的IBinder中具体的翻译操作,我交给一个工具类 Translator   的静态方法完成,只需传入待翻译文本即可。 
01 public class Translator {
02  
03     private static final String TAG = "Translator";
04  
05     private static final String ENCODING = "UTF-8";
06  
07     /**
08      * <pre>
09      * 请求标准: http://fanyi.youdao.com/openapi.do?
10      *      keyfrom=<keyfrom>&
11      *      key=<key>&
12      *      type=data&
13      *      doctype=<doctype>&
14      *      version=1.1&
15      *      q=要翻译的文本
16      * 版本:1.1,请求方式:get,编码方式:utf-8
17      * 主要功能:
18      *      中英互译,同时获得有道翻译结果和有道词典结果(可能没有)
19      * 参数说明:
20      *      type - 返回结果的类型,固定为data
21      *      doctype - 返回结果的数据格式,xml或json或jsonp
22      *      version - 版本,当前最新版本为1.1
23      *      q - 要翻译的文本,不能超过200个字符,需要使用utf-8编码
24      *  errorCode:  
25      *      0 - 正常  
26      *      20 - 要翻译的文本过长  
27      *      30 - 无法进行有效的翻译  
28      *      40 - 不支持的语言类型  
29      *      50 - 无效的key
30      * </pre>
31      * @throws IOException
32      * @throws ClientProtocolException
33      * */
34     public static String translate(String text) throws Exception {
35         String url = "http://fanyi.youdao.com/openapi.do?keyfrom=" + StaticDef.KEY_FROM
36                 "&key=" + StaticDef.KEY_FOR_TRANSLATE
37                 "&type=data"
38                 "&doctype=json"
39                 "&version=1.1"
40                 "&q=" + text;
41         try{
42             HttpClient client = new DefaultHttpClient();
43             HttpGet httpGet = new HttpGet(url);
44             HttpResponse response = client.execute(httpGet);
45             InputStream is = response.getEntity().getContent();
46             BufferedReader reader = new BufferedReader(new InputStreamReader(is, ENCODING));
47             StringBuffer result = new StringBuffer();
48             String string = null;
49             if(null != (string = reader.readLine()))
50                 result.append(string).append('\n');
51             //TODO parse the response json string
52             String translation = (String) new JSONObject(result.toString())
53                 .getJSONArray("translation").get(0);
54              
55             Log.i(TAG, "result: " + result.toString());
56             return translation;
57         }finally{
58             //close stream here
59         }
60     }
61 }

    实现UI并调用翻译服务

    UI相对简单,具体的布局请见Github中的代码,后面我会给出地址。

    MainActivity中的方法也比较简单,在onCreate中启用服务(doBindService),在onDestory中解除绑定,销毁服务(doUnBindService),可以使用doTranslate进行后台翻译(由于服务是直接运行在Main线程上的,我开启了一个异步线程来完成这个工作,并将结果反馈给Handler,由它来更新UI)。

    doBindService

1 private void doBindService(){
2     Intent service = new Intent(StaticDef.ACTION_TRANALATE);
3     bindService(service, serviceConn, Context.BIND_AUTO_CREATE);
4 }

    doUnBindService

1 private void doUnBindService(){
2     unbindService(serviceConn);
3 }

    doTranslate

01 //launch a thread for translation
02 private void doTranslate(){
03     new Thread(new Runnable() {
04         @Override
05         public void run() {
06             String result = null;
07             try {
08                 String input = etInput.getText().toString();
09                 //use the translate service
10                 result = mTranslateService.traslate(input);
11                 //send message callback
12                 Message msg = new Message();
13                 msg.obj = result;
14                 if(result == null){
15                     msg.what = TRANSLATE_ERROR;
16                     throw new Exception("Failed to get a translation...");
17                 }
18                 msg.what = TRANSLATE_COMPLETED;
19                 mHandler.sendMessage(msg);
20             catch (Exception e) {
21                 Log.e(TAG, "Error happened while translating...", e);
22             }
23         }
24     }).start();
25 }

    Handler

01 private static final int TRANSLATE_COMPLETED = 0;
02 private static final int TRANSLATE_ERROR = 1;
03  
04 //controller
05 private Handler mHandler = new Handler(){
06     @Override
07     public void handleMessage(Message msg) {
08         switch (msg.what) {
09         case TRANSLATE_COMPLETED:
10             String result = (String) msg.obj;
11             etTranslation.setText(result);
12             etInput.selectAll();
13             break;
14         case TRANSLATE_ERROR:
15             Log.e(TAG, "translation error");
16             break;
17         default:
18             break;
19         }
20     }
21      
22 };

    总结

    代码不多,逻辑也相对简单,主要是学习如何使用AIDL调用远程服务。

    提示:使用之前,请用申请到的KEY替换config包下的key以及keyfrom!

    代码

    详见我的Github:https://github.com/ryanhoo/TranslateService

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值