打造Android的中文Siri語音助手(一)——小I機器人的介面

來源:互聯網
上載者:User

 

 

By 何明桂(http://blog.csdn.net/hmg25) 轉載請註明出處

Iphone4S的Siri讓人眼前一亮,網上出現了無數調戲Siri的視頻。真是讓android使用者們心癢不已。好在隨後android陣營中的高手迅速反擊,推出了Iris。悲劇的是Iris僅支援英文,讓我們這些英語爛的無比的人調戲Iris不成,反被它給調戲了。真是鬱悶的不行啊~_~

所以我打算使用android的資源自己打造一個中文版的Siri,讓我們用中文隨意的來調戲它。(我自己做了一個簡單的,哈哈,放在優億市場裡,有興趣的童鞋可以去體驗下http://www.eoemarket.com/apps/61634)

 

 

 

   首先,我們來分析Siri的構成,應該大致可以分為3個組成部份:語音辨識、自然語言處理、語音輸出。對於語音辨識,我們可以使用google的語音辨識API進行語音的識別,講語音轉成文字。語音輸出,其實就是使用TTS,講文字進行語音合成播放出來,這個android也是有介面可以利用的。真正核心的是自然語言識別處理這個部分,Siri功能的好壞判斷很大一部分是取決於此的,這需要很大一個資料庫來維持運轉,在本地是無法實現的,即使iphone的Siri也是講語音辨識的指令語音上傳到Apple的伺服器上去解析後返回。由於apple的介面不開放,所以我們無法使用他們的介面,好在世界上擁有這樣伺服器的不止蘋果一家,android上的Iris利用的就是http://start.csail.mit.edu/(自然語音問答系統)這個網站提供的介面以及一個叫做cleverbot的一款智能聊天平台http://www.cleverbot.com/這個聊天網站是支援漢語的,不過,只是支援拼音輸入——汗啊。

 

   所以我們的核心任務就是尋找一個支援中文漢字輸入的問答系統。經過在網路上長時間的搜尋,結果發現——很遺憾,沒有找到(PS:如果有誰找到了比較好的網址,麻煩共用,告訴我一聲),不過對於我們調戲Siri的這個需求,我找到了一個較好的替代品——聊天機器人.http://www.xiaoi.com/widget/1007/小i智能聊天機器人。

   經過短時間的摸索,我實現了一個類來,初始化串連小i機器人的介面,發送資料以及接受反饋。用到的介面地址如下:

 

 

   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,會反饋回來一些資料:

 

 

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是變動的,所以首先需要將它從反饋回來的茫茫資料中提取出來,我使用的是一個簡單的Regex:

 

       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將填入下邊格式中,發送到伺服器去就行了。

 

 

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();

接收到的內容也是需要提取的,使用的是Regex:

 

 

 String  msgTmp = EntityUtils.toString(httpResponse.getEntity()); 

Pattern p = Pattern.compile("\"MSG\":\"(.*?)\""); 

Matcher m = p.matcher(msgTmp); 

 (m.find()) { 

 msg = m.group(1); 

 

 

    通過上述的小i聊天機器人的介面,你便可以實現一個簡單的,可以自由聊天對話的Siri。小I機器人還是很智能的,聊天的對話也很有意思,但是僅僅只能聊天,這個和iphone Siri的差距太大了,所以稍後我們將給它添加另外一個智能的大腦。

 

本文完整代碼如下:

 

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; 

 

    } 

 

使用方法:XiaoI xiaoi = new XiaoI();

                xiaoi.initialize();

               xiaoi.sendMsg(mQuestion);

       results = xiaoi.revMsg();

 

 

由於發送接收耗時較多,最好放幕後處理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.