使用图灵机器人api接口开发智能聊天机器人
聊天界面
图灵机器人是一个智能机器人的开放平台,它提供了自动解析文字的API接口。创建一个机器人,就可以得到一个Key值,作为访问API的身份标识,下图的apikey就是图灵机器人对应的key值
注册完成后开始搭建项目
首先打开网络权限
只需在清单文件(AndroidManifest.xml)中添加允许访问网络权限
< uses-permission android:name=“android.permission.INTERNET”/>
界面布局
<?xml version="1.0" encoding="utf-8"?><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">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="与机器人聊天"
android:gravity="center"
android:textSize="36sp"
android:background="#2894EB"/>
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/title"
android:layout_above="@+id/ll"/>
<LinearLayout
android:id="@+id/ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#1591C9"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
>
<EditText
android:id="@+id/etMsg"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#fff"
android:layout_weight="3"
/>
<Button
android:id="@+id/send"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="发送" />
</LinearLayout>
</RelativeLayout>
需要两个Item布局,分别显示机器人两天界面和用户聊天界面
机器人item
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/ivRobot"
android:layout_width="80dp"
android:layout_height="60dp"
android:src="@drawable/robot"/>
<TextView
android:id="@+id/tvMsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:layout_toRightOf="@+id/ivRobot"/>
</RelativeLayout>
## 用户item
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/ivUser"
android:layout_width="80dp"
android:layout_height="60dp"
android:src="@drawable/man"
android:layout_alignParentRight="true"/>
<TextView
android:id="@+id/tvMsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:layout_toLeftOf="@+id/ivUser"
/>
</RelativeLayout>
封装聊天信息类
package com.fangkuai.chatrobot;
public class ChatBean {
public static final int SEND = 1; //发送消息
public static final int RECEIVE = 2; // 接收消息
private int state; //消息状态(接受或发送)
private String message; //发送的消息
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
编写适配器ChatAdapter
package com.fangkuai.chatrobot;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.List;
public class ChatAdapter extends BaseAdapter {
private List list;
private LayoutInflater inflater;
public ChatAdapter(Context context, List<ChatBean> list) {
this.list = list;
this.inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return list == null ? 0 : list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder=new ViewHolder();
//根据消息的状态加载不同view
if (list.get(position).getState()==ChatBean.RECEIVE){
//机器人布局
convertView=inflater.inflate(R.layout.chatting_left_item,null);
}else {
//用户布局
convertView=inflater.inflate(R.layout.chatting_right_item,null);
}
holder.message=convertView.findViewById(R.id.tvMsg);
holder.message.setText(list.get(position).getMessage());
return convertView;
}
class ViewHolder{
TextView message; //聊天内容
}
}
向服务器请求数据需要用到okhttp库的OkHttpClient类,添加okhttp库:com.squareup.okhttp3:okhttp:4.8.0
在res/values的strings.xml文件中存放欢迎信息
<resources>
<string name="app_name">ChatRobot</string>
<string-array name="welcome">
<item>亲爱的,想死我了,么么哒~</item>
<item>"更多资源,访问:http:myapptg.com</item>
<item>主人,人家好无聊呀,来陪我耍吧</item>
<item>"更多资源,请访问http:myapptg.com</item>
<item>主人,自从使用了高考助手,成绩是不是提高了呢?</item>
<item>小主人,你是不是学习累了,您可以输入,来个笑话,我可以为 您讲笑话哦</item>
<item>主人,你是不是上班疲惫了?您可以输入,讲故事,我可以为您讲一些有趣的故事哟</item>
<item>今天,我好累,不想和你聊天</item>
<item>小主人您复习的怎么样了?</item>
</string-array>
</resources>
界面交互代码
package com.fangkuai.chatrobot;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Paint;
import android.icu.text.UnicodeSetSpanner;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity implements
View.OnClickListener {
private List<ChatBean> list;
private ChatAdapter adapter;
private static final String WEB_SITE = "http://www.tuling123.com/openapi/api";
//key值,***器人后获取
private static final String KEY = "5454285e1e094f7084353e3ba0955567";
private String[] welcome; //存储欢迎信息
private String sendMsg; //发送的信息
private static final int MSG_OK = 1; //获取数据
private MHandler handler;
private ListView lv;
private EditText etMsg;
private Button send;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list=new ArrayList<ChatBean>();
welcome=getResources().getStringArray(R.array.welcome);
handler=new MHandler();
initView();
}
private void initView() {
lv = (ListView) findViewById(R.id.lv);
etMsg = (EditText) findViewById(R.id.etMsg);
send = (Button) findViewById(R.id.send);
adapter=new ChatAdapter(MainActivity.this,list);
lv.setAdapter(adapter);
//设置点击Enter键也能发送信息
etMsg.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode==KeyEvent.KEYCODE_ENTER
&&event.getAction()==KeyEvent.ACTION_DOWN){
sendData();
}
return false;
}
});
int random= (int) ((Math.random())*welcome.length-1); //获取随机数
showData(welcome[random]); //随机发送欢迎信息
send.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.send:
sendData();
break;
}
}
private void sendData() {
sendMsg=etMsg.getText().toString();
if (TextUtils.isEmpty(sendMsg)){
Toast.makeText(MainActivity.this,"您为输入任何信息",Toast.LENGTH_SHORT).show();
}
//替换所有空行和换行符
sendMsg=sendMsg.replaceAll(" ","").replaceAll("\n","").trim();
etMsg.setText("");
ChatBean bean=new ChatBean();
bean.setState(ChatBean.SEND);
bean.setMessage(sendMsg);
list.add(bean);
adapter.notifyDataSetChanged();
getDataFromServer();
}
//从服务器获取机器人发送的消息
private void getDataFromServer() {
OkHttpClient okHttpClient=new OkHttpClient();
Request request=new Request.Builder().url(WEB_SITE+"?key="+KEY+"&info="+sendMsg).build();
Call call=okHttpClient.newCall(request);
//异步线程访问网络
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
String res=response.body().string();
Message message=new Message();
message.obj=res;
message.what=MSG_OK;
handler.sendMessage(message);
}
});
}
//事件捕获
class MHandler extends Handler{
@Override
public void dispatchMessage(@NonNull Message msg) {
super.dispatchMessage(msg);
switch (msg.what){
case MSG_OK:
if (msg.obj!=null){
String result= (String) msg.obj;
parseData(result);
}
break;
}
}
}
//解析Json数据
private void parseData(String result) {
try {
JSONObject obj=new JSONObject(result);
String content=obj.getString("text"); //获取机器人信息
int code=obj.getInt("code"); //获取服务器状态码
updateView(code,content);
} catch (JSONException e) {
e.printStackTrace();
showData("主人,网络不好哦");
}
}
private void updateView(int code, String content) {
//code有很多种,可以cankao图灵机器人官网
switch (code){
case 4004:
showData("主人,今天我累了,我要休息了,明天再来找我耍吧");
break;
case 40005:
showData("主人,你说的是外星语吗?");
break;
case 40006:
showData("主人,我今天要去约会哦,暂不接客啦");
break;
case 40007:
showData("主人,明天再和你耍啦,我生病了,呜呜。。。。。。");
default:
showData(content);
break;
}
}
private void showData(String data) {
ChatBean bean=new ChatBean();
bean.setState(ChatBean.RECEIVE);
bean.setMessage(data);
list.add(bean);
adapter.notifyDataSetChanged();
}
//第一次点击时的时间
private long exitTime;
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode==KeyEvent.KEYCODE_BACK&&
event.getAction()==KeyEvent.ACTION_DOWN){
if ((System.currentTimeMillis()-exitTime)>2000){
Toast.makeText(MainActivity.this,"再按一次退出",Toast.LENGTH_SHORT).show();
exitTime=System.currentTimeMillis();
}else {
MainActivity.this.finish();
System.exit(0);
}
}
return super.onKeyDown(keyCode, event);
}
}