本博客整理自慕客网Android智能机器人“小慕”的实现。
通过本课程主要可以学到两个知识点:
1、第三方API 图灵机器人的使用
2、ListView多种Item布局时的处理,实现聊天对话的界面
说明:使用图灵机器人需要首先注册相关账号,网址为:http://www.tuling123.com/openapi/
1、编写一个工具类实现消息发送与接收
public class HttpUtils { private static final String URL = "http://www.tuling123.com/openapi/api"; private static final String API_KEY = "080390332ce0704a54cd5a3aaf70f443"; public static String doGet(String msg) { String result = ""; String url = setParams(msg); ByteArrayOutputStream baos = null; InputStream is = null; try { java.net.URL urlNet = new java.net.URL(url); HttpURLConnection conn = (HttpURLConnection) urlNet.openConnection(); conn.setReadTimeout(5 * 1000); conn.setConnectTimeout(5 * 1000); conn.setRequestMethod("GET"); is = conn.getInputStream(); int len = -1; byte[] buf = new byte[128]; baos = new ByteArrayOutputStream(); while((len = is.read(buf)) != -1) { baos.write(buf, 0, len); } baos.flush(); result = new String(baos.toByteArray()); } catch (MalformedURLException e) { e.printStackTrace(); } catch (ProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { baos.close(); } catch (IOException e) { e.printStackTrace(); } try { is.close(); } catch (IOException e) { e.printStackTrace(); } } return result; } private 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; } }2、搭建测试环境,对工具类进行测试
在AndroidManifest.xml作如下配置:
</pre><pre name="code" class="html"><uses-library android:name="android.test.runner"/>
<instrumentation android:targetPackage="com.zong.tulingrobot" android:label="This is a test" android:name="android.test.InstrumentationTestRunner"></instrumentation>测试类:
public class TestHttpUtils extends AndroidTestCase { public void testSendInfo() { String res = HttpUtils.doGet("给我讲个笑话"); Log.e("TAG", res); res = HttpUtils.doGet("给我讲个鬼故事"); Log.e("TAG", res); res = HttpUtils.doGet("你好"); Log.e("TAG", res); res = HttpUtils.doGet("你真美"); Log.e("TAG", res); } }
3、完成消息实体的编写
界面显示所需类:
public class ChatMessage { private String name; private String msg; private Type type; private Date date; public enum Type { INCOMING, OUTCOMING } 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; } }服务端返回数据所需类:
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; } }修改HttpUtils工具类,添加如下方法:
public static ChatMessage sendMessage(String msg) { ChatMessage chatMessage = new ChatMessage(); String jsonRes = doGet(msg); Gson gson = new Gson(); Result result = null; try { result = gson.fromJson(jsonRes, Result.class); chatMessage.setMsg(result.getText()); } catch (JsonSyntaxException e) { chatMessage.setMsg("服务器繁忙,请稍候再试"); } chatMessage.setDate(new Date()); chatMessage.setType(Type.INCOMING); return chatMessage; }其中用到把字符串转换成JSON对象的第三方库gson,下载地址:https://code.google.com/p/google-gson/
4、完成ListView布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/id_from_msg_date" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="#bebebe" android:text="2012-12-12 12:12:12" android:textColor="#f5f5f5" android:textSize="12sp"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <ImageView android:layout_width="49dp" android:layout_height="49dp" android:src="@drawable/icon"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="小慕" android:textSize="18sp"/> </LinearLayout> <TextView android:id="@+id/id_from_msg_info" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/chatfrom_bg_normal" android:gravity="center_vertical" android:textSize="16sp" android:text="你好"/> </LinearLayout> </LinearLayout>
<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" > <RelativeLayout android:id="@+id/id_ly_top" android:layout_width="fill_parent" android:layout_height="45dp" android:layout_alignParentTop="true" android:background="@drawable/title_bar"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="小慕" android:textColor="#ffffff" android:textSize="22sp" /> </RelativeLayout> <RelativeLayout android:id="@+id/id_ly_bottom" android:layout_width="fill_parent" android:layout_height="55dp" android:layout_alignParentBottom="true" android:background="@drawable/bottom_bar"> <Button android:id="@+id/id_send_msg" android:layout_width="60dp" android:layout_height="40dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:background="@drawable/send_btn_bg" android:text="发送"/> <EditText android:id="@+id/id_input_msg" android:layout_width="fill_parent" android:layout_height="40dp" android:layout_centerVertical="true" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_toLeftOf="@id/id_send_msg" android:background="@drawable/login_edit_normal" android:textSize="18sp"/> </RelativeLayout> <ListView android:id="@+id/id_listview_msgs" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_above="@id/id_ly_bottom" android:layout_below="@id/id_ly_top" android:divider="@null" android:dividerHeight="5dp"> </ListView> </RelativeLayout>
public class ChatMessageAdapter extends BaseAdapter { private LayoutInflater mInflater; private List<ChatMessage> mDatas; public ChatMessageAdapter(Context context, List<ChatMessage> mDatas) { 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; } @Override public View getView(int position, View convertView, ViewGroup parent) { ChatMessage chatMessage = mDatas.get(position); ViewHolder viewHolder = null; if(convertView == null) { //通过ItemType设置不同的布局 if(getItemViewType(position) == 0) { convertView = mInflater.inflate(R.layout.item_from_msg, parent, false); viewHolder = new ViewHolder(); viewHolder.mDate = (TextView) convertView.findViewById(R.id.id_from_msg_date); viewHolder.mMsg = (TextView) convertView.findViewById(R.id.id_from_msg_info); } else { convertView = mInflater.inflate(R.layout.item_to_msg, parent, false); viewHolder = new ViewHolder(); viewHolder.mDate = (TextView) convertView.findViewById(R.id.id_to_msg_date); viewHolder.mMsg = (TextView) convertView.findViewById(R.id.id_to_msg_info); } convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } //设置数据 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); viewHolder.mDate.setText(df.format(chatMessage.getDate())); viewHolder.mMsg.setText(chatMessage.getMsg()); return convertView; } @Override public int getItemViewType(int position) { ChatMessage chatMessage = mDatas.get(position); if(chatMessage.getType() == Type.INCOMING) { return 0; } return 1; } @Override public int getViewTypeCount() { return 2; } private final class ViewHolder { TextView mDate; TextView mMsg; } }
public class MainActivity extends Activity { private ListView mMsgs; private ChatMessageAdapter mAdapter; private List<ChatMessage> mDatas; private EditText mInputMsg; private Button mSendMsg; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { //等待接收,子线程完成数据 的返回 ChatMessage fromMessage = (ChatMessage) msg.obj; mDatas.add(fromMessage); mAdapter.notifyDataSetChanged(); mMsgs.setSelection(mDatas.size() - 1); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); initView(); initDatas(); //初始化事件 initListener(); } private void initView() { mMsgs = (ListView) findViewById(R.id.id_listview_msgs); mInputMsg = (EditText) findViewById(R.id.id_input_msg); mSendMsg = (Button) findViewById(R.id.id_send_msg); } private void initDatas() { mDatas = new ArrayList<ChatMessage>(); mDatas.add(new ChatMessage("你好,小慕为你服务!", Type.INCOMING, new Date())); mAdapter = new ChatMessageAdapter(this, mDatas); mMsgs.setAdapter(mAdapter); } private void initListener() { mSendMsg.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { final String toMsg = mInputMsg.getText().toString(); if(TextUtils.isEmpty(toMsg)) { Toast.makeText(MainActivity.this, "发送消息不能为空!", Toast.LENGTH_SHORT).show(); return; } ChatMessage toMessage = new ChatMessage(); toMessage.setDate(new Date()); toMessage.setMsg(toMsg); toMessage.setType(Type.OUTCOMING); mDatas.add(toMessage); mAdapter.notifyDataSetChanged(); mMsgs.setSelection(mDatas.size() - 1); mInputMsg.setText(""); new Thread() { public void run() { ChatMessage fromMessage = HttpUtils.sendMessage(toMsg); Message m = Message.obtain(); m.obj = fromMessage; mHandler.sendMessage(m); } }.start(); } }); } }
源码下载