• 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

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

  • 相关阅读:
    Global.asax的Application_BeginRequest实现url重写无后缀的代码
    Windows 2008驱动安装失败的原因及解决方法
    解决win8.1电脑无法安装手机驱动问题
    适用于Win8的Office2003_SP3精简版集成各类补丁+兼容包
    CSS 文本缩进,行间距
    自动换行后缩进怎么做(CSS)?(可用于 Li y 元素的排版)
    ApkTool反编译和重新打包
    sql server 2005 32位+64位、企业版+标准版、CD+DVD 下载地址大全
    【Lua】Lua中__index与元表(转)
    【VS2012】项目文件夹管理
  • 原文地址:https://www.cnblogs.com/ouyangduoduo/p/4626992.html
Copyright © 2020-2023  润新知