要实现一个图灵机器人(类似微软小冰),首先需要在 http://www.tuling123.com/ 中注册,然后创建一个应用,便可通过应用的API key使用图灵机器人。图灵机器人非常方便的一点是不需要添加额外的库类。只需要get请求访问 http://www.tuling123.com/openapi/api 就可以获得json数据,然后对json数据进行解析即可。
1 写一个访问图灵机器人网络地址的工具类
这里用到了谷歌sdk自带的JSONObject解析json数据,然后根据json数据中的code值辨别不同的json类型
最终返回一个JavaBean对象,示例代码如下:
public class HttpUtils {
public static final String TURING_URL = " http://www.tuling123.com/openapi/api";
public static final String API_KET = "ded5d09265aa95782f638bfdcb5eb96c";
public static ChatMessage doGet(String msg) {
String url = setParams(msg);
if (TextUtils.isEmpty(url)) {
return null;
}
ChatMessage chatMessage=new ChatMessage();
InputStream inputStream = null;
ByteArrayOutputStream outputStream = null;
try {
URL urlNet = new URL(url);
HttpURLConnection connection = (HttpURLConnection) urlNet
.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(3 * 1000);
connection.setReadTimeout(5 * 1000);
int code = connection.getResponseCode();
Log.i("Code", code + "");
inputStream = connection.getInputStream();
int len = -1;
byte[] buff = new byte[128];
outputStream = new ByteArrayOutputStream();
while ((len = inputStream.read(buff)) != -1) {
outputStream.write(buff, 0, len);
}
outputStream.flush();
Gson gson = new Gson();
String result=new String(outputStream.toByteArray());
JSONObject jsonObject=new JSONObject(result) ;
int typeCode=jsonObject.getInt("code");
Log.i("code", typeCode+"");
chatMessage.setDate(new Date());
chatMessage.setName("小王");
chatMessage.setType(Type.INCOMING);
if(typeCode==100000)
{
chatMessage.setCode(typeCode);
chatMessage.setText(jsonObject.getString("text"));
}else if(typeCode==200000)
{
chatMessage.setCode(typeCode);
chatMessage.setText(jsonObject.getString("text"));
chatMessage.setUrl(jsonObject.getString("url"));
}else if(typeCode==302000)
{
NewsBean newsBean=gson.fromJson(result, NewsBean.class);
chatMessage.setCode(typeCode);
chatMessage.setText(newsBean.getText());
chatMessage.setList(newsBean.getList());
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (inputStream != null)
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (outputStream != null)
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return chatMessage;
}
private static String setParams(String msg) {
String url = "";
try {
url = TURING_URL + "?key=" + API_KET + "&info="
+ URLEncoder.encode(msg, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return url;
}
}
2 聊天界面
聊天界面设计比较简单 顶部是一个标题栏,中间是显示聊天记录的LIstView,底部是一个发送消息的布局。
总布局:
<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"
tools:context=".MainActivity" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_alignParentTop="true"
android:background="@drawable/title_bar"
android:id="@+id/rl_top"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#ffffff"
android:text="小王"
android:textSize="22sp"
/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="55dp"
android:layout_alignParentBottom="true"
android:background="@drawable/bottom_bar"
android:id="@+id/rl_bottom"
>
<Button
android:id="@+id/btn_send"
android:layout_width="60dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="发送"
android:onClick="send"
/>
<EditText
android:id="@+id/et_msg"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_centerVertical="true"
android:background="@drawable/login_edit_normal"
android:textSize="18sp"
android:layout_toLeftOf="@+id/btn_send"
/>
</RelativeLayout>
<ListView
android:id="@+id/lv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/rl_bottom"
android:layout_below="@+id/rl_top"
android:divider="@null"
android:dividerHeight="5dp"
/>
</RelativeLayout>
子ListVIew的布局也比较简单,有一个图像和TextView组成,根据信息来设置布局是居左还是居右。
<?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="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tv_time_from"
android:text="2012-12-12 12:12:12"
android:textSize="16sp"
android:background="#bebebe"
android:textColor="#f5f5f5"
android:gravity="center"
/>
<LinearLayout
android:layout_marginTop="3dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:layout_width="49dp"
android:layout_height="49dp"
android:src="@drawable/xw" />
<TextView
android:id="@+id/tv_text_from"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/chatfrom_bg_normal"
android:gravity="center_vertical"
android:text="你好"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
3 实现聊天界面的逻辑功能
主要是实现发送按钮的点击事件,当触发点击事件后,将开启子线程将从EditText获得的文本信息向图灵
机器人发出请求。获得数据后将异步刷新ListView,显示结果,示例代码如下:
public class MainActivity extends Activity {
private ListView lv_content;
private List<ChatMessage> chats=new ArrayList<ChatMessage>();
private MyAdapter adapter=null;
private EditText et_msg;
private Handler handler=new Handler(){
public void handleMessage(android.os.Message msg) {
ChatMessage chatMessage=(ChatMessage) msg.obj;
chats.add(chatMessage);
adapter.notifyDataSetChanged();
lv_content.setSelection(lv_content.getBottom());
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
lv_content=(ListView) findViewById(R.id.lv_content);
et_msg=(EditText) findViewById(R.id.et_msg);
adapter=new MyAdapter(this);
lv_content.setAdapter(adapter);
ChatMessage m1=new ChatMessage();
m1.setDate(new Date());
m1.setName("h");
m1.setText("你好,我是小王");
m1.setType(Type.INCOMING);
chats.add(m1);
// EditText的监听器
et_msg.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
lv_content.setSelection(lv_content.getBottom());
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
et_msg.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
lv_content.setSelection(lv_content.getBottom());
}
});
}
public void send(View v)
{
final String msg=et_msg.getText().toString();
if(TextUtils.isEmpty(msg))
{
return ;
}
Log.i("data", msg);
ChatMessage chatMessage=new ChatMessage();
chatMessage.setDate(new Date());
chatMessage.setName("h");
chatMessage.setText(msg);
chatMessage.setType(Type.OUTCOMING);
chats.add(chatMessage);
adapter.notifyDataSetChanged();
lv_content.setSelection(lv_content.getBottom());
et_msg.setText("");
// 关闭输入法的软键盘
InputMethodManager im = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
im.hideSoftInputFromWindow(getCurrentFocus().getApplicationWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
new Thread()
{
public void run() {
ChatMessage chatMessage=HttpUtils.doGet(msg);
/* chatMessage.setDate(new Date());
chatMessage.setName("h");
chatMessage.setText(bean.getText());
chatMessage.setType(Type.INCOMING);*/
Message message=Message.obtain();
message.obj=chatMessage;
handler.sendMessage(message);
};
}.start();
}
private class MyAdapter extends BaseAdapter{
private Context context;
public MyAdapter(Context context)
{
this.context=context;
}
@Override
public int getCount() {
return chats.size();
}
@Override
public Object getItem(int position) {
return chats.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ChatMessage chatMessage = chats.get(position);
ViewHolder holder=null;
if(convertView==null)
{
if(getItemViewType(position)==0)
{
convertView=View.inflate(context, R.layout.item_from_msg, null);
holder=new ViewHolder();
holder.tv_time=(TextView) convertView.findViewById(R.id.tv_time_from);
holder.tv_content=(TextView) convertView.findViewById(R.id.tv_text_from);
convertView.setTag(holder);
}else{
convertView=View.inflate(context, R.layout.item_to_msg, null);
holder=new ViewHolder();
holder.tv_time=(TextView) convertView.findViewById(R.id.tv_time_to);
holder.tv_content=(TextView) convertView.findViewById(R.id.tv_text_to);
convertView.setTag(holder);
}
}else{
holder=(ViewHolder) convertView.getTag();
}
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
holder.tv_time.setText(df.format(chatMessage.getDate()));
int code=chatMessage.getCode();
if(code==100000)
{
holder.tv_content.setText(chatMessage.getText());
Log.i("Text", chatMessage.getText());
}else if(code==200000)
{
holder.tv_content.setText(chatMessage.getText()
+chatMessage.getUrl());
Log.i("URL", chatMessage.getText());
/* Intent intent =new Intent(context,UrlActivity.class);
intent.putExtra("url", chatMessage.getUrl());
context.startActivity(intent);*/
}else if(code==302000)
{
News []list=chatMessage.getList();
StringBuffer sb=new StringBuffer();
for(News n:list)
{
sb.append(n.toString());
}
holder.tv_content.setText(chatMessage.getText()+sb.toString());
Log.i("NEWS", chatMessage.getText());
}else{
holder.tv_content.setText(chatMessage.getText());
Log.i("ELSE", chatMessage.getText());
}
return convertView;
}
@Override
public int getItemViewType(int position) {
return chats.get(position).getType()==Type.INCOMING?0:1;
}
@Override
public int getViewTypeCount() {
return 2;
}
public class ViewHolder{
TextView tv_time;
TextView tv_content;
}
}
}
4.效果图:
时间: 2024-10-28 21:26:45