Android聊天机器人

今天我们做个小项目,就是Android自动聊天机器人的开发。需要注意的点有:.图灵机器人API的解读和ListView多种item的实现

思考:
1.在ListView的每一项item中要放的数据是什么?
2.怎么把用于返回数据解析类的对象放在item的显示对象中。
3.提醒adapter有新数据了。

以下就是具体的代码实现:简单介绍一下各个函数的作用:

①MainActivity:在主线程中要实现发送按钮的监听事件,另外要创建一个异步任务实现网络数据的解析

②ChatMessageAdapter:继承于适配器BaseAdapter的类,用于向ListView中填充数据

③ChatMessage:定义ListView中要填充的内容

④Result类:因为该解析数据中没有第一级标题,所以就自定义Result类,其变量于Json解析出的变量保持一致,即是code和text

⑤HttpUtils:工具类,用于网络数据的解析

一、MainActivity

package org.mobiletrain.robot;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.mobiletrain.robot.bean.ChatMessage;
import org.mobiletrain.robot.bean.ChatMessage.Type;
import org.mobiletrain.robot.http.HttpUtils;

import android.app.Activity;
import android.text.TextUtils;
import android.view.View;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;


public class MainActivity extends Activity implements View.OnClickListener{

	private ListView listView;
	private EditText mInputText;
	private Button mSendButton;
	private ChatMessageAdapter adapter;
	private List<ChatMessage>mDatas;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);
		listView = (ListView)this.findViewById(R.id.id_listview_msgs);
		mInputText = (EditText)this.findViewById(R.id.id_input_msg);
		mSendButton = (Button)this.findViewById(R.id.id_send_msg);
		initDate();
		mSendButton.setOnClickListener(this);
		
	}
	
	/**
	 * 初始化ListView的第一行
	 */
	private void initDate() {
		mDatas = new ArrayList<ChatMessage>();
		ChatMessage chat = new ChatMessage("您好,我是蛋蛋,很高兴为您服务!!",new Date(),Type.INCOMING);
		mDatas.add(chat);
		adapter = new ChatMessageAdapter(this, mDatas);
		listView.setAdapter(adapter);
	}
	
	/**
	 * 设置按钮点击事件
	 *@Override
	 */
	public void onClick(View v) {
		//1.点击之后获取edittext的值,判读一下是否为空,如果是空的,就提示用户。
		String msg = mInputText.getText().toString();
		if (TextUtils.isEmpty(msg)) {
			Toast.makeText(MainActivity.this, "输入数据不能为空", Toast.LENGTH_SHORT).show();
		}
		ChatMessage toMessage = new ChatMessage();
		toMessage.setDate(new Date());
		toMessage.setMessage(msg);
		toMessage.setType(Type.OUTCOMING);
		mDatas.add(toMessage);
		//提醒适配器更新数据
		adapter.notifyDataSetChanged();
		mInputText.setText("");
		new ChatMessageTask().execute(msg);
		
	}
	/**
	 * 这是解析出来的数据格式
	 * {
	 * code : 123
	 * text : 好开心呀,有吃成长快乐了。。。
	 * }
	 * 定义异步任务实现数据的解析
	 * 
	 */
	class ChatMessageTask extends AsyncTask<String, Void, ChatMessage>{

		@Override
		protected ChatMessage doInBackground(String... params) {
			ChatMessage chat = HttpUtils.sendMessage(params[0]);
			return chat;
		}
		
		@Override
		protected void onPostExecute(ChatMessage result) {
			super.onPostExecute(result);
			mDatas.add(result);
			//提醒适配器更新数据
			adapter.notifyDataSetChanged();
		}
		
	}
	

}
二、ChatMessageAdapter适配器

package org.mobiletrain.robot;

import java.text.SimpleDateFormat;
import java.util.List;

import org.mobiletrain.robot.bean.ChatMessage;
import org.mobiletrain.robot.bean.ChatMessage.Type;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

/**
 * 定义ChatMessageAdapter适配器继承BaseAdapter
 * @author Administrator
 *
 */
public class ChatMessageAdapter extends BaseAdapter{

	private List<ChatMessage>mDatas;
	private LayoutInflater mInflater;
	
	public ChatMessageAdapter(Context context,List<ChatMessage>mDatas){
		this.mInflater = LayoutInflater.from(context);
		this.mDatas = mDatas;
		
	}
	@Override
	public int getCount() {

		return mDatas.size();
	}

	@Override
	public Object getItem(int position) {

		return mDatas.get(position);
	}

	@Override
	public long getItemId(int position) {

		return position;
	}
	/**
	 * 协定listview中有几种类型的item
	 *@Override
	 */
	public int getViewTypeCount() {

		return 2;
	}
	
	/**
	 * 判断枚举Type的类型然后确定填充数据的布局
	 * @Override
	 */
	public int getItemViewType(int position) {
		ChatMessage chatMessage = mDatas.get(position);
		if (chatMessage.getType() == Type.OUTCOMING) {
			return 0;
		}
		return 1;
	}
	
	
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder vh;
		//如果converView为空,就去找到布局文件并填充内容
		if (convertView==null) {
			//判断Type的类型,如果为0代表用户输入,则convertView填充的数据界面为ListView的右边
			if (getItemViewType(position)==0) {
				convertView = mInflater.inflate(R.layout.item_to_msg, null);
				vh = new ViewHolder();
				vh.tv_date = (TextView)convertView.findViewById(R.id.id_to_msg_date);
				vh.tv_message=(TextView)convertView.findViewById(R.id.id_to_msg_info);
			}else {
				convertView = mInflater.inflate(R.layout.item_from_msg, null);
				vh = new ViewHolder();
				vh.tv_date = (TextView)convertView.findViewById(R.id.id_form_msg_date);
				vh.tv_message=(TextView)convertView.findViewById(R.id.id_from_msg_info);
			}
			convertView.setTag(vh);
		}else{
			vh = (ViewHolder)convertView.getTag();
		}
		//向ListView中填充数据
		ChatMessage data = mDatas.get(position);
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		vh.tv_date.setText(df.format(data.getDate()));
		vh.tv_message.setText(data.getMessage());
		
		
		return convertView;
	}
	
	/**
	 *定义ViewHolder实现ListView的优化
	 * @author Administrator
	 *
	 */
	class ViewHolder{
		
		TextView tv_date;
		TextView tv_message;
	}
	
}
三、ChatMessage类

package org.mobiletrain.robot.bean;

import java.util.Date;
/**
 * 定义获取输入的内容的类
 * @author Administrator
 *
 */
public class ChatMessage {

	private String message;
	private String name;
	private Date date;
	private Type type;
	
	
	public void setType(Type type) {
		this.type = type;
	}
	
	public Type getType() {
		return type;
	}
	//枚举:是一种新型的变量,他可以控制设定的内容
	public enum Type{
		OUTCOMING,INCOMING
	}
	
	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	public ChatMessage(String message, Date date, Type type) {
		super();
		this.message = message;
		this.date = date;
		this.type = type;
	}
	
	public ChatMessage() {
		// TODO Auto-generated constructor stub
	}
	
	
}

四、与解析内容相匹配的自定义Result类

package org.mobiletrain.robot.bean;

/**
 * 解析结果的格式
 * @author Administrator
 *
 */
public class Result {

	private String code;
	private String text;
	
	public String getCode() {
		return code;
	}
	public String getText() {
		return text;
	}
	public void setCode(String code) {
		this.code = code;
	}
	public void setText(String text) {
		this.text = text;
	}
	
}

五、解析工具类:HttpUtils

package org.mobiletrain.robot.http;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.mobiletrain.robot.bean.ChatMessage;
import org.mobiletrain.robot.bean.ChatMessage.Type;
import org.mobiletrain.robot.bean.Result;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;

import android.R.string;

/**
 * 联网工具类,用于连接网络,取得数据
 *
 */

public class HttpUtils {
	// 图灵机器人使用api的公网地址
	public static final String URL = "http://www.tuling123.com/openapi/api";
	// 申请的apiKey
	public static final String API_KEY = "be12dd3c0bac3654e78aa69e4b36a6dd";
	
	/**
	 * 通过HttpURLConnection解析Json数据,返回结果是一个字符串
	 * @param url
	 * @return
	 */
	public static String getJsonContent(String url) {
		String result = "";
		URL url2;
		InputStream is;
		InputStreamReader isr;
		BufferedReader br;
		try {
			url2 = new URL(url);
			HttpURLConnection connection = (HttpURLConnection) url2
					.openConnection();
			is = connection.getInputStream();
			isr = new InputStreamReader(is, "utf-8");
			String line = "";
			br = new BufferedReader(isr);
			while ((line = br.readLine()) != null) {
				result += line;
			}
			try {
				br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 通过HttpClient解析Json数据,返回结果是一个字符串
	 * @param url
	 * @return
	 */
	public static String getJsonContent2(String url) {
		String result = "";
		HttpClient httpClient = new DefaultHttpClient();
		HttpGet httpGet = new HttpGet(url);
		HttpResponse response = null;
		try {
			response = httpClient.execute(httpGet);
			if (response.getStatusLine().getStatusCode() == 200) {
				result = EntityUtils.toString(response.getEntity(), "utf-8");
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 解析Json数据,返回结果是一个byte[]数组,一般用于解析网络图片
	 * @param url
	 * @return
	 */
	public static byte[] getByteContent2(String url) {
		byte[] data = null;
		HttpClient httpClient = new DefaultHttpClient();
		HttpGet httpGet = new HttpGet(url);
		HttpResponse response = null;
		try {
			response = httpClient.execute(httpGet);
			if (response.getStatusLine().getStatusCode() == 200) {
				data = EntityUtils.toByteArray(response.getEntity());
			}
			return data;
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return data;

	}
	/**
	 * 通过HttpURLConnection解析Json数据,返回结果也是一个byte[]类型的数组
	 * @param url
	 * @return
	 */
	public static byte[] getByteContent(String url) {
		try {
			URL url2 = new URL(url);
			HttpURLConnection httpConn = (HttpURLConnection) url2
					.openConnection();
			httpConn.setDoInput(true); // 允许输入内容
			httpConn.setDoOutput(false);
			httpConn.connect();
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			if (httpConn.getResponseCode() == 200) {
				BufferedInputStream bis = new BufferedInputStream(
						httpConn.getInputStream());
				byte[] buffer = new byte[8 * 1024];
				int c = 0;
				while ((c = bis.read(buffer)) != -1) {
					baos.write(buffer, 0, c);
					baos.flush();
				}
				byte[] data = baos.toByteArray();
				return data;
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 拼接接口,其中参数为用户输入传来的内容
	 */
	public static String setParams(String msg){
		String url = "";
		try {
			 url = URL +"?key="+API_KEY+"&info="+URLEncoder.encode(msg, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return url;
	}
	
	/**
	 * 解析Json数据,返回类型是一个ChatMessage对象
	 * @param msg
	 * @return
	 */
	public static ChatMessage sendMessage(String msg){
		ChatMessage chatMessage = new ChatMessage();
		String jsonRes = getJsonContent(setParams(msg));
		Gson gson = new Gson();
		Result result = null;
		try {
			result = gson.fromJson(jsonRes, Result.class);
			chatMessage.setMessage(result.getText());
		} catch (JsonSyntaxException e) {
			chatMessage.setMessage("服务器繁忙,请稍后再试");
		}
		chatMessage.setDate(new Date());
		chatMessage.setType(Type.INCOMING);
		return chatMessage;
	}
}
下面就是实现的效果图:

初始界面:



聊天界面:




  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值