分享

打造Android的中文Siri语音助手(一)

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

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

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

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

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

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

  1.    private String Webbot_Path = "http://webbot./engine/widget1007/webbot.js?encoding=utf-8";  
  2. private String Send_Path = "http://122.226.240.164/engine/widget1007/send.js?encoding=utf-8&";  
  3. private String Recv_Path = "http://122.226.240.164/engine/widget1007/recv.js?encoding=utf-8&";  
  1.    private String Webbot_Path = "http://webbot./engine/widget1007/webbot.js?encoding=utf-8";  
  2. private String Send_Path = "http://122.226.240.164/engine/widget1007/send.js?encoding=utf-8&";  
  3. private String Recv_Path = "http://122.226.240.164/engine/widget1007/recv.js?encoding=utf-8&";  

      http连接上边的Webbot_Path会反馈回来一些数据:

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

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

  1. String   strSendJoin = Send_Path+ "SID="+ mSessionId+"&USR="+ mSessionId+ "&CMD=JOIN&r=";  
  1. 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();

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

  1.  String  msgTmp = EntityUtils.toString(httpResponse.getEntity());  
  2. Pattern p = Pattern.compile("\"MSG\":\"(.*?)\"");  
  3. Matcher m = p.matcher(msgTmp);  
  4.  (m.find()) {  
  5.  msg = m.group(1);  
  1.  String  msgTmp = EntityUtils.toString(httpResponse.getEntity());  
  2. Pattern p = Pattern.compile("\"MSG\":\"(.*?)\"");  
  3. Matcher m = p.matcher(msgTmp);  
  4.  (m.find()) {  
  5.  msg = m.group(1);  

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


本文完整代码如下:

  1. public class XiaoI {  
  2.   
  3.     private String Webbot_Path = "http://webbot./engine/widget1007/webbot.js?encoding=utf-8";  
  4.     private String Send_Path = "http://122.226.240.164/engine/widget1007/send.js?encoding=utf-8&";  
  5.     private String Recv_Path = "http://122.226.240.164/engine/widget1007/recv.js?encoding=utf-8&";  
  6.   
  7.     private String mSessionId = null;  
  8.     private HttpClient httpClient = null;  
  9.   
  10.     public boolean initialize() {  
  11.         boolean success=false;    
  12.         HttpParams httpParams = new BasicHttpParams();  
  13.         HttpConnectionParams.setConnectionTimeout(httpParams, 30000);  
  14.         HttpConnectionParams.setSoTimeout(httpParams, 30000);  
  15.         httpClient = new DefaultHttpClient(httpParams);  
  16.         try {  
  17.             String strGetId = Webbot_Path;  
  18.             HttpGet httpRequest = new HttpGet(strGetId);  
  19.             HttpResponse httpResponse = httpClient.execute(httpRequest);  
  20.             if (httpResponse.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK) {  
  21.                 String strResult = EntityUtils.toString(httpResponse  
  22.                         .getEntity());  
  23.                 Pattern p = Pattern.compile("sessionId = .(\\d+)"); //get sessionId   
  24.                 Matcher m = p.matcher(strResult);  
  25.                 if (m.find()) {  
  26.                     mSessionId = m.group(1);  
  27.                     String strSendJoin = Send_Path + "SID=" + mSessionId  
  28.                             + "&USR=" + mSessionId + "&CMD=JOIN&r=";  
  29.                     HttpGet httpRequest1 = new HttpGet(strSendJoin);  
  30.                     httpResponse = httpClient.execute(httpRequest1);  
  31.   
  32.                     String strRevAsk = Recv_Path + "SID=" + mSessionId  
  33.                             + "&USR=" + mSessionId + "&r=";  
  34.                     HttpGet httpRequest2 = new HttpGet(strRevAsk);  
  35.                     httpResponse = httpClient.execute(httpRequest2);  
  36.                     success=true;  
  37.                 }  
  38.             }  
  39.         } catch (ClientProtocolException e) {  
  40.             e.printStackTrace();  
  41.         } catch (IOException e) {  
  42.             e.printStackTrace();  
  43.         } catch (Exception e) {  
  44.             e.printStackTrace();  
  45.         }finally{  
  46.             return success;  
  47.         }  
  48.     }  
  49.   
  50.     public void sendMsg(String msg) {  
  51.         String strTalksend = Send_Path + "SID=" + mSessionId + "&USR="  
  52.                 + mSessionId + "&CMD=CHAT&SIG=You&MSG=" + msg  
  53.                 + "&FTN=&FTS=&FTC=&r=";  
  54.         HttpGet httpRequest = new HttpGet(strTalksend);  
  55.         try {  
  56.             httpClient.execute(httpRequest);  
  57.         } catch (ClientProtocolException e) {  
  58.             // TODO Auto-generated catch block   
  59.             e.printStackTrace();  
  60.         } catch (IOException e) {  
  61.             // TODO Auto-generated catch block   
  62.             e.printStackTrace();  
  63.         }  
  64.     }  
  65.   
  66.     public String revMsg() {  
  67.         String strTalkRec = Recv_Path + "SID=" + mSessionId + "&USR="  
  68.                 + mSessionId + "&r=";  
  69.         HttpGet httpRequest = new HttpGet(strTalkRec);  
  70.         String msg = null;  
  71.         try {  
  72.             HttpResponse httpResponse = httpClient.execute(httpRequest);  
  73.             if (httpResponse.getStatusLine().getStatusCode() == 200) {  
  74.                 String msgTmp = EntityUtils.toString(httpResponse.getEntity());  
  75.                 Pattern p = Pattern.compile("\"MSG\":\"(.*?)\"");  
  76.                 Matcher m = p.matcher(msgTmp);  
  77.                 if (m.find()) {  
  78.                     msg = m.group(1);  
  79.                 }  
  80.             }  
  81.         } catch (ClientProtocolException e) {  
  82.             // TODO Auto-generated catch block   
  83.             e.printStackTrace();  
  84.         } catch (IOException e) {  
  85.             // TODO Auto-generated catch block   
  86.             e.printStackTrace();  
  87.         }  
  88.         return msg;  
  89.   
  90.     }  
  91. }  
  1. public class XiaoI {  
  2.   
  3.     private String Webbot_Path = "http://webbot./engine/widget1007/webbot.js?encoding=utf-8";  
  4.     private String Send_Path = "http://122.226.240.164/engine/widget1007/send.js?encoding=utf-8&";  
  5.     private String Recv_Path = "http://122.226.240.164/engine/widget1007/recv.js?encoding=utf-8&";  
  6.   
  7.     private String mSessionId = null;  
  8.     private HttpClient httpClient = null;  
  9.   
  10.     public boolean initialize() {  
  11.         boolean success=false;    
  12.         HttpParams httpParams = new BasicHttpParams();  
  13.         HttpConnectionParams.setConnectionTimeout(httpParams, 30000);  
  14.         HttpConnectionParams.setSoTimeout(httpParams, 30000);  
  15.         httpClient = new DefaultHttpClient(httpParams);  
  16.         try {  
  17.             String strGetId = Webbot_Path;  
  18.             HttpGet httpRequest = new HttpGet(strGetId);  
  19.             HttpResponse httpResponse = httpClient.execute(httpRequest);  
  20.             if (httpResponse.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK) {  
  21.                 String strResult = EntityUtils.toString(httpResponse  
  22.                         .getEntity());  
  23.                 Pattern p = Pattern.compile("sessionId = .(\\d+)"); //get sessionId  
  24.                 Matcher m = p.matcher(strResult);  
  25.                 if (m.find()) {  
  26.                     mSessionId = m.group(1);  
  27.                     String strSendJoin = Send_Path + "SID=" + mSessionId  
  28.                             + "&USR=" + mSessionId + "&CMD=JOIN&r=";  
  29.                     HttpGet httpRequest1 = new HttpGet(strSendJoin);  
  30.                     httpResponse = httpClient.execute(httpRequest1);  
  31.   
  32.                     String strRevAsk = Recv_Path + "SID=" + mSessionId  
  33.                             + "&USR=" + mSessionId + "&r=";  
  34.                     HttpGet httpRequest2 = new HttpGet(strRevAsk);  
  35.                     httpResponse = httpClient.execute(httpRequest2);  
  36.                     success=true;  
  37.                 }  
  38.             }  
  39.         } catch (ClientProtocolException e) {  
  40.             e.printStackTrace();  
  41.         } catch (IOException e) {  
  42.             e.printStackTrace();  
  43.         } catch (Exception e) {  
  44.             e.printStackTrace();  
  45.         }finally{  
  46.             return success;  
  47.         }  
  48.     }  
  49.   
  50.     public void sendMsg(String msg) {  
  51.         String strTalksend = Send_Path + "SID=" + mSessionId + "&USR="  
  52.                 + mSessionId + "&CMD=CHAT&SIG=You&MSG=" + msg  
  53.                 + "&FTN=&FTS=&FTC=&r=";  
  54.         HttpGet httpRequest = new HttpGet(strTalksend);  
  55.         try {  
  56.             httpClient.execute(httpRequest);  
  57.         } catch (ClientProtocolException e) {  
  58.             // TODO Auto-generated catch block  
  59.             e.printStackTrace();  
  60.         } catch (IOException e) {  
  61.             // TODO Auto-generated catch block  
  62.             e.printStackTrace();  
  63.         }  
  64.     }  
  65.   
  66.     public String revMsg() {  
  67.         String strTalkRec = Recv_Path + "SID=" + mSessionId + "&USR="  
  68.                 + mSessionId + "&r=";  
  69.         HttpGet httpRequest = new HttpGet(strTalkRec);  
  70.         String msg = null;  
  71.         try {  
  72.             HttpResponse httpResponse = httpClient.execute(httpRequest);  
  73.             if (httpResponse.getStatusLine().getStatusCode() == 200) {  
  74.                 String msgTmp = EntityUtils.toString(httpResponse.getEntity());  
  75.                 Pattern p = Pattern.compile("\"MSG\":\"(.*?)\"");  
  76.                 Matcher m = p.matcher(msgTmp);  
  77.                 if (m.find()) {  
  78.                     msg = m.group(1);  
  79.                 }  
  80.             }  
  81.         } catch (ClientProtocolException e) {  
  82.             // TODO Auto-generated catch block  
  83.             e.printStackTrace();  
  84.         } catch (IOException e) {  
  85.             // TODO Auto-generated catch block  
  86.             e.printStackTrace();  
  87.         }  
  88.         return msg;  
  89.   
  90.     }  
  91. }  

使用方法:XiaoI xiaoi = new XiaoI();
                xiaoi.initialize();
               xiaoi.sendMsg(mQuestion);
       results = xiaoi.revMsg();

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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约