Android学习之智能聊天机器人(图灵机器人)

今天我们来分享一个有趣的应用:Android版的智能聊天机器人

开发工具:Eclipse

开发时间:2015/07/07 

所用技术:图灵机器人API  网络通信之异步请求 接口回调  自定义Adapter

下面我将详细叙述开发的步骤:

第一步:申请图灵机器人的API KEY

方法很简单,只需要在图灵机器人API官网注册一个账号,注册成功之后,会显示一个API KEY

图灵机器人API 账号注册网址:图灵机器人

注册成功后,点击平台接入,认真看一下API接入的流程

第二步:开始创建工程进行编码,首先,新建一个class,用作异步请求图灵机器人API,获取返回信息

以下是我的HttpData 的源码:

 1 package com.oysd.tuling;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.InputStream;
 5 import java.io.InputStreamReader;
 6 
 7 import org.apache.http.HttpEntity;
 8 import org.apache.http.HttpResponse;
 9 import org.apache.http.client.methods.HttpGet;
10 import org.apache.http.impl.client.DefaultHttpClient;
11 
12 import android.os.AsyncTask;
13 
14 public class HttpData extends AsyncTask<String, Void, String> {
15 
16     private DefaultHttpClient mHttpClient;
17     private HttpGet mHttpGet;
18     private String url;
19     private HttpResponse mHttpResponse;//获取Http请求的返回
20     private HttpEntity mHttpEntity;//创建Http实体
21     private InputStream in;//将获取的数据转换成流文件来处理
22     private HttpGetDataListener listener;
23     
24     public HttpData(String url,HttpGetDataListener listener){
25         this.url = url;
26         this.listener = listener;
27     }
28     
29     @Override
30     protected String doInBackground(String... arg0) {
31         // TODO Auto-generated method stub
32         try{
33             mHttpClient = new DefaultHttpClient();
34             mHttpGet = new HttpGet(url);
35             mHttpResponse = mHttpClient.execute(mHttpGet);//通过客户端来进行发送
36             mHttpEntity = mHttpResponse.getEntity();//通过Response对象获取数据
37             in = mHttpEntity.getContent();//通过Http的实体来获取具体的内容
38             //通过缓存区进行读取
39             BufferedReader br = new BufferedReader(new InputStreamReader(in));
40             String line = null;
41             StringBuffer sb = new StringBuffer();
42             while((line = br.readLine()) != null){
43                 sb.append(line);
44             }    
45             return sb.toString();
46             
47         }catch(Exception e){
48             e.printStackTrace();
49             
50         }
51         
52         
53         return null;
54     }
55     
56     @Override
57     protected void onPostExecute(String result) {
58         listener.getDataUrl(result);
59         super.onPostExecute(result);
60     }
61     
62     
63 }
View Code

其中,我添加了一个接口类,为了让主类能够获取到这个异步申请返回的result

以下是我的接口类(里面就一个方法,只是学习一下这种逻辑,勿喷……):

1 package com.oysd.tuling;
2 
3 public interface HttpGetDataListener {
4     void getDataUrl(String data);
5 }
View Code

当我们自己发的消息以及我们自己的开发API KEY 都获取之后发给图灵机器人API,就可以获取到json数据了,

在主类中MainActivity实现了json数据的解析(此json的格式非常简单,通过JSonObject直接就能解析)

以下是MainActivity的代码:

  1 package com.oysd.tuling;
  2 
  3 import java.text.SimpleDateFormat;
  4 import java.util.ArrayList;
  5 import java.util.Date;
  6 import java.util.List;
  7 
  8 import org.json.JSONException;
  9 import org.json.JSONObject;
 10 
 11 import android.app.Activity;
 12 import android.os.Bundle;
 13 import android.util.Log;
 14 import android.view.Menu;
 15 import android.view.MenuItem;
 16 import android.view.View;
 17 import android.view.View.OnClickListener;
 18 import android.widget.Button;
 19 import android.widget.EditText;
 20 import android.widget.ListView;
 21 
 22 public class MainActivity extends Activity implements HttpGetDataListener, OnClickListener{
 23 
 24     private static final String URL = "http://www.tuling123.com/openapi/api?";
 25     private static final String KEY = "ae3ecf47d74a8904cc7e527eece961e6";
 26     private static final String TAG = "TuLingMain";
 27     //String info = "深圳今天天气";
 28     private HttpData httpData;
 29     private List<ListData> lists;
 30     private ListView lv;
 31     private EditText sendText;
 32     private Button btnSend;
 33     private TextAdapter adapter;
 34     private String [] welcome_array;
 35     private String content_str;
 36     private double currentTime,oldTime = 0;
 37     
 38     
 39     @Override
 40     protected void onCreate(Bundle savedInstanceState) {
 41         super.onCreate(savedInstanceState);
 42         setContentView(R.layout.activity_main);
 43         initView();
 44         //String url = getUrl(info);
 45     }
 46     
 47     private void initView(){
 48         //Log.d(TAG,getTime());
 49         lv = (ListView) findViewById(R.id.lv);
 50         sendText = (EditText) findViewById(R.id.sendText);
 51         btnSend = (Button) findViewById(R.id.btnSend);
 52         lists = new ArrayList<ListData>();
 53         btnSend.setOnClickListener(this);
 54         adapter = new TextAdapter(lists, this);//承接上下文
 55         lv.setAdapter(adapter);
 56         ListData listData;
 57         listData = new ListData(getRondomWelcomeTips(), ListData.REVEIVER,getTime());
 58         lists.add(listData);
 59     }
 60     
 61     private String getUrl(String msg){
 62         String str = URL + "key=" + KEY + "&info=" + msg;
 63         return str;
 64     }
 65 
 66     private String getRondomWelcomeTips(){
 67         String welcome_tip = null;
 68         welcome_array = this.getResources().getStringArray(R.array.welcome_tips);
 69         int index = (int) (Math.random()*(welcome_array.length - 1));
 70         welcome_tip = welcome_array[index];
 71         return welcome_tip;
 72     }
 73     @Override
 74     public void getDataUrl(String data) {
 75         // TODO Auto-generated method stub
 76         parseText(data);
 77     }
 78     
 79     private void parseText(String str){
 80         
 81         try {
 82             JSONObject jb = new JSONObject(str);
 83             ListData listData;
 84             listData = new ListData(jb.getString("text"),ListData.REVEIVER,getTime());
 85             lists.add(listData);    
 86             adapter.notifyDataSetChanged();//重新适配
 87             
 88         } catch (JSONException e) {
 89             // TODO Auto-generated catch block
 90             e.printStackTrace();
 91         }
 92         
 93     }
 94 
 95     @Override
 96     public void onClick(View arg0) { 
 97         //getTime();
 98         content_str = sendText.getText().toString();
 99         sendText.setText("");//发送之后,将输入框清空
100         //点击的时候需要添加重新适配的代码
101         String doTrim = content_str.replace(" ", "");//处理空格的问题
102         String doEnter = doTrim.replace("
", "");//处理回车的问题
103         ListData listData;
104         listData = new ListData(content_str, ListData.SEND,getTime());
105         lists.add(listData);
106         if(lists.size() > 30){
107             for(int i = 0 ;i < lists.size() -20 ; i++){
108                 lists.remove(i);
109             }
110         }
111         adapter.notifyDataSetChanged( );//不要忘记刷新
112         
113         httpData = (HttpData) new HttpData(getUrl(content_str), this).execute();
114         
115     }
116     
117     private String getTime(){
118         currentTime = System.currentTimeMillis();
119         SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
120         Date curDate = new Date();
121         String str = format.format(curDate);
122         int sjc = (int) (currentTime - oldTime);
123         Log.d(TAG, "" + sjc);
124         
125         if((currentTime - oldTime) >= 5*1000*60){
126             oldTime = currentTime;
127             return str;
128         }else{
129             return "";
130         }
131     }
132 }
View Code

其中有很多ListView,我们需要自己定义个Adapter,
新建一个TextAdapter 扩展至BaseAdapter:

 1 package com.oysd.tuling;
 2 
 3 import java.util.List;
 4 
 5 import android.content.Context;
 6 import android.view.LayoutInflater;
 7 import android.view.View;
 8 import android.view.ViewGroup;
 9 import android.widget.BaseAdapter;
10 import android.widget.RelativeLayout;
11 import android.widget.TextView;
12 
13 public class TextAdapter extends BaseAdapter {
14 
15     private List<ListData> lists;
16     private Context mContext;
17     private RelativeLayout layout;
18     public TextAdapter(List<ListData> lists,Context context){
19         this.lists = lists;
20         this.mContext = context;
21     }
22     @Override
23     public int getCount() {
24         return lists.size();
25     }
26 
27     @Override
28     public Object getItem(int position) {
29         return lists.get(position);
30     }
31 
32     @Override
33     public long getItemId(int position) {
34         return position;
35     }
36 
37     @Override
38     public View getView(int position, View convertView, ViewGroup parent) {
39         
40         LayoutInflater inflater = LayoutInflater.from(mContext);
41         
42         if(lists.get(position).getFlag() == ListData.REVEIVER){
43             layout = (RelativeLayout) inflater.inflate(R.layout.leftitem, null);
44             
45         }
46         
47         if(lists.get(position).getFlag() == ListData.SEND){
48             layout = (RelativeLayout) inflater.inflate(R.layout.rightitem, null);
49         }
50         TextView tv = (TextView) layout.findViewById(R.id.tv);
51         tv.setText(lists.get(position).getContent());
52         TextView time = (TextView) layout.findViewById(R.id.time);
53         time.setText(lists.get(position).getTime());
54         return layout;
55     }
56 
57 }
View Code

其中需要涉及到数据的封装,以下是我的封装类:

 1 package com.oysd.tuling;
 2 
 3 public class ListData {
 4     
 5     public static final int SEND = 1;
 6     public static final int REVEIVER = 2;
 7     private String content;
 8     private String time;
 9     private int flag;
10     
11     public ListData(String content,int flag,String time){
12         setContent(content);
13         setFlag(flag);
14         setTime(time);
15     }
16 
17     public String getContent() {
18         return content;
19     }
20 
21     public void setContent(String content) {
22         this.content = content;
23     }
24 
25     public int getFlag() {
26         return flag;
27     }
28 
29     public void setFlag(int flag) {
30         this.flag = flag;
31     }
32 
33     public String getTime() {
34         return time;
35     }
36 
37     public void setTime(String time) {
38         this.time = time;
39     }
40     
41 
42 }
View Code

功能比较简单,以上涉及到的布局文件如下:

首先是主界面的布局文件:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical"
 6     >
 7     
 8     <ListView 
 9         android:layout_width="fill_parent"
10         android:layout_height="0dp"
11         android:layout_weight="1"
12         android:transcriptMode="alwaysScroll"
13         android:id="@+id/lv"
14         android:divider="@null"
15         android:listSelector="@android:color/transparent">
16     </ListView>
17     
18     <LinearLayout 
19         android:layout_width="fill_parent"
20         android:layout_height="wrap_content"
21         android:orientation="horizontal"
22         android:focusable="true" 
23         android:focusableInTouchMode="true">
24         
25         <EditText 
26             android:id="@+id/sendText"
27             android:layout_width="0dp"
28             android:layout_weight="1"
29             android:layout_height="wrap_content"/>
30         
31         <Button 
32             android:id="@+id/btnSend"
33             android:layout_width="wrap_content"
34             android:layout_height="wrap_content"
35             android:text="@string/send"
36             />
37     </LinearLayout>
38 
39 </LinearLayout>
View Code

然后是每一个单独的ListView的布局,就是图灵机器人发送时的显示,以及我们自己发送时的显示,分左右两边

以下是leftitem布局:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent" >
 5     
 6     
 7     <TextView 
 8         android:id="@+id/time"
 9         android:layout_width="fill_parent"
10         android:layout_height="wrap_content"
11         android:gravity="center_horizontal"
12         />
13     <ImageView 
14         android:layout_below="@id/time"
15         android:id="@+id/iv"
16         android:layout_width="70dp"
17         android:layout_height="70dp"
18         android:padding="10dp"
19         android:src="@drawable/rabot2"/>
20 
21     <TextView
22         android:layout_below="@id/time"
23         android:id="@+id/tv"
24         android:layout_marginRight="60dp"
25         android:layout_width="wrap_content"
26         android:layout_height="wrap_content"
27         android:layout_alignBottom="@+id/iv"
28         android:layout_toRightOf="@+id/iv"
29         android:background="@drawable/chatfrom_bg_normal"
30         android:gravity="left" />
31 
32 </RelativeLayout>
View Code

然后是rightitem布局:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent" >
 5     
 6     
 7     <TextView 
 8         android:id="@+id/time"
 9         android:layout_width="fill_parent"
10         android:layout_height="wrap_content"
11         android:gravity="center_horizontal"
12         />
13     
14     <ImageView 
15         android:layout_below="@id/time"
16         android:layout_alignParentRight="true"
17         android:id="@+id/iv"
18         android:layout_width="70dp"
19         android:layout_height="70dp"
20         android:padding="10dp"
21         android:src="@drawable/rabot1"/>
22 
23     <TextView
24         android:layout_below="@id/time"
25         android:id="@+id/tv"
26         android:layout_marginLeft="60dp"
27         android:layout_width="wrap_content"
28         android:layout_height="wrap_content"
29         android:layout_alignBottom="@+id/iv"
30         android:layout_toLeftOf="@+id/iv"
31         android:background="@drawable/chatto_bg_normal"
32         android:gravity="left" />
33 
34 </RelativeLayout>
View Code

到这里,智能聊天机器人的小应用开发完成,如果需要下载整个项目的,请点这里

原文地址:https://www.cnblogs.com/ouyangduoduo/p/4626992.html