By 何明桂(http://blog.csdn.net/hmg25) 转载请注明出处

Iphone4SSiri让人眼前一亮,网上出现了无数调戏Siri的视频。真是让android用户们心痒不已。好在随后android阵营中的高手迅速反击,推出了Iris。悲剧的是Iris仅支持英文,让我们这些英语烂的无比的人调戏Iris不成,反被它给调戏了。真是郁闷的不行啊~_~

所以我打算使用android的资源自己打造一个中文版的Siri,让我们用中文随意的来调戏它。(我自己做了一个简单的,哈哈,放在优亿市场里,有兴趣的童鞋可以去体验下http://www.eoemarket.com/apps/61634)

打造Android的中文Siri语音助手(一)——小I机器人的接口_第1张图片

首先,我们来分析Siri的构成,应该大致可以分为3个组成部份:语音识别、自然语言处理、语音输出。对于语音识别,我们可以使用google的语音识别API进行语音的识别,讲语音转成文字。语音输出,其实就是使用TTS,讲文字进行语音合成播放出来,这个android也是有接口可以利用的。真正核心的是自然语言识别处理这个部分,Siri功能的好坏判断很大一部分是取决于此的,这需要很大一个数据库来维持运转,在本地是无法实现的,即使iphoneSiri也是讲语音识别的指令语音上传到Apple的服务器上去解析后返回。由于apple的接口不开放,所以我们无法使用他们的接口,好在世界上拥有这样服务器的不止苹果一家,android上的Iris利用的就是http://start.csail.mit.edu/(自然语音问答系统)这个网站提供的接口以及一个叫做cleverbot的一款智能聊天平台http://www.cleverbot.com/这个聊天网站是支持汉语的,不过,只是支持拼音输入——汗啊。

所以我们的核心任务就是寻找一个支持中文汉字输入的问答系统。经过在网络上长时间的搜索,结果发现——很遗憾,没有找到(PS:如果有谁找到了比较好的网址,麻烦共享,告诉我一声),不过对于我们调戏Siri的这个需求,我找到了一个较好的替代品——聊天机器人.http://www.xiaoi.com/widget/1007/i智能聊天机器人。

经过短时间的摸索,我实现了一个类来,初始化连接小i机器人的接口,发送数据以及接受反馈。用到的接口地址如下:

view plain copy to clipboard print ?
  1. privateStringWebbot_Path="http://webbot.xiaoi.com/engine/widget1007/webbot.js?encoding=utf-8";
  2. privateStringSend_Path="http://122.226.240.164/engine/widget1007/send.js?encoding=utf-8&";
  3. privateStringRecv_Path="http://122.226.240.164/engine/widget1007/recv.js?encoding=utf-8&";
private String Webbot_Path = "http://webbot.xiaoi.com/engine/widget1007/webbot.js?encoding=utf-8"; private String Send_Path = "http://122.226.240.164/engine/widget1007/send.js?encoding=utf-8&"; private String Recv_Path = "http://122.226.240.164/engine/widget1007/recv.js?encoding=utf-8&";
http连接上边的Webbot_Path会反馈回来一些数据:

view plain copy to clipboard print ?
  1. varL_IDS_SEND_MESSAGE_URL="http://122.226.240.164/engine/widget1007/send.js?encoding=utf-8&";
  2. varL_IDS_RECV_MESSAGE_URL="http://122.226.240.164/engine/widget1007/recv.js?encoding=utf-8&";
  3. varL_IDS_GET_RESOURCE_URL="http://122.226.240.164/engine/widget1007/getres.do";
  4. var__sessionId="86491993134658194";
  5. document.write("<scriptsrc='http://122.226.240.164/engine/widget1007/_core.js?encoding=utf-8&'><\/script>");
var L_IDS_SEND_MESSAGE_URL = "http://122.226.240.164/engine/widget1007/send.js?encoding=utf-8&"; var L_IDS_RECV_MESSAGE_URL = "http://122.226.240.164/engine/widget1007/recv.js?encoding=utf-8&"; var L_IDS_GET_RESOURCE_URL = "http://122.226.240.164/engine/widget1007/getres.do"; var __sessionId = "86491993134658194"; document.write("<script src='http://122.226.240.164/engine/widget1007/_core.js?encoding=utf-8&'><\/script>"); 反馈回来的数据包 括上 边的发送和接收地址,以及一个 sessionId,这个sessionId很重要,类似于一个key,用于后边的会话中。由于发送和接收地址是固定的,可以直接写死,但是sessionId是变动的,所以首先需要将它从反馈回来的茫茫数据中提取出来,我使用的是一个简单的正则表达式: view plain copy to clipboard print ?
  1. StringstrResult=EntityUtils.toString(httpResponse.getEntity());
  2. Patternp=Pattern.compile("sessionId=.(\\d+)");//getsessionId
  3. Matcherm=p.matcher(strResult);
  4. if(m.find())mSessionId=m.group(1);
String strResult = EntityUtils.toString(httpResponse.getEntity()); Pattern p = Pattern.compile("sessionId = .(\\d+)"); //get sessionId Matcher m = p.matcher(strResult); if (m.find()) mSessionId = m.group(1);

得到sessionId后,我们就可以进行初始化了,初始化的过程很简单,将sessionId将填入下边格式中,发送到服务器去就行了。

view plain copy to clipboard print ?
  1. StringstrSendJoin=Send_Path+"SID="+mSessionId+"&USR="+mSessionId+"&CMD=JOIN&r=";
String strSendJoin = Send_Path+ "SID="+ mSessionId+"&USR="+ mSessionId+ "&CMD=JOIN&r=";

初始化完成后,就可以使用下边的格式网址发送问题以及接收答案:

String strSend = Send_Path + "SID=" + mSessionId + "&USR=" + mSessionId + "&CMD=CHAT&SIG=You&MSG=" + msg +"&FTN=&FTS=&FTC=&r="; String strRec = Recv_Path + "SID=" + mSessionId + "&USR=" +mSessionId + "&r=";xiaoi.sendMsg(mQuestion);
results = xiaoi.revMsg();

接收到的内容也是需要提取的,使用的是正则表达式:

view plain copy to clipboard print ?
  1. StringmsgTmp=EntityUtils.toString(httpResponse.getEntity());
  2. Patternp=Pattern.compile("\"MSG\":\"(.*?)\"");
  3. Matcherm=p.matcher(msgTmp);
  4. (m.find()){
  5. msg=m.group(1);
String msgTmp = EntityUtils.toString(httpResponse.getEntity()); Pattern p = Pattern.compile("\"MSG\":\"(.*?)\""); Matcher m = p.matcher(msgTmp); if (m.find()) { msg = m.group(1); }

通过上述的小i聊天机器人的接口,你便可以实现一个简单的,可以自由聊天对话的Siri。小I机器人还是很智能的,聊天的对话也很有意思,但是仅仅只能聊天,这个和iphone Siri的差距太大了,所以稍后我们将给它添加另外一个智能的大脑。


本文完整代码如下:

view plain copy to clipboard print ?
  1. publicclassXiaoI{
  2. privateStringWebbot_Path="http://webbot.xiaoi.com/engine/widget1007/webbot.js?encoding=utf-8";
  3. privateStringSend_Path="http://122.226.240.164/engine/widget1007/send.js?encoding=utf-8&";
  4. privateStringRecv_Path="http://122.226.240.164/engine/widget1007/recv.js?encoding=utf-8&";
  5. privateStringmSessionId=null;
  6. privateHttpClienthttpClient=null;
  7. publicbooleaninitialize(){
  8. booleansuccess=false;
  9. HttpParamshttpParams=newBasicHttpParams();
  10. HttpConnectionParams.setConnectionTimeout(httpParams,30000);
  11. HttpConnectionParams.setSoTimeout(httpParams,30000);
  12. httpClient=newDefaultHttpClient(httpParams);
  13. try{
  14. StringstrGetId=Webbot_Path;
  15. HttpGethttpRequest=newHttpGet(strGetId);
  16. HttpResponsehttpResponse=httpClient.execute(httpRequest);
  17. if(httpResponse.getStatusLine().getStatusCode()==HttpURLConnection.HTTP_OK){
  18. StringstrResult=EntityUtils.toString(httpResponse
  19. .getEntity());
  20. Patternp=Pattern.compile("sessionId=.(\\d+)");//getsessionId
  21. Matcherm=p.matcher(strResult);
  22. if(m.find()){
  23. mSessionId=m.group(1);
  24. StringstrSendJoin=Send_Path+"SID="+mSessionId
  25. +"&USR="+mSessionId+"&CMD=JOIN&r=";
  26. HttpGethttpRequest1=newHttpGet(strSendJoin);
  27. httpResponse=httpClient.execute(httpRequest1);
  28. StringstrRevAsk=Recv_Path+"SID="+mSessionId
  29. +"&USR="+mSessionId+"&r=";
  30. HttpGethttpRequest2=newHttpGet(strRevAsk);
  31. httpResponse=httpClient.execute(httpRequest2);
  32. success=true;
  33. }
  34. }
  35. }catch(ClientProtocolExceptione){
  36. e.printStackTrace();
  37. }catch(IOExceptione){
  38. e.printStackTrace();
  39. }catch(Exceptione){
  40. e.printStackTrace();
  41. }finally{
  42. returnsuccess;
  43. }
  44. }
  45. publicvoidsendMsg(Stringmsg){
  46. StringstrTalksend=Send_Path+"SID="+mSessionId+"&USR="
  47. +mSessionId+"&CMD=CHAT&SIG=You&MSG="+msg
  48. +"&FTN=&FTS=&FTC=&r=";
  49. HttpGethttpRequest=newHttpGet(strTalksend);
  50. try{
  51. httpClient.execute(httpRequest);
  52. }catch(ClientProtocolExceptione){
  53. //TODOAuto-generatedcatchblock
  54. e.printStackTrace();
  55. }catch(IOExceptione){
  56. //TODOAuto-generatedcatchblock
  57. e.printStackTrace();
  58. }
  59. }
  60. publicStringrevMsg(){
  61. StringstrTalkRec=Recv_Path+"SID="+mSessionId+"&USR="
  62. +mSessionId+"&r=";
  63. HttpGethttpRequest=newHttpGet(strTalkRec);
  64. Stringmsg=null;
  65. try{
  66. HttpResponsehttpResponse=httpClient.execute(httpRequest);
  67. if(httpResponse.getStatusLine().getStatusCode()==200){
  68. StringmsgTmp=EntityUtils.toString(httpResponse.getEntity());
  69. Patternp=Pattern.compile("\"MSG\":\"(.*?)\"");
  70. Matcherm=p.matcher(msgTmp);
  71. if(m.find()){
  72. msg=m.group(1);
  73. }
  74. }
  75. }catch(ClientProtocolExceptione){
  76. //TODOAuto-generatedcatchblock
  77. e.printStackTrace();
  78. }catch(IOExceptione){
  79. //TODOAuto-generatedcatchblock
  80. e.printStackTrace();
  81. }
  82. returnmsg;
  83. }
  84. }
public class XiaoI { private String Webbot_Path = "http://webbot.xiaoi.com/engine/widget1007/webbot.js?encoding=utf-8"; private String Send_Path = "http://122.226.240.164/engine/widget1007/send.js?encoding=utf-8&"; private String Recv_Path = "http://122.226.240.164/engine/widget1007/recv.js?encoding=utf-8&"; private String mSessionId = null; private HttpClient httpClient = null; public boolean initialize() { boolean success=false; HttpParams httpParams = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(httpParams, 30000); HttpConnectionParams.setSoTimeout(httpParams, 30000); httpClient = new DefaultHttpClient(httpParams); try { String strGetId = Webbot_Path; HttpGet httpRequest = new HttpGet(strGetId); HttpResponse httpResponse = httpClient.execute(httpRequest); if (httpResponse.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK) { String strResult = EntityUtils.toString(httpResponse .getEntity()); Pattern p = Pattern.compile("sessionId = .(\\d+)"); //get sessionId Matcher m = p.matcher(strResult); if (m.find()) { mSessionId = m.group(1); String strSendJoin = Send_Path + "SID=" + mSessionId + "&USR=" + mSessionId + "&CMD=JOIN&r="; HttpGet httpRequest1 = new HttpGet(strSendJoin); httpResponse = httpClient.execute(httpRequest1); String strRevAsk = Recv_Path + "SID=" + mSessionId + "&USR=" + mSessionId + "&r="; HttpGet httpRequest2 = new HttpGet(strRevAsk); httpResponse = httpClient.execute(httpRequest2); success=true; } } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); }finally{ return success; } } public void sendMsg(String msg) { String strTalksend = Send_Path + "SID=" + mSessionId + "&USR=" + mSessionId + "&CMD=CHAT&SIG=You&MSG=" + msg + "&FTN=&FTS=&FTC=&r="; HttpGet httpRequest = new HttpGet(strTalksend); try { httpClient.execute(httpRequest); } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public String revMsg() { String strTalkRec = Recv_Path + "SID=" + mSessionId + "&USR=" + mSessionId + "&r="; HttpGet httpRequest = new HttpGet(strTalkRec); String msg = null; try { HttpResponse httpResponse = httpClient.execute(httpRequest); if (httpResponse.getStatusLine().getStatusCode() == 200) { String msgTmp = EntityUtils.toString(httpResponse.getEntity()); Pattern p = Pattern.compile("\"MSG\":\"(.*?)\""); Matcher m = p.matcher(msgTmp); if (m.find()) { msg = m.group(1); } } } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return msg; } }
使用方法:XiaoIxiaoi = new XiaoI();
xiaoi.initialize();
xiaoi.sendMsg(mQuestion);
results = xiaoi.revMsg();

由于发送接收耗时较多,最好放后台处理。

更多相关文章

  1. Android NDK之接口统一
  2. 使用jni接口完成android本地程序的运行--具体的操作
  3. Android 语音识别示例
  4. 在设置里面增加关闭和打开GPS ,数据流量的接口
  5. Android 语音识别
  6. Android Http通信(使用 标准Java接口)及解析Json
  7. Android语音识别功能使用总结
  8. Activity与Fragment通过接口回调进行通信

随机推荐

  1. PHP常用的字符串处理函数
  2. Python学习系列之 xrange和range的区别!
  3. PHP类与对象的基础概念
  4. DNS
  5. Java基础知识点1
  6. 类声明-实例化-成员-继承-trait特征类
  7. 字符串函数
  8. 深入理解 ProtoBuf 原理与工程实践(概述)
  9. 高性能缓存 Caffeine 原理及实战
  10. php学习笔记(20个常用的字符串函数)