聊天界面
图灵机器人是一个智能机器人的开放平台,它提供了自动解析文字的API接口。创建一个机器人,就可以得到一个Key值,作为访问API的身份标识,下图的apikey就是图灵机器人对应的key值
注册完成后开始搭建项目
首先打开网络权限
只需在清单文件(AndroidManifest.xml)中添加允许访问网络权限
< uses-permission android:name=“android.permission.INTERNET”/>
界面布局
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/title"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="与机器人聊天"android:gravity="center"android:textSize="36sp"android:background="#2894EB"/><ListViewandroid:id="@+id/lv"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_below="@+id/title"android:layout_above="@+id/ll"/><LinearLayoutandroid:id="@+id/ll"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#1591C9"android:orientation="horizontal"android:layout_alignParentBottom="true"><EditTextandroid:id="@+id/etMsg"android:layout_width="0dp"android:layout_height="wrap_content"android:background="#fff"android:layout_weight="3"/><Buttonandroid: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="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><ImageViewandroid:id="@+id/ivRobot"android:layout_width="80dp"android:layout_height="60dp"android:src="@drawable/robot"/><TextViewandroid: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="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><ImageViewandroid:id="@+id/ivUser"android:layout_width="80dp"android:layout_height="60dp"android:src="@drawable/man"android:layout_alignParentRight="true"/><TextViewandroid: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);}@Overridepublic int getCount() {return list == null ? 0 : list.size();}@Overridepublic Object getItem(int position) {return list.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder=new ViewHolder();//根据消息的状态加载不同viewif (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:</item><item>主人,人家好无聊呀,来陪我耍吧</item><item>"更多资源,请访问http:</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 implementsView.OnClickListener {private List<ChatBean> list;private ChatAdapter adapter;private static final String WEB_SITE = "/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;@Overrideprotected 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() {@Overridepublic 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);}@Overridepublic 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() {@Overridepublic void onFailure(@NotNull Call call, @NotNull IOException e) {}@Overridepublic 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{@Overridepublic 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;@Overridepublic 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);}}