Android图灵聊天机器人-薇尔莉特
智能聊天机器人-图灵机器人项目说明
文章目录
- 智能聊天机器人-图灵机器人项目说明
- 1.项目介绍
- 2.项目用到的技术
- 3.项目的开发环境
- 4.开发步骤
- 1.首先编写主界面(activity_main.xml文件),这个界面主要是一些简单的基础控件,与一个ListView
- 2.访问http://www.turingapi.com/ 申请注册图灵机器人(免费版)
- 3.导入主界面需要的图片(drawable文件内)以及需要的xml定义的样式资源
- 2.搭建聊天的条目布局
- 3.创建一个ChatBean类来存放消息信息这些属性
- 4.创建一个ChatAdapter数据适配器来对ListView进行数据适配
- 5.添加其他操作(1.在清单文件添加网络权限 2.添加okhttp库)
- 6.主程序MainActivity文件
1.项目介绍
Github项目地址:https://github.com/Churchillhua-wangfei/WF_Violet_RobotProject
基于这钉钉时代(疫情阶段),在家闷得慌,以一个初学者的身份制作一个Android图灵机器人聊天项目。
效果图:
2.项目用到的技术
简单的XML基础 + ListView控件 + 数据器适配 + Postman请求调用API
3.项目的开发环境
操作系统:windows10 1909
开发工具: JDK8 + Android studio 3.5.2 + 模拟器(Android8.0)
Android版本: Android API29
第三方API网址:http://www.turingapi.com/
4.开发步骤
1.首先编写主界面(activity_main.xml文件),这个界面主要是一些简单的基础控件,与一个ListView
<?xml version="1.0" encoding="utf-8"?><LinearLayout 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" android:background="#E7E7E7" android:orientation="vertical" tools:context=".MainActivity"> <RelativeLayout android:id="@+id/head" android:layout_width="match_parent" android:layout_height="42dp" android:background="#fff"> <ImageView android:id="@+id/re" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_marginTop="7dp" android:src="@drawable/re" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_marginLeft="5dp" android:layout_toRightOf="@+id/re" android:text="王飞的Robot-薇尔莉特" android:textColor="#000000" android:textSize="16dp" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginTop="4dp" android:layout_marginRight="10dp" android:src="@drawable/config" /> RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/rl_bottom" android:cacheColorHint="@android:color/black" android:divider="@null" android:listSelector="@null" android:transcriptMode="alwaysScroll" /> <RelativeLayout android:id="@+id/rl_bottom" android:layout_width="match_parent" android:layout_height="55dp" android:layout_alignParentBottom="true" android:background="@drawable/bottom_bg"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_marginLeft="3dp" android:layout_marginTop="10dp" android:src="@drawable/voice" /> <Button android:id="@+id/btn_send" android:layout_width="75dp" android:layout_height="40dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="10dp" android:background="@drawable/button_circle_shape" android:fontFamily="sans-serif-black" android:text="发 送" android:textColor="#FCFCFC" android:textSize="14sp" /> <EditText android:id="@+id/et_send_msg" android:layout_width="match_parent" android:layout_height="40dp" android:layout_centerVertical="true" android:layout_marginLeft="45dp" android:layout_marginRight="10dp" android:layout_toLeftOf="@id/btn_send" android:background="@drawable/textview_circle_item" android:singleLine="true" android:textColor="@android:color/black" android:textSize="18sp" /> RelativeLayout> RelativeLayout>LinearLayout>
2.访问http://www.turingapi.com/ 申请注册图灵机器人(免费版)
3.导入主界面需要的图片(drawable文件内)以及需要的xml定义的样式资源
详细可以参考Github:https://github.com/Churchillhua-wangfei/WF_Violet_RobotProject
1.btn_send_selector.xm
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:drawable="@android:color/darker_gray" android:state_pressed="true" /><item android:drawable="@color/btn_send_bg_normal" />selector>
2.button_circle_shape.xml
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"><solid android:color="#6EA74F" /><corners android:radius="25dp" /><paddingandroid:bottom="2dp"android:left="2dp"android:right="2dp"android:top="2dp"/>shape>
3.chat_left_selector.xml
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/chat_left_bg_pressed" android:state_pressed="true" /> <item android:drawable="@drawable/chat_left_bg_normal" />selector>
4.chat_right_selector.xml
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/chat_right_bg_pressed" android:state_pressed="true" /> <item android:drawable="@drawable/chat_right_bg_normal" />selector>
5.textview_circle_item.xml
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#FFFFFF" /> <corners android:radius="25dp" /> <padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" />shape>
6.values(clolors.xml)
<?xml version="1.0" encoding="utf-8"?><resources> <color name="colorPrimary">#F57C00color> <color name="colorPrimaryDark">#F57C00color> <color name="colorAccent">#D81B60color> <color name="btn_send_bg_normal">#95EC69color>resources>
7.values(strings.xml)
图灵机器人 - 遇见你,真美好
- 客人,听好了。我的名字是薇尔莉特
- 这位客人,我的名字是薇尔莉特
- 请问客人你有什么需要?
8.values(styles.xml)
<resources> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> - "colorPrimary"
>#0288D1 - "colorPrimaryDark">#0288D1
- "colorAccent">@color/colorAccent
style> <style name="chat_content_style"> - "android:minHeight"
>50dp - "android:gravity">center_vertical
- "android:layout_marginTop">12dp
- "android:textColor">#000000
- "android:textStyle">bold
- "android:textSize">15sp
- "android:lineSpacingExtra">2dp
- "android:clickable">true
- "android:focusable">true
- "android:background">#bfbfbf
style>resources>
2.搭建聊天的条目布局
1.chatting_robot_item.xml
``
<?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="wrap_content" android:padding="6dp"> <TextView android:id="@+id/tv_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="2020年4月29日上午10点" android:layout_centerHorizontal="true" android:textColor="#000000" android:textSize="18sp" /> <ImageView android:id="@+id/iv_head" android:layout_width="60dp" android:layout_height="60dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginTop="15dp" android:layout_marginLeft="2dp" android:background="@drawable/violet" android:focusable="false" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="薇尔莉特" android:layout_below="@+id/iv_head" android:textColor="#7B1FA2" android:textSize="16dp" android:layout_marginTop="5dp" android:layout_marginLeft="5dp" android:textStyle="bold" /> <TextView android:id="@+id/tv_chat_content" style="@style/chat_content_style" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_marginTop="30dp" android:layout_toEndOf="@id/iv_head" android:background="@drawable/chat_left_selector" />RelativeLayout>
2.chatting_user_item.xml
<?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" android:padding="6dp"> <TextView android:id="@+id/tv_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="2020年4月29日上午10点" android:layout_centerHorizontal="true" android:textColor="#000000" android:textSize="18sp" /> <ImageView android:id="@+id/iv_head" android:layout_width="55dp" android:layout_height="55dp" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginTop="15dp" android:layout_marginRight="2dp" android:background="@drawable/wangfei" android:focusable="false" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/iv_head" android:layout_alignParentRight="true" android:text="王飞" android:textSize="20dp" android:textStyle="bold" android:layout_marginTop="8dp" android:layout_marginRight="8dp" android:textColor="#090909" /> <TextView android:id="@+id/tv_chat_content" style="@style/chat_content_style" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="5dp" android:layout_marginTop="30dp" android:layout_toLeftOf="@id/iv_head" android:background="@drawable/chat_right_selector" />RelativeLayout>
3.创建一个ChatBean类来存放消息信息这些属性
package com.mzxy.wangfei_robot_chattingproject;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; }}
4.创建一个ChatAdapter数据适配器来对ListView进行数据适配
package com.mzxy.wangfei_robot_chattingproject;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;class ChatAdapter extends BaseAdapter { private List<ChatBean> chatBeanList; //聊天数据 private LayoutInflater layoutInflater; public ChatAdapter(List<ChatBean> chatBeanList, Context context) { this.chatBeanList = chatBeanList; layoutInflater = LayoutInflater.from(context); } @Override public int getCount() { return chatBeanList.size(); } @Override public Object getItem(int position) { return chatBeanList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View contentView, ViewGroup viewGroup) { Holder holder = new Holder(); //判断当前的信息是发送的信息还是接收到的信息,不同信息加载不同的view if (chatBeanList.get(position).getState() == ChatBean.RECEIVE) { //加载左边布局,也就是机器人对应的布局信息 contentView = layoutInflater.inflate(R.layout.chatting_robot_item, null); } else { //加载右边布局,也就是用户对应的布局信息 contentView = layoutInflater.inflate(R.layout.chatting_user_item, null); } holder.tv_chat_content = (TextView) contentView.findViewById(R.id. tv_chat_content); holder.tv_chat_content.setText(chatBeanList.get(position).getMessage()); return contentView; } class Holder { public TextView tv_chat_content; // 聊天内容 }}
5.添加其他操作(1.在清单文件添加网络权限 2.添加okhttp库)
1.在清单文件添加网络权限
<uses-permission android:name="android.permission.INTERNET" />
2.添加okhttp库(在build.gradle文件中添加)–在dependencies
dependencies{implementation 'com.squareup.okhttp3:okhttp:3.12.0'}
6.主程序MainActivity文件
package com.mzxy.wangfei_robot_chattingproject;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.appcompat.app.AppCompatActivity;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 { /** * * @author:王飞 * @My_GitHub:https://github.com/Churchillhua-wangfei * @Project_FinishTime:2020年4月29日——09点09分 */ private ListView listView; private ChatAdapter adpter; private List<ChatBean> chatBeanList; // 存放所有聊天数据的集合 private EditText et_send_msg; private Button btn_send; // 接口地址 private static final String WEB_SITE = "http://www.tuling123.com/openapi/api"; // 唯一key,该key的值是从官网注册账号后获取的,注册地址来自于:http://www.tuling123.com/ private static final String KEY = "40abb943778c472ea40e9c31e1a3c339"; private String sendMsg; // 发送的信息 private String welcome[]; // 存储欢迎信息 private MHandler mHandler; public static final int MSG_OK = 1; // 获取数据 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); chatBeanList = new ArrayList<ChatBean>(); mHandler = new MHandler(); // 获取内置的欢迎信息 welcome = getResources().getStringArray(R.array.welcome); initView(); // 初始化界面控件 } public void initView() { listView = findViewById(R.id.list); et_send_msg = findViewById(R.id.et_send_msg); btn_send = findViewById(R.id.btn_send); adpter = new ChatAdapter(chatBeanList, this); listView.setAdapter(adpter); btn_send.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View arg0) { sendData(); // 点击发送按钮,发送信息 } }); et_send_msg.setOnKeyListener( new View.OnKeyListener() { @Override public boolean onKey(View view, int keyCode, KeyEvent keyEvent) { if (keyCode == KeyEvent.KEYCODE_ENTER && keyEvent.getAction() == KeyEvent.ACTION_DOWN) { sendData(); // 点击Enter键也可以发送信息 } return false; } }); int position = (int) (Math.random() * welcome.length - 1); // 获取一个随机数 showData(welcome[position]); // 用随机数获取机器人的首次聊天信息 } private void sendData() { sendMsg = et_send_msg.getText().toString(); // 获取你输入的信息 if (TextUtils.isEmpty(sendMsg)) { // 判断是否为空 Toast.makeText(this, "你还未输任何信息,输出框不能为空", Toast.LENGTH_SHORT).show(); return; } et_send_msg.setText(""); // 替换空格和换行 sendMsg = sendMsg.replaceAll(" ", "").replaceAll("\n", "").trim(); ChatBean chatBean = new ChatBean(); chatBean.setMessage(sendMsg); chatBean.setState(chatBean.SEND); // SEND表示自己发送的信息 chatBeanList.add(chatBean); // 将发送的信息添加到chatBeanList集合中 adpter.notifyDataSetChanged(); // 更新ListView列表 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 onResponse(Call call, Response response) throws IOException { String res = response.body().string(); Message msg = new Message(); msg.what = MSG_OK; msg.obj = res; mHandler.sendMessage(msg); } @Override public void onFailure(Call call, IOException e) {} }); } /** 事件捕获 */ class MHandler extends Handler { @Override public void dispatchMessage(Message msg) { super.dispatchMessage(msg); switch (msg.what) { case MSG_OK: if (msg.obj != null) { String vlResult = (String) msg.obj; paresData(vlResult); } break; } } } private void paresData(String JsonData) { // Json解析 try { JSONObject obj = new JSONObject(JsonData); String content = obj.getString("text"); // 获取的机器人信息 int code = obj.getInt("code"); // 服务器状态码 updateView(code, content); // 更新界面 } catch (JSONException e) { e.printStackTrace(); showData("网络未连接"); } } private void showData(String message) { ChatBean chatBean = new ChatBean(); chatBean.setMessage(message); chatBean.setState(ChatBean.RECEIVE); // RECEIVE表示接收到机器人发送的信息 chatBeanList.add(chatBean); // 将机器人发送的信息添加到chatBeanList集合中 adpter.notifyDataSetChanged(); } private void updateView(int code, String content) { // code有很多种状,先弄几组测试数据 switch (code) { case 4004: showData("测试数据01"); break; case 40005: showData("测试数据02"); break; case 40006: showData("测试数据03"); break; case 40007: showData("测试数据04"); break; default: showData(content); break; } } protected 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 true; } return super.onKeyDown(keyCode, event); }}
试数据04");
break;
default:
showData(content);
break;
}
}
protected 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 true;
}
return super.onKeyDown(keyCode, event);
}
}
##### 7.最后清理不必要的文件,Build APK文件
更多相关文章
- android 适配
- 为 Android(安卓)添加 Java 层服务(二)
- [置顶] android studio在svn中ignore的文件及文件夹
- 【Android】 ANR异常及traces信息解析
- 【Android】学习笔记(1)――基本控件一
- Android之项目中如何用好构建神器Gradle?
- 利用Android(安卓)Studio、MAT对Android进行内存泄漏检测
- 7种形式的Android(安卓)Dialog使用举例
- 服务器主动向android手机端推送消息---------Linux下实现