標籤:android 機器人 聊天 application json
我相信大家應該知道有款應用叫小黃雞吧!
如果不知道,那你見過那種可以秒回複的聊天應用嗎?
如果仍然沒看到!那你總見過可以迅速回複你的公用賬吧!
如果仍然....親出門左拐
好,不多說。
首先大家都應該瞭解程式,程式就是由人為的設定搭建起來的一套系統,
這裡的機器人也是,簡單的原理就是當你輸入關鍵字後,通過一套演算法,
在資料庫中找到與之最為匹配的內容在返回給你。這個已經有人實現,我們這節教程就用別人
已經實現好的東西去做一??個應用來玩耍~~
(當然如果你非要想知道如何去做,給我留言。看情況我會出篇教程去交大家如何去做這個後端的機器人)
首先我們需要設計程式。
需要用到的類
豆
-------ChatMessage.java(自己建立的類,目的是為了在接受與發送的時候把資訊封裝對象化)
------- Result.java(接受資訊時候需要用到的返回資訊類)
直到
------- AiaiUntil.java(自己建立的類型,用來發送資訊與得到返回資訊的工具)
------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- -------
CharMessageAdapter.java (因為是聊天形式的應用,所以布局需要時動態,這裡引用的布局Adapter需要繼承BaseAdapter )
MainActivity.java(程式入口,程式的總展示層)
以上就是用到的所有類,很少吧。
為什麼這麼少,是因為我們借用的是別人寫好的機器人後台- 圖靈機器人
大家可以點開串連,簡單看看裡面的API是如何用的。
請求方式
API地址: http://www.tuling123.com/openapi/api
請求方式:HTTP GET
資料格式:JSON
返回的資料都是JSON。還有不論是否返回成功都會返回一個代碼,用來判斷是否返回成功
下面我們就進行代碼的編寫,首先是封裝資訊的對象。
ChatMessage。java的
封裝com.www.xiaoaiai.com.bean;進口java.util.Date的;公用類ChatMessage {私人字串名稱;私人弦樂味精;私人類型類型;私人時間日期;公用ChatMessage(){}公用ChatMessage(弦樂味精,類型類型,日期為準){this.msg =味精;this.type =類型;this.date =日期;}//定義枚舉定義類型//枚舉是用來區分資料類型公用枚舉類型{來料,OUTCOMING}公用字串的getName(){返回的名稱;}公用無效的setName(字串名稱){this.name =名稱;}公用字串的getMsg(){返回味精;}公用無效setMsg(弦樂味精){this.msg =味精;}公用類型的getType(){傳回型別;}公用無效的setType(類型類型){this.type =類型;}公開日期GETDATE(){返回日期;}公用無效的setDate(日期為準){this.date =日期;}}下面是資訊結果類
封裝com.www.xiaoaiai.com.bean;/ ** * * @author Srain_zhou *為了發送一個對話對象到伺服器所需要的映射對象 * /公用類結果{//此處注意開頭字母組好小寫,因為返回的結果鍵都是小謝的私人詮釋代碼;私人字串文本;公眾詮釋引用代碼(){傳回碼;}公用無效setCode(INT代碼){this.code =代碼;}公用字串的getText(){返迴文本;}公用無效的setText(字串文本){this.text =文本;}}下面是核心交換類,可以理解為DAO
AiaiUntil.java
包com.www.xiaoaiai.com.until;進口java.io.ByteArrayOutputStream中;進口java.io.IOException的;進口的java.io.InputStream;進口java.io.UnsupportedEncodingException;進口java.net.HttpURLConnection中;進口java.net.MalformedURLException;進口java.net.URLEncoder中;進口java.util.Date的;進口com.google.gson.Gson;進口com.www.xiaoaiai.com.bean.ChatMessage;進口com.www.xiaoaiai.com.bean.ChatMessage.Type;進口com.www.xiaoaiai.com.bean.Result;公用類AiaiUntil {//串連圖靈機器人的介面私人靜態最後字串URL =“htt??p://www.tuling123.com/openapi/api”;//自己的apikey私人靜態最後弦樂API_KEY =“自己去申請的一個APP_KEY體驗下開發的快感吧!”;//發送一個訊息,得到返回的訊息公用靜態ChatMessage的sendMessage(弦樂味精){//建立一個封裝資訊對象ChatMessage chatmessage =新ChatMessage();//此處請看的doGet方法字串jsonRes =的doGet(MSG);// GSON是Google提供的一個JAR包主要用途為序列化的Java對象為JSON字串,或還原序列化JSON字串成的Java對象。//序列化是為了網路傳輸GSON GSON =新GSON();結果結果= NULL;嘗試{//為了獲得返回字串結果= gson.fromJson(jsonRes,Result.class);chatmessage.setMsg(result.getText());}趕上(例外五){chatmessage.setMsg(“伺服器繁忙”);}chatmessage.setDate(新日期());chatmessage.setType(Type.INCOMING);返回chatmessage;}公用靜態字串的doGet(弦樂味精){字串結果=“”;//拼接網址此處需要詳細瞭解圖靈機器人的請求方式字串URL = setRarams(MSG);//輸入資料流InputStream的是= NULL;// ByteArrayOutputStream此類實現了一個輸出資料流,其中的資料被寫入一個位元組數組。ByteArrayOutputStream BAOS = NULL;//構建發送請求的對象嘗試{的java.net.URL url_net =新的java.net.URL(URL);HttpURLConnection的CONN =(HttpURLConnection類)url_net.openConnection();//設定從主機讀取資料逾時conn.setReadTimeout(5 * 1000);//設定串連主機逾時conn.setConnectTimeout(5 * 1000);//設定串連方式conn.setRequestMethod(“GET”);//擷取寫入流是= conn.getInputStream();//設定緩衝區整型長度= -1;//設定緩衝區128位元組byte []的BUF =新的位元組[128];//吧流轉換成字串的類BAOS =新ByteArrayOutputStream();//判斷是否讀完而((長度= is.??read(BUF))!= - 1){baos.write(BUF,0,長度);}//清除緩衝區baos.flush();//把流轉換為字串結果=新的String(baos.toByteArray());}趕上(MalformedURLException的E){// TODO自動產生的catch塊e.printStackTrace();}趕上(IOException異常E){// TODO自動產生的catch塊e.printStackTrace();}最後{//釋放資源嘗試{如果(BAOS!= NULL){baos.close();}}趕上(IOException異常E){// TODO自動產生的catch塊e.printStackTrace();}嘗試{如果(是!= NULL){is.close();}}趕上(IOException異常E){// TODO自動產生的catch塊e.printStackTrace();}}返回結果;}//構建請求路徑的方法公用靜態字串setRarams(弦樂味精){字串URL_value = NULL;嘗試{URL_value =網址+ + + API_KEY“與資訊=”+ URLEncoder.encode(MSG,“UTF-8”)“鍵=?”;}趕上(UnsupportedEncodingException E){// TODO自動產生的catch塊e.printStackTrace();}返回URL_value;}}
CharMessageAdapter.java內容提供者,裡面關於對話的布局檔案你可以按照自己的喜歡自己去設計
簡單解釋下。其中對話方塊是一個listView 裡面分別是兩組不同的ListView(紅色與藍色),請結合下面
代碼去類比定義自己的對話布局,我就覺得我的布局醜,所以就不貼代碼了。自己DIY吧~~
包com.www.xiaoaiai.com;進口java.text.SimpleDateFormat的;進口的java.util.List;進口com.www.xiaoaiai.com.bean.ChatMessage;進口com.www.xiaoaiai.com.bean.ChatMessage.Type;進口android.content.Context;進口android.view.LayoutInflater;進口android.view.View;進口android.view.ViewGroup;進口android.widget.BaseAdapter;進口android.widget.TextView;公用類CharMessageAdapter擴充了BaseAdapter { / ***對於一個沒有被載入或者想要動態載入的介面,都需要使用充氣來載入。 *的Andr??oid裡面想要建立一個畫面的時候,初學一般都是建立一個類,繼承活動基類,*然後在的onCreate裡面使用的setContentView方法來載入一個在XML裡定義好的介面。 *其實在活動裡面就使用了LayoutInflater來載入介面, *通過getSystemService(Context.LAYOUT_INFLATER_SERVICE)方法可以獲得一個LayoutInflater, *也可以通過LayoutInflater吹氣= getLayoutInflater(); *來獲得。然後使用充氣方法來載入布局的XML, *在實際開發種LayoutInflater這個類還是非常有用的,它的作用類似於findViewById()*不同點是LayoutInflater是用來找布局下的xml布局檔案,*並且執行個體化!而findViewById()是找具體的xml下的具體視窗小組件控制項。* ///用來重載布局的對象,是機器人已經幫我們做好的類私人LayoutInflater mInflater;//聊天資訊資料集合私人名單<ChatMessage> mDatas;公用CharMessageAdapter(上下文語境,名單<ChatMessage> mDatas){mInflater = LayoutInflater.from(上下文);this.mDatas = mDatas;}//繼承BaseAdapter需要重寫的方法,擷取資料的長度@覆蓋公眾詮釋getCount將(){// TODO自動產生方法存根返回mDatas.size();}//繼承BaseAdapter需要重寫的方法,擷取資料所處的項目@覆蓋公用對象的getItem(INT位置){// TODO自動產生方法存根返回mDatas.get(位置);}//繼承BaseAdapter需要重寫的方法,擷取ITEMID@覆蓋眾長getItemId(整數位){// TODO自動產生方法存根回到位置;}/ ** *因為本次需要布局兩次不同位置所以需要多寫兩個方法 * /// getItemViewType方法告訴ListView中每行該顯示哪種項目@覆蓋公眾詮釋getItemViewType(整數位){ChatMessage chatMessage = mDatas.get(位置);如果(chatMessage.getType()== Type.INCOMING){返回0;}返回1;}// getViewTypeCount這個方法告訴ListView控制項我共有多少種項目@覆蓋公眾詮釋getViewTypeCount(){// TODO自動產生方法存根返回2;}/ ** *就是一個持有人的類,他裡面一般沒有方法, *只有屬性,作用就是一個臨時的儲存器, *把你getView方法中每次返回的視圖存起來,可以下次再用。 *這樣做的好處就是不必每次都到布局檔案中去拿到你的視圖,提高了效率。 * / 私人final類ViewHolder { TextView的mDate; TextView的MMSG; }//如下這個就是如何動態布局的代碼@覆蓋公用查看getView(INT位置,查看convertView,父母的ViewGroup){ChatMessage chatMessage = mDatas.get(位置);//上文中說出用處,提高頁面效率ViewHolder viewholder = NULL;如果(convertView == NULL){//通過的ItemType設定不同的布局如果(getItemViewType(位置)== 0){convertView = mInflater.inflate(R.layout.item_from_msg,父母,假);viewholder =新ViewHolder();viewholder.mDate =(TextView的)convertView.findViewById(R.id.from_msg_date);viewholder.mMsg =(TextView的)convertView.findViewById(R.id.from_msg);}其他{convertView = mInflater.inflate(R.layout.item_to_msg,父母,假);viewholder =新ViewHolder();viewholder.mDate =(TextView的)convertView.findViewById(R.id.to_msg_date);viewholder.mMsg =(TextView的)convertView.findViewById(R.id.to_msg);}//在使用LayoutInflater對象進行查看擴充的標籤的使用//用來標記convertView,如果viewholder對象有就不在重建對象,為了效率!convertView.setTag(viewholder);}其他{viewholder =(ViewHolder)convertView.getTag();}//下面這段代碼慢慢看,很簡單SimpleDateFormat的DF =新的SimpleDateFormat(“YYYY-MM-DD HH:MM:SS”);viewholder.mDate.setText(df.format(chatMessage.getDate()));viewholder.mMsg.setText(chatMessage.getMsg());返回convertView;}}
下面就是最主要的主MainActivity了~~
package com.www.xiaoaiai.com;import java.util.ArrayList;import java.util.Date;import java.util.List;import com.www.xiaoaiai.com.bean.ChatMessage;import com.www.xiaoaiai.com.bean.ChatMessage.Type;import com.www.xiaoaiai.com.until.AiaiUntil;import android.support.v7.app.ActionBarActivity;import android.text.TextUtils;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.Window;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.ListView;import android.widget.Toast;public class MainActivity extends ActionBarActivity {//最外邊的對話布局private ListView mMsg;//內容提供對象private CharMessageAdapter mAdapter;//資料集合private List<ChatMessage> mDatas;//VIEWprivate EditText mInputMsg;private Button mSendMsg;//因為要更新介面所以要用 Handler mHandlerprivate Handler mHandler =new Handler(){public void handleMessage(android.os.Message msg) {//等待ijieshou子線程ChatMessage cm=(ChatMessage)msg.obj;mDatas.add(cm);mAdapter.notifyDataSetChanged();mMsg.setSelection(mDatas.size()-1);};};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_main);//初始化視圖initView();//初始化資料initDatas();//初始化監聽initListener();}private void initListener() {mSendMsg.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {final String toMsg = mInputMsg.getText().toString();if(TextUtils.isEmpty(toMsg)){Toast.makeText(MainActivity.this, "發送訊息不可以為空白", Toast.LENGTH_SHORT).show();return;}//為了做聊天的效果ChatMessage toMessage = new ChatMessage();toMessage.setDate(new Date());toMessage.setMsg(toMsg);toMessage.setType(Type.OUTCOMING);mDatas.add(toMessage);mAdapter.notifyDataSetChanged();mMsg.setSelection(mDatas.size()-1);mInputMsg.setText("");new Thread(new Runnable() {public void run() {//網路訪問不能用在主線程中應該在子線程中ChatMessage fromMessage =AiaiUntil.sendMessage(toMsg);Message m =Message.obtain();m.obj=fromMessage;//發送後 會在handler中的handleMessage中接受到mHandler.sendMessage(m);}}).start();}});}private void initDatas() {mDatas =new ArrayList<ChatMessage>();mDatas.add(new ChatMessage("你好,我是小艾艾",Type.INCOMING,new Date()));mAdapter = new CharMessageAdapter(this,mDatas);mMsg.setAdapter(mAdapter);}private void initView() {mMsg=(ListView)findViewById(R.id.id_list_view_01);mInputMsg=(EditText)findViewById(R.id.input_msg); mSendMsg=(Button)findViewById(R.id.id_send_msg);}}
希望對大家的學習有協助~~~
提示!~~~
1如果你編譯不出現R檔案,也就是說R. 不出來 說明你的XML檔案絕對有錯誤
2在這個APP中,千萬別忘記加網路存取權限~
在
AndroidManifest.xml 檔案中
加入如下代碼
<uses-permission android:name="android.permission.INTERNET"/> 載入application 標籤外面
手把手教你做Android聊天機器人