第一篇:一个简单的聊天机器人

昨天写了一个简单的聊天机器人,只是完成了文字类的对话,关于查询的还么有做,今天整理了一下发上来,我不是一个大牛,只是希望给学习者一点小小的能量。

1.以下是机器人部分的布局,我用了RelativeLayout布局,开始写的是LinearLayOut,由于编译器的问题出现了错位,我费了好大劲去看我的代码没有错,人不能吊死在一棵树上,我换种方式就OK了。用户部分的布局与这个基本类似,我就不发了。

<span style="font-size:14px;"><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
      <TextView
        android:id="@+id/date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="3dp"
        android:background="#ccc"   
        android:text="2015-09-17 12:23:12" />
      <RelativeLayout 
          android:id="@+id/relayout"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_below="@+id/date">
       <ImageView 
		        android:id="@+id/egg"
		        android:layout_width="50dp"
		        android:layout_height="50dp"	
		        android:src="@drawable/head3"/>   
		<TextView 
		        android:id="@+id/eggname"
		        android:layout_width="wrap_content"
		        android:layout_height="wrap_content"
		        android:textSize="17sp"
		        android:layout_below="@+id/egg"
		        android:text="小友子"/>
     </RelativeLayout>

      <TextView
          android:id="@+id/eggtalk"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_toRightOf="@+id/relayout"
          android:layout_below="@+id/date"
          android:background="@drawable/chatfrom_bg_normal"
          android:text="您好,小友为您服务!!!" />

</RelativeLayout>
</span>
2.MainActivity的布局,也很简单,主要就是一个ListView 和输入框和发送按钮
<span style="font-size:14px;"><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
	android:background="@drawable/ic_03"
    tools:context=".MainActivity" >


    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="小友"
        android:gravity="center_horizontal"
        android:textSize="25sp"
        android:textColor="#FFFFFF"
        android:background="@drawable/title_bar" />

    <ListView
        android:id="@+id/chat_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/bottom"
        android:layout_below="@+id/title"
         >
        
    </ListView>

    <LinearLayout
        android:id="@+id/bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="@drawable/bottom_bar"
        android:orientation="horizontal"        
        android:padding="10dp" >

        <EditText
            android:id="@+id/input_et"
            android:layout_width="230dp"
            android:layout_height="match_parent"
            android:background="@drawable/send_btn_normal"
            android:text="你好"
            android:textSize="15sp" />

        <Button
            android:id="@+id/send"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="发送"
            android:layout_marginLeft="5dp"
            android:textSize="20sp" />
    </LinearLayout>

</RelativeLayout></span>
3.下面是一个聊天信息类,包含谁说的话,说话内容,时间。注意枚举类型的定义和date类型的转换。
<span style="font-size:14px;">public class ChatMessage {
	private String message;
	private String name;
	private Date date;
	private String datestr;
	public String getDatestr() {
		return datestr;
	}
	public void setDatestr(String datestr) {
		this.datestr = datestr;
	}
	public enum Type{   //定义一个枚举,判断是谁说的话
		OUTCOMING,INCOMING    //OUTCOMING代表我,INCOMING代表机器人
	}
	private Type type;  //type只有以上两种取值
	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) {       //date.setDate(New Data())可以放入输入时间的固定格式字符串
		this.date = date;
		DateFormat dFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		this.datestr=dFormat.format(date);
	}
	public Type getType() {
		return type;
	}
	public void setType(Type type) {
		this.type = type;
	}
	public ChatMessage(){
		
	}
	public ChatMessage(Type type,String msg){   //构造函数
		super();
		this.type=type;
		this.message=msg;
		setDate(new Date());
	}
}
</span>

4.Result类主要是机器人返回参数code和text,这是图灵机器人规定的格式,是文字类必有有的,当然如果要添加别的内容,参数也要增加。

<span style="font-size:14px;">/*
 * 机器人返回的内容
 * 文字类的返回参数(Json格式)是状态码code和 文字内容  text
 */
public class Result {
	private int code;
	private String text;
	public int getCode() {
		return code;
	}
	public void setCode(int code) {
		this.code = code;
	}
	public String getText() {
		return text;
	}
	public void setText(String text) {
		this.text = text;
	}
	
}
</span>
5.连接网络的代码

<span style="font-size:14px;">public class HttpUtils {
	private static String API_KEY="6726dcae3e70bad48df7834dd722c200";
	private static String URL="http://www.tuling123.com/openapi/api";
	/*
	 * 得到机器人返回的消息
	 */
	public static ChatMessage sendMsg(String msg){
		ChatMessage message = new ChatMessage();
		String url=setParams(msg);
		String res =doGet(url);
		Gson gson=new Gson();
		Result result = gson.fromJson(res,Result.class);   //gson解析
		if (result.getCode()!=100000||result.getText()==null||result.getText().trim().equals("")){
			message.setMessage("哎。。我的功能也是有限的啊");
		}else {
			message.setMessage(result.getText());
		}
		message.setType(Type.INCOMING);
		message.setDate(new Date());
		return message;
			
		
	}
	/*
	 * 拼接URL
	 */
	private static String setParams(String msg){
		try {
			msg=URLEncoder.encode(msg,"UTF-8");  //用此方法对String类型的msg进行转码成utf—8
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();<pre name="code" class="java">}
		return URL+"?key="+API_KEY+"&info="+msg;   //URL格式
	}
	/*
	 * get请求,获得返回数据
	 */
	private static String doGet(String urlStr){
		String result = "";
		URL url2;
		InputStream is;
		InputStreamReader isr;
		BufferedReader br;
		try {
			url2 = new URL(urlStr);
			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();
			System.out.println("网络异常");
		} catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}
}

 
</pre><span style="font-size:14px"><br />6.自定义一个Adapter类<br /></span><p></p><pre>
<span style="font-family: Arial, Helvetica, sans-serif;">	//LayoutInflater是用来找layout下的xml布局文件,并且实例化;</span>
	//对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入;
	private LayoutInflater mInflater;
	private Context context;
	private List<ChatMessage> datas;
	public MessageAdapter(Context context,List<ChatMessage> datas){
		this.context=context;
		this.datas=datas;
		mInflater=LayoutInflater.from(context);
	}

	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return datas.size();
	}

	@Override
	public Object getItem(int arg0) {
		// TODO Auto-generated method stub
		return datas.get(arg0);
	}

	@Override
	public long getItemId(int arg0) {
		// TODO Auto-generated method stub
		return arg0;
	}
	@Override
	public int getItemViewType(int position) {
		ChatMessage msg=datas.get(position);
		return msg.getType()==Type.INCOMING?1:0;  //机器人输出的type为1,人输出的为0
	}
	//协定ListView中有几种类型的item
	@Override
	public int getViewTypeCount() {
		return 2;
	}

	@Override
	public View getView(int position, View converView, ViewGroup parent) {
		ChatMessage message = datas.get(position);
	    ViewHolder vh = null;
		if (converView==null) {
			if (message.getType()==Type.OUTCOMING) {
				converView = mInflater.inflate(R.layout.me_talk,null);
				vh=new ViewHolder();
				vh.date=(TextView)converView.findViewById(R.id.date);
				vh.content=(TextView)converView.findViewById(R.id.metalk);
				converView.setTag(vh);
				
			}else if (message.getType()==Type.INCOMING) {
				converView=mInflater.inflate(R.layout.agg_talk, null);
				vh=new ViewHolder();
				vh.date=(TextView)converView.findViewById(R.id.date);
				vh.content=(TextView)converView.findViewById(R.id.eggtalk);
				converView.setTag(vh);
			}
			
		}else {
			vh=(ViewHolder)converView.getTag();
		}
		vh.content.setText(message.getMessage());
		vh.date.setText(message.getDatestr());
		return converView;
	}
	class ViewHolder{
		TextView date;
		TextView content;
	}

}
</span>
7.Mainactivity 

<span style="font-size:14px;">public class MainActivity extends Activity {
	private ListView message;
	private EditText input_message;
	private Button send;
	private String msg;
	private List<ChatMessage> datas=new ArrayList<ChatMessage>(); //存储聊天信息
	private MessageAdapter adapter;
	private MyTask task;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		requestWindowFeature(Window.FEATURE_NO_TITLE); //隐藏窗体标题栏,全屏显示
		message = (ListView)findViewById(R.id.chat_content);
		input_message=(EditText)findViewById(R.id.input_et);
		send=(Button)findViewById(R.id.send);
		datas.add(new ChatMessage(Type.INCOMING,"祝小友子生日快乐"));  //设置机器人输出的第一句话
		send.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
			    msg=input_message.getText().toString();  //获取输入内容
				if (TextUtils.isEmpty(msg)) {   //TextUtils类对字符串进行处理,此处判断输入是否为空
					Toast.makeText(MainActivity.this, "你还没输入信息", Toast.LENGTH_LONG).show();
					return;
				}
				ChatMessage to=new ChatMessage(Type.OUTCOMING,msg);  
				to.setDate(new Date());
				datas.add(to);				
				adapter.notifyDataSetChanged();   //更新数据
				message.setSelection(datas.size()-1);  //将列表移动到指定的Position处。
				input_message.setText("");
				task=new MyTask();
				task.execute(msg);

			}
		});
		
		adapter=new MessageAdapter(MainActivity.this, datas);
		message.setAdapter(adapter);
		
	}
	
	//返回一个CharMessage对象
	class MyTask extends AsyncTask<String, Void, ChatMessage>{

		@Override
		protected ChatMessage doInBackground(String... arg0) {
			ChatMessage from = null;
			try {
				from=HttpUtils.sendMsg(arg0[0]);			
			} catch (Exception e) {
				from=new ChatMessage(Type.INCOMING,"哎呀,我的服务器挂啦!");
			}
			
			return from;
		}
		@Override
		protected void onPostExecute(ChatMessage result) {
			super.onPostExecute(result);
			datas.add(result);
			adapter.notifyDataSetChanged();
			message.setSelection(datas.size()-1);
			
			
		}
	}
	


}
</span>
8.最后,不要忘了连网操作!





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值