Android案例练习(一)——智能机器人
采用Eclipse编写。
一、本案例使用的知识:
1.第三方API图灵机器人的API。
2.ListView多种Item布局时的处理,实现聊天对话的界面
二、目录结构
三、编写过程:
1.编写一个工具类,实现消息的发送与接收
1 package com.example.util;
2 /*
3 * 发送一个消息,得到一个返回的消息
4 */
5 import java.io.ByteArrayOutputStream;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.UnsupportedEncodingException;
9 import java.net.HttpURLConnection;
10 import java.net.MalformedURLException;
11 import java.net.URLEncoder;
12 import java.util.Date;
13
14 import com.example.bean.ChatMessage;
15 import com.example.bean.ChatMessage.Type;
16 import com.example.bean.Result;
17 import com.google.gson.Gson;
18
19 public class HttpUtils {
20 private static final String URL="http://www.tuling123.com/openapi/api";
21 //固定的uri,指定往哪里发送请求
22 private static final String API_KEY="ba5637dd0b34bab9322c7c61317cee5a";
23 public static String doGet(String msg){
24 String result="";
25 String url=setParams(msg);//为URL设置参数
26 InputStream is=null;
27 ByteArrayOutputStream baos=null;
28
29 try {
30 java.net.URL urlNet=new java.net.URL(url);
31 HttpURLConnection conn=(HttpURLConnection) urlNet.openConnection();
32 conn.setReadTimeout(5*1000);
33 conn.setConnectTimeout(5*1000);
34 conn.setRequestMethod("GET");//conn参数设置
35
36 is=conn.getInputStream();
37 int len=-1;
38 byte[] buf=new byte[128];//设置128字节缓冲区
39 baos=new ByteArrayOutputStream();
40
41 while((len=is.read(buf)) !=-1){
42 baos.write(buf,0,len);
43 }
44 baos.flush();
45
46 result=new String(baos.toByteArray());
47 } catch (MalformedURLException e) {
48 // TODo 自动生成的 catch 块
49 e.printStackTrace();
50 } catch (IOException e) {
51 // TODO 自动生成的 catch 块
52 e.printStackTrace();
53 }finally
54 {
55 if(baos!=null){
56 try {
57 baos.close();
58 } catch (IOException e) {
59 // TODO 自动生成的 catch 块
60 e.printStackTrace();
61 }
62 }
63 if(is!=null){
64 try {
65 is.close();
66 } catch (IOException e) {
67 // TODO 自动生成的 catch 块
68 e.printStackTrace();
69 }
70 }
71
72 }
73 return result;
74 }
75 private static String setParams(String msg) {
76 // TODO 自动生成的方法存根
77 String url="";
78 try {
79 url = URL+"?key="+API_KEY+"&info="+URLEncoder.encode(msg,"UTF-8");
80 } catch (UnsupportedEncodingException e) {
81 // TODO 自动生成的 catch 块
82 e.printStackTrace();
83 }
84 return url;
85 }
86 public static ChatMessage sendMessage(String msg){
87 ChatMessage chatMessage=new ChatMessage();
88 String jsonRes=doGet(msg);
89 Gson gson=new Gson();
90 Result result=null;
91 try {
92 result = gson.fromJson(jsonRes, Result.class);
93 chatMessage.setMsg(result.getText());
94 } catch (Exception e) {
95 // TODO: handle exception
96 chatMessage.setMsg("服务器繁忙,请稍后重试");
97 }
98 chatMessage.setDate(new Date());
99 chatMessage.setType(Type.INCOMING);
100 return chatMessage;
101 }
102
103 }
2.搭建操作环境,对工具类进行测试
1 package com.example.test;
2
3 import com.example.util.HttpUtils;
4
5 import android.test.AndroidTestCase;
6 import android.util.Log;
7
8
9 public class TestHttpUtils extends AndroidTestCase {
10 public void testSendInfo(){
11 String res=HttpUtils.doGet("给我讲个笑话");
12 Log.e("TAG",res);
13 String res1=HttpUtils.doGet("给我讲个鬼故事");
14 Log.e("TAG",res1);
15 String res2=HttpUtils.doGet("你好");
16 Log.e("TAG",res2);
17 String res3=HttpUtils.doGet("你真美");
18 Log.e("TAG",res3);
19 }
20 }
3.编写聊天界面
在drawable-hdpi文件下加入所需的图片,res/layout下建立activity_main.xml,item_from_msg.xml,item_to_msg.xml三个布局文件,代码如下:
1 <RelativeLayout 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 <RelativeLayout
6 android:id="@+id/id_ly_top"
7 android:layout_width="fill_parent"
8 android:layout_height="45dp"
9 android:layout_alignParentTop="true"
10 android:background="@drawable/title_bar">"
11 <TextView
12 android:layout_width="wrap_content"
13 android:layout_height="wrap_content"
14 android:layout_centerInParent="true"
15 android:textColor="#ffffff"
16 android:textSize="22sp"
17 android:text="小慕"
18 />"
19 </RelativeLayout>
20
21
22 <RelativeLayout
23 android:id="@+id/id_ly_bottom"
24 android:layout_width="fill_parent"
25 android:layout_height="55dp"
26 android:layout_alignParentBottom="true"
27 android:background="@drawable/bottom_bar">
28 <Button
29 android:id="@+id/id_send_msg"
30 android:layout_width="60dp"
31 android:layout_height="40dp"
32 android:layout_centerInParent="true"
33 android:layout_alignParentRight="true"
34 android:background="@drawable/send_btn_bg"
35 android:text="发送"
36
37 />
38 <EditText
39 android:id="@+id/id_input_msg"
40 android:layout_width="fill_parent"
41 android:layout_height="40dp"
42 android:background="@drawable/login_edit_normal"
43 android:layout_marginLeft="10dp"
44 android:layout_marginRight="10dp"
45 android:layout_centerVertical="true"
46 android:textSize="18sp"
47 android:layout_toLeftOf="@id/id_send_msg"/> "
48 </RelativeLayout>
49 <ListView
50 android:id="@+id/id_listview_msgs"
51 android:layout_width="fill_parent"
52 android:layout_height="fill_parent"
53 android:layout_above="@+id/id_ly_bottom"
54 android:layout_below="@+id/id_ly_top"
55 android:divider="@null"
56 android:dividerHeight="5dp">
57 </ListView>
58 </RelativeLayout>
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="wrap_content"
5 android:orientation="vertical" >
6
7 <TextView
8 android:id="@+id/id_from_msg_date"
9 android:layout_width="wrap_content"
10 android:layout_height="wrap_content"
11 android:layout_gravity="center"
12 android:background="#bebebe"
13 android:textColor="#f5f5f5"
14 android:textSize="12sp"
15 android:text="2012-12-12 12:12:12" />
16 <LinearLayout
17 android:layout_width="wrap_content"
18 android:layout_height="wrap_content"
19 android:orientation="horizontal"
20 >
21 <LinearLayout
22 android:layout_width="fill_parent"
23 android:layout_height="wrap_content"
24 android:orientation="vertical">
25 <ImageView
26 android:layout_width="49dp"
27 android:layout_height="49dp"
28 android:src="@drawable/icon"/>
29 <TextView
30 android:layout_width="wrap_content"
31 android:layout_height="wrap_content"
32 android:textSize="18sp"
33 android:layout_gravity="center"
34 android:text="小慕"
35 />"
36
37 </LinearLayout>
38 <TextView
39 android:id="@+id/id_from_msg_info"
40 android:layout_width="wrap_content"
41 android:layout_height="wrap_content"
42 android:text="你好!"
43 android:textSize="16sp"
44 android:gravity="center_vertical"
45 android:background="@drawable/chatfrom_bg_normal"/><!-- 垂直居中 -->"
46
47 </LinearLayout>"
48
49
50 </LinearLayout>
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="wrap_content"
5 android:gravity="right"
6 android:orientation="vertical" >
7
8 <TextView
9 android:id="@+id/id_to_msg_date"
10 android:layout_width="wrap_content"
11 android:layout_height="wrap_content"
12 android:layout_gravity="center"
13 android:background="#bebebe"
14 android:textColor="#f5f5f5"
15 android:textSize="12sp"
16 android:text="2012-12-12 12:12:12" />
17 <LinearLayout
18 android:layout_width="wrap_content"
19 android:layout_height="wrap_content"
20 android:orientation="horizontal"
21 >
22 <TextView
23 android:id="@+id/id_to_msg_info"
24 android:layout_width="wrap_content"
25 android:layout_height="wrap_content"
26 android:text="你好!"
27 android:textSize="16sp"
28 android:gravity="center_vertical"
29 android:background="@drawable/chatto_bg_normal"/><!-- 垂直居中 -->
30 <LinearLayout
31 android:layout_width="fill_parent"
32 android:layout_height="wrap_content"
33 android:orientation="vertical">
34 <ImageView
35 android:layout_width="49dp"
36 android:layout_height="49dp"
37 android:src="@drawable/me"/>
38 <TextView
39 android:layout_width="wrap_content"
40 android:layout_height="wrap_content"
41 android:textSize="18sp"
42 android:layout_gravity="center"
43 android:text="Saraad"
44 />"
45
46 </LinearLayout>
47
48
49 </LinearLayout>
50
51
52 </LinearLayout>
为了更好的实现发送按钮的效果,需要在res下建立drawable文件夹,建立send_btn_bg.xml文件。代码如下:
1 <?xml version="1.0" encoding="utf-8"?>
2 <selector xmlns:android="http://schemas.android.com/apk/res/android">
3 <item android:state_pressed="true"
4 android:drawable="@drawable/send_btn_pressed"></item>
5 <item android:drawable="@drawable/send_btn_normal"></item>"
6 </selector>
4.添加数据
建立com.example.bean包,建立ChatMessage.java,Result.java文件,代码如下:
1 package com.example.bean;
2
3 import java.util.Date;
4
5 public class ChatMessage {
6 private String name;
7 private String msg;
8 private Type type;
9 private Date date;
10 public ChatMessage() {
11
12 }
13
14
15 public ChatMessage(String msg, Type type, Date date) {
16 super();
17 this.msg = msg;
18 this.type = type;
19 this.date = date;
20 }
21
22
23 public enum Type{
24 INCOMING,OUTCOMING
25 }
26
27 public String getName() {
28 return name;
29 }
30
31 public void setName(String name) {
32 this.name = name;
33 }
34
35 public String getMsg() {
36 return msg;
37 }
38
39 public void setMsg(String msg) {
40 this.msg = msg;
41 }
42
43 public Type getType() {
44 return type;
45 }
46
47 public void setType(Type type) {
48 this.type = type;
49 }
50
51 public Date getDate() {
52 return date;
53 }
54
55 public void setDate(Date date) {
56 this.date = date;
57 }
58 }
1 package com.example.bean;
2
3 public class Result {
4 private int code;
5 private String text;
6 public int getCode() {
7 return code;
8 }
9 public void setCode(int code) {
10 this.code = code;
11 }
12 public String getText() {
13 return text;
14 }
15 public void setText(String text) {
16 this.text = text;
17 }
18 }
5.实现对话
在原有的包下建立ChatMessageAdapter.java文件,MainActivity.java是原有的。代码如下:
1 package com.example.imook_mook;
2
3 import java.text.SimpleDateFormat;
4 import java.util.List;
5
6 import com.example.bean.ChatMessage;
7 import com.example.bean.ChatMessage.Type;
8
9 import android.content.Context;
10 import android.view.LayoutInflater;
11 import android.view.View;
12 import android.view.ViewGroup;
13 import android.widget.BaseAdapter;
14 import android.widget.TextView;
15
16 public class ChatMessageAdapter extends BaseAdapter {
17 private LayoutInflater myInflater;
18 private List<ChatMessage> mDatas;
19
20 public ChatMessageAdapter(Context context,List<ChatMessage> mDatas){
21 myInflater=LayoutInflater.from(context);
22 this.mDatas=mDatas;
23 }
24
25 @Override
26 public int getCount() {
27 // TODO 自动生成的方法存根
28 return mDatas.size();
29 }
30
31 @Override
32 public Object getItem(int position) {
33 // TODO 自动生成的方法存根
34 return mDatas.get(position);
35 }
36
37 @Override
38 public long getItemId(int position) {
39 // TODO 自动生成的方法存根
40 return position;
41 }
42
43 @Override
44 public int getItemViewType(int position) {
45 // TODO 自动生成的方法存根
46 ChatMessage chatMessage=mDatas.get(position);
47 if(chatMessage.getType()==Type.INCOMING){
48 return 0;
49 }
50 return 1;
51 }//接受消息为0,发送消息为1;
52
53 @Override
54 public int getViewTypeCount() {
55 // TODO 自动生成的方法存根
56 return 2;
57 }
58
59 @Override
60 public View getView(int position, View convertView, ViewGroup parent) {
61 // TODO 自动生成的方法存根
62 ChatMessage chatMessage=mDatas.get(position);
63 ViewHolder viewHolder=null;
64 if(convertView==null){
65 //通过ItemType设置不同的布局
66 if(getItemViewType(position)==0)
67 {
68 convertView=myInflater.inflate(R.layout.item_from_msg,
69 parent,false);
70 viewHolder=new ViewHolder();
71 viewHolder.mDate=(TextView) convertView
72 .findViewById(R.id.id_from_msg_date);
73 viewHolder.mMsgs=(TextView) convertView
74 .findViewById(R.id.id_from_msg_info);
75 }else{
76 convertView=myInflater.inflate(R.layout.item_to_msg,parent,
77 false);
78 viewHolder=new ViewHolder();
79 viewHolder.mDate=(TextView) convertView
80 .findViewById(R.id.id_to_msg_date);
81 viewHolder.mMsgs=(TextView) convertView
82 .findViewById(R.id.id_to_msg_info);
83 }
84 convertView.setTag(viewHolder);
85 }else{
86 viewHolder=(ViewHolder) convertView.getTag();
87 }
88 //设置数据
89 SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
90 viewHolder.mDate.setText(df.format(chatMessage.getDate()));
91 viewHolder.mMsgs.setText(chatMessage.getMsg());
92 return convertView;
93 }
94 private final class ViewHolder{
95 TextView mDate;
96 TextView mMsgs;
97 }//提升效率
98
99 }
1 package com.example.imook_mook;
2
3 import java.util.ArrayList;
4 import java.util.Date;
5 import java.util.List;
6
7 import com.example.bean.ChatMessage;
8 import com.example.bean.ChatMessage.Type;
9 import com.example.util.HttpUtils;
10
11 import android.os.Bundle;
12 import android.os.Handler;
13 import android.os.Message;
14 import android.app.Activity;
15 import android.text.TextUtils;
16 import android.view.Menu;
17 import android.view.View;
18 import android.view.View.OnClickListener;
19 import android.view.Window;
20 import android.widget.Button;
21 import android.widget.EditText;
22 import android.widget.ListView;
23 import android.widget.Toast;
24
25 public class MainActivity extends Activity {
26 private ListView mMsgs;
27 private ChatMessageAdapter mAdapter;
28 private List<ChatMessage> mDatas;//数据源
29
30 private EditText mInputMsg;
31 private Button mSendMsg;
32
33 private Handler mHandler=new Handler()
34 {
35 public void handleMessage(android.os.Message msg){
36 //等待接受子线程数据的返回
37 ChatMessage fromMessage=(ChatMessage) msg.obj;
38 mDatas.add(fromMessage);
39 mAdapter.notifyDataSetChanged();
40 }
41 };
42 @Override
43 protected void onCreate(Bundle savedInstanceState) {
44 super.onCreate(savedInstanceState);
45 requestWindowFeature(Window.FEATURE_NO_TITLE);
46 setContentView(R.layout.activity_main);
47
48 initView();
49 initDatas();
50 //初始化事假
51 initListener();
52 }
53 private void initListener() {
54 // TODO 自动生成的方法存根
55 mSendMsg.setOnClickListener(new OnClickListener(){
56
57 @Override
58 public void onClick(View v) {
59 // TODO 自动生成的方法存根
60 final String toMsg =mInputMsg.getText().toString();
61 if(TextUtils.isEmpty(toMsg))
62 {
63 Toast.makeText(MainActivity.this,"发送消息不能为空",Toast.LENGTH_SHORT).show();
64 return ;
65 }
66
67 ChatMessage toMessage=new ChatMessage();
68 toMessage.setDate(new Date());
69 toMessage.setMsg(toMsg);
70 toMessage.setType(Type.OUTCOMING);
71 mDatas.add(toMessage);
72 mAdapter.notifyDataSetChanged();//通知更新
73
74 mInputMsg.setText("");
75 new Thread(){
76 public void run(){
77 ChatMessage fromMessage=HttpUtils.sendMessage(toMsg);
78 Message m=Message.obtain();
79 m.obj=fromMessage;
80 mHandler.sendMessage(m);
81 }
82 }.start();
83
84 }
85
86 });
87 }
88 private void initDatas() {
89 // TODO 自动生成的方法存根
90 mDatas=new ArrayList<ChatMessage>();
91 mDatas.add(new ChatMessage("你好,小慕为您服务",Type.INCOMING,new Date()));
92 //mDatas.add(new ChatMessage("你好",Type.OUTCOMING,new Date()));
93 mAdapter=new ChatMessageAdapter(this,mDatas);
94 mMsgs.setAdapter(mAdapter);
95 }
96
97 private void initView() {
98 // TODO 自动生成的方法存根
99 mMsgs=(ListView) findViewById(R.id.id_listview_msgs);
100 mInputMsg=(EditText) findViewById(R.id.id_input_msg);
101 mSendMsg= (Button) findViewById(R.id.id_send_msg);
102
103 }
104
105
106 }
最后在AndroidManifest.xml文件中添加权限:
1 <?xml version="1.0" encoding="utf-8"?>
2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3 package="com.example.imook_mook"
4 android:versionCode="1"
5 android:versionName="1.0" >
6 <uses-permission android:name="android.permission.INTERNET"/>"
7 <uses-sdk
8 android:minSdkVersion="8"
9 android:targetSdkVersion="18" />
10
11 <application
12 android:allowBackup="true"
13 android:icon="@drawable/ic_launcher"
14 android:label="@string/app_name"
15 android:theme="@style/AppTheme" >
16 <uses-library android:name="android.test.runner"/>
17 <activity
18 android:name="com.example.imook_mook.MainActivity"
19 android:label="@string/app_name" >
20 <intent-filter>
21 <action android:name="android.intent.action.MAIN" />
22
23 <category android:name="android.intent.category.LAUNCHER" />
24 </intent-filter>
25 </activity>
26 </application>
27 <instrumentation android:targetPackage="com.example.imook_mook"
28 android:label="this is a test"
29 android:name="android.test.InstrumentationTestRunner">
30 </instrumentation>
31 </manifest>
四、总结
项目截图:
抛出异常快捷键shift+alt+z。
引用图灵机器人的API官网 http://www.tuling123.com/。
2016-03-1720:57:38
本性的苏醒,往往在遭遇真实之后。