Android案例练习(一)——智能机器人
案例来自慕课网 ,采用Eclipse编写。
一、本案例使用的知识:
1.第三方API图灵机器人的API。
2.ListView多种Item布局时的处理,实现聊天对话的界面
二、目录结构
三、编写过程:
1.编写一个工具类,实现消息的发送与接收
建立包com.example.util,在包下建立HttpUtils.java类,代码如下。
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.搭建操作环境,对工具类进行测试
建立包com.example.test,在此包下建立类TestHttpUtils.java。代码如下:
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三个布局文件,代码如下:
15 49"11 20 21 22"19 28 38 "48 57 58
1 26 7 16 21 "48 49 5025 3829 "36 37 "46 47
1 27 8 17 22 50 51 5230 34 47 48 4938 "45 46
为了更好的实现发送按钮的效果,需要在res下建立drawable文件夹,建立send_btn_bg.xml文件。代码如下:
1 23 - 5
- "6
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,OUTCOMING25 }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 ListmDatas;19 20 public ChatMessageAdapter(Context context,List mDatas){21 myInflater=LayoutInflater.from(context);22 this.mDatas=mDatas;23 }24 25 @Override26 public int getCount() {27 // TODO 自动生成的方法存根28 return mDatas.size();29 }30 31 @Override32 public Object getItem(int position) {33 // TODO 自动生成的方法存根34 return mDatas.get(position);35 }36 37 @Override38 public long getItemId(int position) {39 // TODO 自动生成的方法存根40 return position;41 }42 43 @Override44 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 @Override54 public int getViewTypeCount() {55 // TODO 自动生成的方法存根56 return 2;57 }58 59 @Override60 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) convertView72 .findViewById(R.id.id_from_msg_date);73 viewHolder.mMsgs=(TextView) convertView74 .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) convertView80 .findViewById(R.id.id_to_msg_date);81 viewHolder.mMsgs=(TextView) convertView82 .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 ListmDatas;//数据源 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 (); 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 26 " 7 10 11 16 17 20 21 25 26 2722 23 24 30 31
四、总结
项目截图:
抛出异常快捷键shift+alt+z。
引用图灵机器人的API官网 http://www.tuling123.com/。
2016-03-1720:57:38