最近做了一个图灵机器人,现在把具体的代码以及一些需要注意的问题给写上来!
1.首先创建一个工具类HttpUtils,代码如下:
1 package com.xiaochao.weatherinfo.utils; 2 3 import java.io.BufferedReader; 4 import java.io.ByteArrayOutputStream; 5 import java.io.DataOutputStream; 6 import java.io.IOException; 7 import java.io.InputStream; 8 import java.io.InputStreamReader; 9 import java.io.UnsupportedEncodingException; 10 import java.net.HttpURLConnection; 11 import java.net.MalformedURLException; 12 import java.net.URL; 13 import java.net.URLEncoder; 14 import java.util.Date; 15 16 import com.google.gson.Gson; 17 import com.xiaochao.weather.bean.Result; 18 import com.xiaochao.weather.bean.TalkMessage; 19 import com.xiaochao.weather.enums.Type; 20 21 /** 22 * 工具类 23 * @author Administrator 24 * 25 */ 26 public class HttpUtils { 27 28 private static final String URL = "http://www.tuling123.com/openapi/api";//图灵机器人URL 29 private static final String API_KEY = "ff01daa6197a95bc37382985589e8da6";//key,需要自己从官网上申请 30 31 /** 32 * 此方法用来服务端根据客户端发送的请求返回数据,返回的数据类型是一个TalkMessage类 33 * 34 * @param msg 35 * @return 36 */ 37 public static TalkMessage sendMessage(String msg) { 38 TalkMessage message = new TalkMessage(); 39 String jsonResult = doGet(msg);// 返回一个gson字符串结果 40 Gson gson = new Gson(); 41 Result result = null; 42 try { 43 result = gson.fromJson(jsonResult, Result.class);// 将jsonResult转换成Result对象 44 if (result.getCode() == 100000) {注:这里是根据图灵机器人返回的code值来设置的,100000代表文本类,200000代表链接类,其他自己可以查看官方文档 45 message.setMsg(result.getText()); 46 } 47 if (result.getCode() == 200000) { 48 // message.setUrl(result.getUrl()); 49 String string = result.getUrl().toString(); 50 message.setMsg(result.getText() + "\r\n" + string); 51 } 52 53 if (result.getCode() == 305000) { 54 // message.setUrl(result.getUrl()); 55 String string = result.getUrl().toString(); 56 message.setMsg(result.getText() + "\r\n" + string); 57 } 58 59 if (result.getCode() == 302000) { 60 message.setMsg("您想看新闻了吗?我反正我是想看了!"); 61 } 62 63 if (result.getCode() == 308000) { 64 message.setMsg("你要学做菜啊?好厉害!"); 65 } 66 } catch (Exception e) { 67 message.setMsg("哎呀,我受不了啦!"); 68 } 69 message.setDate(new Date()); 70 message.setType(Type.RECEIVE); 71 72 return message; 73 } 74 75 /** 76 * @param msg 77 * @return 返回result doGet方法 78 */ 79 public static String doGet(String msg) { 80 String resutl = ""; 81 82 String url = setParams(msg); 83 InputStream in = null; 84 ByteArrayOutputStream byos = null; 85 try { 86 URL urlNet = new java.net.URL(url); 87 HttpURLConnection conn = (HttpURLConnection) urlNet 88 .openConnection(); 89 conn.setReadTimeout(5 * 1000); 90 conn.setConnectTimeout(5 * 1000); 91 conn.setRequestMethod("GET"); 92 93 in = conn.getInputStream(); 94 int len = -1; 95 byte[] buffer = new byte[128]; 96 byos = new ByteArrayOutputStream(); 97 while ((len = in.read(buffer)) != -1) { 98 byos.write(buffer, 0, len); 99 } 100 byos.flush(); 101 resutl = new String(byos.toByteArray()); 102 } catch (MalformedURLException e) { 103 e.printStackTrace(); 104 } catch (IOException e) { 105 e.printStackTrace(); 106 } finally { 107 if (in != null) { 108 try { 109 in.close(); 110 } catch (IOException e) { 111 // TODO Auto-generated catch block 112 e.printStackTrace(); 113 } 114 } 115 if (byos != null) { 116 try { 117 byos.close(); 118 } catch (IOException e) { 119 // TODO Auto-generated catch block 120 e.printStackTrace(); 121 } 122 } 123 } 124 125 return resutl; 126 } 127 128 private static String setParams(String msg) { 129 String url = null; 130 try { 131 url = URL + "?key=" + API_KEY + "&info=" 132 + URLEncoder.encode(msg, "utf-8"); 133 } catch (UnsupportedEncodingException e) { 134 // TODO Auto-generated catch block 135 e.printStackTrace(); 136 } 137 return url; 138 139 } 140 141 /** 142 * doPost方法测试出问题,显示请求的内容为空 143 */ 144 145 public static String doPost(String msg) { 146 String result = ""; 147 URL url; 148 try { 149 url = new URL(URL); 150 HttpURLConnection urlConn = (HttpURLConnection) url 151 .openConnection(); 152 urlConn.setRequestMethod("POST"); 153 urlConn.setDoInput(true); 154 urlConn.setDoOutput(true); 155 urlConn.setUseCaches(false); 156 urlConn.setInstanceFollowRedirects(true); 157 urlConn.setRequestProperty("Content-Type", 158 "application/x-www-form-urlencoded"); 159 DataOutputStream out = new DataOutputStream(urlConn.getOutputStream()); 160 String param = "?key="+ API_KEY+"&info="+URLEncoder.encode(msg, "utf-8"); 161 out.writeBytes(param); 162 out.flush(); 163 out.close(); 164 if(urlConn.getResponseCode()==HttpURLConnection.HTTP_OK){ 165 InputStreamReader in = new InputStreamReader(urlConn.getInputStream()); 166 BufferedReader buffer = new BufferedReader(in); 167 String inputLine = null; 168 while((inputLine=buffer.readLine())!=null){ 169 result+=inputLine; 170 } 171 in.close(); 172 } 173 urlConn.disconnect(); 174 } catch (MalformedURLException e) { 175 e.printStackTrace(); 176 } catch (IOException e) { 177 e.printStackTrace(); 178 } 179 return result; 180 } 181 182 }
2.在HttpUtils中为了将从服务器端的json数据转换成我们需要的类型,还需创建一个Result类,代码如下:
1 package com.xiaochao.weather.bean; 2 3 import java.net.URL; 4 5 /** 6 * 此对象用来将服务器端获取到的json数据转换为该对象类型 7 * @author Administrator 8 * 9 */ 10 public class Result { 11 12 private int code; 13 private String text; 14 private URL url; 15 16 public int getCode() { 17 return code; 18 } 19 public void setCode(int code) { 20 this.code = code; 21 } 22 public String getText() { 23 return text; 24 } 25 public void setText(String text) { 26 this.text = text; 27 } 28 public URL getUrl() { 29 return url; 30 } 31 public void setUrl(URL url) { 32 this.url = url; 33 } 34 35 36 }
3.创建一个实体类,用于显示聊天信息,代码如下:
package com.xiaochao.weather.bean; import java.net.URL; import java.util.Date; import com.xiaochao.weather.enums.Type; /** * 实体类TalkMessage,对应显示在listview中的每一条数据 * @author Administrator * */ public class TalkMessage { private String name; private String msg; private Type type; private Date date; private URL url; public TalkMessage() { } public TalkMessage(String msg,Type type,Date date) { this.msg = msg; this.type = type; this.date = date; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public Type getType() { return type; } public void setType(Type type) { this.type = type; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } }
4.为了将聊天记录能够保存起来,我们还需要创建自己的数据库,先实现一个数据库帮助类,具体数据库从MainActivity中通过数据库帮组类实现,代码如下:
1 package com.xiaochao.weatherinfo.utils; 2 3 import android.content.Context; 4 import android.database.sqlite.SQLiteDatabase; 5 import android.database.sqlite.SQLiteDatabase.CursorFactory; 6 import android.database.sqlite.SQLiteOpenHelper; 7 8 /** 9 * 数据库帮助类,用来创建数据库库 10 * @author Administrator 11 * 12 */ 13 public class DataBaseHelper extends SQLiteOpenHelper { 14 15 public static final String TABLE_NAME = "message"; 16 public static final String ID = "_id"; 17 public static final String TEXTTIME = "texttime"; 18 public static final String TEXTMSG = "textmsg"; 19 public static final String TYPE = "type"; 20 public static final String NAME = "name"; 21 22 private static final String CREATE_TABLE = "create table "+TABLE_NAME+"("+ 23 ID+" integer primary key autoincrement,"+TEXTTIME+" text not null," + 24 NAME+" text not null,"+TEXTMSG+" text not null);"; 25 26 public DataBaseHelper(Context context, String name, CursorFactory factory, 27 int version) { 28 super(context, name, factory, version); 29 } 30 31 @Override 32 public void onCreate(SQLiteDatabase db) { 33 db.execSQL(CREATE_TABLE); 34 } 35 36 37 @Override 38 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 39 db.execSQL("drop table if exists "+TABLE_NAME); 40 onCreate(db); 41 } 42 }
5.我们还需要给listview创建一个适配器MyAdapter,代码如下:
package com.xiaochao.weather.adapter; import java.text.SimpleDateFormat; import java.util.List; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import com.xiaochao.weather.bean.TalkMessage; import com.xiaochao.weather.enums.Type; import com.xiaochao.weatherinfo.R; /** * 为listview配置的适配器 * @author Administrator * */ public class MyAdapter extends BaseAdapter { private Context context; private List<TalkMessage> list; private SQLiteDatabase db; public MyAdapter(Context context, List<TalkMessage> list, SQLiteDatabase db) { this.context = context; this.list = list; this.db = db; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public int getItemViewType(int position) { TalkMessage message = list.get(position); if (message.getType() == Type.RECEIVE) { return 0; } else { return 1; } } @Override public int getViewTypeCount() { return 2;//返回的数据为Type的数量,有RECEIVE和SEND两种。 } // String textmsg; // String textdate; /** * 返回给listview的数据 */ @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder = null; TalkMessage message = list.get(position);//获取到当前listview对应的item if (convertView == null) {注:下面的左右布局即为与机器人聊天布局,如果是自己发送的则显示右边布局,如果是机器人回复的则显示左边布局 viewHolder = new ViewHolder(); if (getItemViewType(position) == 0) { //如果Type的值为RECEIVE,则显示左边的布局 convertView = LayoutInflater.from(context).inflate( R.layout.leftlayout, parent, false); viewHolder.texttime = (TextView) convertView .findViewById(R.id.lefttime); viewHolder.textmsg = (TextView) convertView .findViewById(R.id.lefttext); convertView.setTag(viewHolder); } else { //否则Type的值即为SEND,则显示右边的布局。 convertView = LayoutInflater.from(context).inflate( R.layout.rightlayout, parent, false); viewHolder.texttime = (TextView) convertView .findViewById(R.id.righttime); viewHolder.textmsg = (TextView) convertView .findViewById(R.id.righttext); convertView.setTag(viewHolder); } } else { //如果不为空,则取出当前的viewHolder viewHolder = (ViewHolder) convertView.getTag(); } //为viewHolder中的view设置值 viewHolder.textmsg.setText(message.getMsg()); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String date = format.format(message.getDate()); viewHolder.texttime.setText(date); // SimpleDateFormat format1 = new // SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return convertView;//返回convertView作为listview的item } static final class ViewHolder { TextView texttime; TextView textmsg; } }
6.最后我们在MainActivity中实现我们需要完成的功能效果,代码如下:
1 package com.xiaochao.weatherinfo; 2 3 import java.text.SimpleDateFormat; 4 import java.util.ArrayList; 5 import java.util.Date; 6 import java.util.List; 7 8 import android.annotation.SuppressLint; 9 import android.app.Activity; 10 import android.app.AlertDialog; 11 import android.content.ClipboardManager; 12 import android.content.ContentValues; 13 import android.content.Context; 14 import android.content.DialogInterface; 15 import android.content.DialogInterface.OnClickListener; 16 import android.database.Cursor; 17 import android.database.sqlite.SQLiteDatabase; 18 import android.net.ParseException; 19 import android.os.AsyncTask; 20 import android.os.Bundle; 21 import android.text.TextUtils; 22 import android.view.View; 23 import android.view.Window; 24 import android.widget.AdapterView; 25 import android.widget.AdapterView.OnItemLongClickListener; 26 import android.widget.Button; 27 import android.widget.EditText; 28 import android.widget.ListView; 29 import android.widget.Toast; 30 31 import com.xiaochao.weather.adapter.MyAdapter; 32 import com.xiaochao.weather.bean.TalkMessage; 33 import com.xiaochao.weather.enums.Type; 34 import com.xiaochao.weatherinfo.utils.DataBaseHelper; 35 import com.xiaochao.weatherinfo.utils.HttpUtils; 36 public class MainActivity extends Activity { 37 38 private ListView listview; 39 private Button button; 40 private EditText edittext; 41 42 private MyAdapter adapter; 43 // private TalkMessage message; 44 private List<TalkMessage> list; 45 46 private SQLiteDatabase db; 47 private DataBaseHelper helper = new DataBaseHelper(this, "database", null, 48 1); 49 50 @Override 51 protected void onCreate(Bundle savedInstanceState) { 52 super.onCreate(savedInstanceState); 53 requestWindowFeature(Window.FEATURE_NO_TITLE); 54 setContentView(R.layout.mainlayout); 55 initView(); 56 initDatas(); 57 initListener(); 58 initSQLData(); 59 // listview.smoothScrollToPosition(listview.getCount()-1); 60 listview.setSelection(listview.getCount() - 1); 61 initListViewListener(); 62 } 63 64 private void initListViewListener() { 65 //长按监听事件点击 66 listview.setOnItemLongClickListener(new OnItemLongClickListener() { 67 68 @Override 69 public boolean onItemLongClick(final AdapterView<?> arg0, 70 final View view, final int position, long id) { 71 72 AlertDialog.Builder builder = new AlertDialog.Builder( 73 MainActivity.this); 74 builder.setPositiveButton("复制", new OnClickListener() { 75 76 @Override 77 public void onClick(DialogInterface dialog, int which) { 78 ClipboardManager cpm = (ClipboardManager) getApplication() 79 .getSystemService(Context.CLIPBOARD_SERVICE); 80 TalkMessage message = list.get(position); 81 cpm.setText(message.getMsg()); 82 Toast.makeText(getApplication(), "文本已复制到粘贴板", 83 Toast.LENGTH_SHORT).show(); 84 } 85 }); 86 87 builder.setNegativeButton("删除聊天记录", new OnClickListener() { 88 89 @Override 90 public void onClick(DialogInterface dialog, int which) { 91 list.removeAll(list); 92 db = helper.getWritableDatabase(); 93 db.delete(DataBaseHelper.TABLE_NAME, null, null); 94 adapter.notifyDataSetChanged(); 95 } 96 }); 97 builder.show(); 98 return false; 99 } 100 }); 101 } 102 103 private void initSQLData() { 104 105 //取出数据库中的数据 106 db = helper.getWritableDatabase(); 107 Cursor cursor = db.rawQuery("select * from " 108 + DataBaseHelper.TABLE_NAME, null); 109 if (cursor != null) { 110 while (cursor.moveToNext()) { 111 112 String textmsg = cursor.getString(cursor 113 .getColumnIndex(DataBaseHelper.TEXTMSG)); 114 String texttime = cursor.getString(cursor 115 .getColumnIndex(DataBaseHelper.TEXTTIME)); 116 String textname = cursor.getString(cursor 117 .getColumnIndex(DataBaseHelper.NAME)); 118 TalkMessage talkMessage = new TalkMessage(); 119 120 if (textname.equals("me")) { 121 SimpleDateFormat fDateFormat = new SimpleDateFormat( 122 "yyyy-MM-dd HH:mm:ss"); 123 Date date = null; 124 try { 125 try { 126 date = fDateFormat.parse(texttime); 127 } catch (Exception e) { 128 // TODO Auto-generated catch block 129 e.printStackTrace(); 130 } 131 } catch (ParseException e) { 132 e.printStackTrace(); 133 } 134 //通过判断textname的值来设置TalkMessage的类型,然后添加到list中 135 talkMessage.setDate(date); 136 talkMessage.setMsg(textmsg); 137 talkMessage.setType(Type.SEND); 138 list.add(talkMessage); 139 } 140 if (textname.equals("Android")) { 141 SimpleDateFormat fDateFormat = new SimpleDateFormat( 142 "yyyy-MM-dd HH:mm:ss"); 143 Date date = null; 144 try { 145 try { 146 date = fDateFormat.parse(texttime); 147 } catch (java.text.ParseException e) { 148 // TODO Auto-generated catch block 149 e.printStackTrace(); 150 } 151 } catch (ParseException e) { 152 e.printStackTrace(); 153 } 154 talkMessage.setDate(date); 155 talkMessage.setMsg(textmsg); 156 talkMessage.setType(Type.RECEIVE); 157 list.add(talkMessage); 158 } 159 adapter.notifyDataSetChanged(); 160 } 161 cursor.close(); 162 } 163 } 164 165 private void initListener() { 166 //为发送按钮设置点击监听事件 167 button.setOnClickListener(new View.OnClickListener() { 168 169 @Override 170 public void onClick(View v) { 171 final String msg = edittext.getText().toString();//获取到edittext中的文本内容 172 if (TextUtils.isEmpty(msg)) { 173 //当edittext中的内容为空时,弹出一个吐司,并使用return停止 174 Toast.makeText(MainActivity.this, "发送内容是空的啦!", 175 Toast.LENGTH_SHORT).show(); 176 return; 177 } 178 179 //初始化一个发送对象,并添加到list中 180 TalkMessage sendMessage = new TalkMessage(); 181 sendMessage.setDate(new Date()); 182 sendMessage.setMsg(msg); 183 sendMessage.setType(Type.SEND); 184 sendMessage.setName("me"); 185 list.add(sendMessage); 186 187 //将发送对象sendMessage插入到数据库 188 db = helper.getWritableDatabase(); 189 ContentValues values = new ContentValues(); 190 values.put(DataBaseHelper.TEXTMSG, sendMessage.getMsg()); 191 SimpleDateFormat format = new SimpleDateFormat( 192 "yyyy-MM-dd HH:mm:ss"); 193 String date = format.format(sendMessage.getDate()); 194 values.put(DataBaseHelper.TEXTTIME, date); 195 values.put(DataBaseHelper.NAME, sendMessage.getName()); 196 // String type = Type.SEND.toString(); 197 // values.put(DataBaseHelper.TYPE, type); 198 db.insert(DataBaseHelper.TABLE_NAME, null, values); 199 db.close(); 200 adapter.notifyDataSetChanged();//通知适配器进行更新 201 202 edittext.setText("");//将edittext清空 203 204 //开启一个异步任务用于接收服务器端返回的数据 205 new AsyncTask<String, String, TalkMessage>() { 206 207 @Override 208 protected TalkMessage doInBackground(String... params) { 209 TalkMessage receiveMessage = HttpUtils.sendMessage(msg);//服务器端得到的一个接收对象 210 211 //将服务器端得到的数据插入数据库 212 db = helper.getWritableDatabase(); 213 ContentValues values = new ContentValues(); 214 values.put(DataBaseHelper.TEXTMSG, 215 receiveMessage.getMsg()); 216 SimpleDateFormat format1 = new SimpleDateFormat( 217 "yyyy-MM-dd HH:mm:ss"); 218 String date2 = format1.format(receiveMessage.getDate()); 219 values.put(DataBaseHelper.TEXTTIME, date2); 220 // String type = Type.RECEIVE.toString(); 221 // values.put(DataBaseHelper.TYPE, type); 222 db.insert(DataBaseHelper.TABLE_NAME, null, values); 223 db.close(); 224 return receiveMessage; 225 } 226 227 @Override 228 protected void onPostExecute(TalkMessage result) { 229 //这里接收到的result就是doInBackground中返回的receiveMessage 230 list.add(result);//添加到list中 231 adapter.notifyDataSetChanged(); 232 } 233 234 }.execute(msg); 235 } 236 }); 237 } 238 239 @SuppressLint("SimpleDateFormat") 240 private void initDatas() { 241 //初始化数据 242 db = helper.getWritableDatabase();//创建我们自己需要的数据库db 243 list = new ArrayList<TalkMessage>(); 244 245 //初始化一个TalkMessage作为机器人的欢迎语 246 TalkMessage initmessage = new TalkMessage("主人,有什么可以为您服务的呢?", 247 Type.RECEIVE, new Date()); 248 249 //将初始化的initmessage插入数据库 250 ContentValues values = new ContentValues(); 251 values.put(DataBaseHelper.TEXTMSG, initmessage.getMsg()); 252 SimpleDateFormat formattime = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); 253 String formatdate = formattime.format(initmessage.getDate()); 254 values.put(DataBaseHelper.TEXTTIME, formatdate); 255 values.put(DataBaseHelper.NAME, "jiqiren"); 256 db.insert(DataBaseHelper.TABLE_NAME, null, values); 257 db.close(); 258 259 //将initmessage添加到list中,显示到listview上。 260 list.add(initmessage); 261 // Cursor cursor = 262 // db.rawQuery("select * from "+DataBaseHelper.TABLE_NAME, null); 263 264 adapter = new MyAdapter(this, list, db); 265 266 //为listview设置适配器 267 listview.setAdapter(adapter); 268 } 269 270 private void initView() { 271 //初始化view控件 272 listview = (ListView) findViewById(R.id.listview); 273 button = (Button) findViewById(R.id.buttonsend); 274 edittext = (EditText) findViewById(R.id.edittext); 275 } 276 277 }
时间: 2024-11-10 11:03:37