一、项目介绍
​ 本项目使用android来开发一个智能聊天机器人,该智能聊天机器人主要是供用户娱乐,他可以供用户娱乐休闲,他可以与用户讲故事、说笑话、说笑话、跟用户聊天,非常有趣。

涉及到知识点:

网络编程【okhttp】
json数据解析
Handler处理
在实现智能机器人聊天功能,在实现这个功能的过程中申请了一个图灵机器人的key,根据该key并通过异步访问网络获取机器人回复的信息,接着调用Handler将获取的信息发送到主线程,并通过JSON解析将获取的聊天数据解析成字符串显示到界面上。

二、项目结果
在这里插入图片描述

三、项目开发
1、需求开发
聊天机器人的主要功能就是和用户进行智能对话,如此智能的效果,涉及对用户语义理解,以及海量信息的精准搜索,我们没有办法做到,选择调用的是第三方公司提供的开发API。

图灵机器人:http://www.tuling123.com/member/robot/index.jhtm

模型:

2、开发环境介绍
开发工具:JDK8
API版本:Android API27
3、功能实现【聊天功能】
从需求出发进行分析,显然要实现聊天功能,我们需要一个界面:

界面上需要显示机器人及用户的头像,还需要一个编辑框和发送按钮以及显示聊天信息的界面。聊天界面使用了ListView控件。

用户输入聊天信息,信息需要保存且显示在聊天信息中,同时向图灵机器人发送聊天信息,图灵机器人做出响应,得到响应的聊天信息,保存并显示在聊天信息中。

3.1、申请机器人身份标识
课本255

3.2、搭建聊天界面布局
课本256-257

3.3、搭建聊天条目布局
1.创建聊天界面Item

2.放置姐买你控件

3.修改styles.xml

3.4封装聊天信息实体类
由于机器人与用户聊天的每天信息都会有消息的状态,消息的内容等属性,因此需要创建一个CHatBean类来存放消息的这些属性。

3.5、编写聊天列表适配器
由于聊天界面用了ListView控件显示聊天信息,因此需要一个数据适配器ChatAdapter对ListView控件进行数据适配。

1、创建ChatAdapter类

2、创建ViewHolder类

3.6、实现智能机器人通信
聊天界面主要用于展示机器人与用户的头像和聊天内容,当第一次进入智能机器人聊天应用时,首先程序会从string.xml文件中获取机器人需要发出的欢迎信息并显示再界面上,用户接受到欢迎信息后,会与机器人进行一些互动,发送一些信息,程序会将这些信息封装到一个ChatBean对象中并显示到界面上,同时会根据用户发送的聊天内容来从图灵机器人服务器上获取机器人的回复信息,并将获取的机器人回复信息通过Json解析显示到界面上。

在项目的RobotActivity中实现聊天界面的逻辑代码,具体步骤如下:

1,添加okhttp库

2,设置机器人欢迎信息

注意问题:

由于需要访问网络,需要对Android Studio模拟器联网进行设置
1.开启root权限
2.更改dns

由于图灵机器人v2版本不能使用get方式,所以需要按照图灵机器人接口说明中所写的,使用post方法
官方文档:https://www.kancloud.cn/turing/www-tuling123-com/718227

请求信息格式:

{
“reqType”:0,
“perception”: {
“inputText”: {
“text”: “讲个笑话”
}
},
“userInfo”: {
“apiKey”: “4fce0bc257c04a9f88f0a55ee179794d”,
“userId”: “fool”
}
}
1
2
3
4
5
6
7
8
9
10
11
12
响应信息格式:

{
“emotion”: {
“robotEmotion”: {
“a”: 0,
“d”: 0,
“emotionId”: 0,
“p”: 0
},
“userEmotion”: {
“a”: 0,
“d”: 0,
“emotionId”: 10300,
“p”: 0
}
},
“intent”: {
“actionName”: “”,
“code”: 10004,
“intentName”: “”
},
“results”: [
{
“groupType”: 1,
“resultType”: “text”,
“values”: {
“text”: “每次都是人家讲,欺负人家”
}
}
]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
解析json

为了解析JSON数据,Android SDK为开发者提供了org.json包,该包存放了解析JSON数据的类,其中最重要的两个类是JSONObject用于解析对象结构的JSON数据,JSONArray用于类解析对象结构的JSON对象

四、大致流程
在这里插入图片描述

五、代码
1、布局文件
activity_robot.xml

<?xml version="1.0" encoding="utf-8"?>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
chat_left_item.xml

<?xml version="1.0" encoding="utf-8"?>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
chatting_right_item.xml

<?xml version="1.0" encoding="utf-8"?>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2、ChatBean
package com.lsz.robot;

/**

  • 用于存放机器人和用户聊天的每条消息的状态,内容等属性。
    */
    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;
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    3、ChatAdapter
    package com.lsz.robot;

import android.content.Context;
import android.content.Intent;
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<ChatBean> chatBeanList;/*一个用于加载布局的系统服务,就是实例化与Layout XML文件对应的View对象,不能直接使用, 需要通过getLayoutInflater( )方法或getSystemService( )方法来获得与当前Context绑定的 LayoutInflater实例!*/
private LayoutInflater layoutInflater;//构造器
public ChatAdapter(List<ChatBean> chatBeanList, Context context) {this.chatBeanList = chatBeanList;layoutInflater = LayoutInflater.from(context);
}/**** @return 聊天数据列表的总数*/
@Override
public int getCount() {return chatBeanList.size();
}/**** @param* @return 返回对应item上的对象*/
@Override
public Object getItem(int position) {return chatBeanList.get(position);
}/*** @param position* @return  item对象的id*/
@Override
public long getItemId(int position) {return position;
}/*** 返回对应的视图* @param position* @param contentView* @param viewGroup* @return*/
@Override
public View getView(int position, View contentView, ViewGroup viewGroup) {//用来获取 Item 界面上的控件Holder holder = new Holder();// 判断当前的信息是发送的信息还是接受的信息,不同信息加载不同的viewif (chatBeanList.get(position).getState() == ChatBean.RECEIVE){// 加载左边布局,也就是机器人对应的布局信息/*public View inflate (int resource, ViewGroup root, boolean attachToRoot) 该方法的三个参数依次为:①要加载的布局对应的资源id②为该布局的外部再嵌套一层父布局,如果不需要的话,写null就可以了!③是否为加载的布局文件的最外层套一层root布局,不设置该参数的话,如果root不为null的话,则默认为true 如果root为null的话,attachToRoot就没有作用了! root不为null,attachToRoot为true的话,会在加载的布局文件最外层嵌套一层root布局; 为false的话,则root失去作用!简单理解就是:是否为加载的布局添加一个root的外层容器~!*/contentView = layoutInflater.inflate(R.layout.chatting_left_item,null);}else {// 加载右边的布局contentView = layoutInflater.inflate(R.layout.chatting_right_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;
}

// private Intent intent = new Intent();
//
/**
* 用来获取 Item 界面上的控件
*/
class Holder{
public TextView tv_chat_content; // 聊天内容
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
4、RobotActivity
package com.lsz.robot;

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.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**

  • 界面交互
    */
    public class RobotActivity extends AppCompatActivity {

    private ListView listView;

    //聊天列表适配器对象
    private ChatAdapter adapter;

    // 存放所有聊天数据的集合
    private List chatBeanList;

    //编辑文本框对象
    private EditText et_send_msg;

    //发送键对象
    private Button btn_send;

    //图灵机器人 接口地址 http://openapi.tuling123.com/openapi/api/v2 47.93.153.235
    private static final String WEB_SITE = “http://openapi.tuling123.com/openapi/api/v2”;
    private static final String KEY = “4fce0bc257c04a9f88f0a55ee1797”;

    // 发送的消息
    private String sendMsg;

    // 存储欢迎信息的数组
    private String[] welcome;

    //捕获事件的对象
    private MHandler mHandler;

    // 获取数据
    private static final int MSG_OK = 1;

    /**

    • onCreate()函数是在activity初始化的时候调用的,

    • 通常情况下,我们需要在onCreate()中调用setContentView(int)函数填充屏幕的UI,

    • 一般通过findViewById(int)返回xml中定义的视图或组件的ID

    • @param savedInstanceState
      */
      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_robot);
      chatBeanList = new ArrayList();
      mHandler = new MHandler();

      // 获取内置的欢迎信息[ 获取strings.xml文件中的欢迎信息,并将这些信息存放在数组welcome中 ]
      welcome = getResources().getStringArray(R.array.welcome);
      // 初始化界面控件
      initView();
      }

    /**

    • 初始化控件
      */
      public void initView() {

      //ListView允许用户通过上下滑动来将屏幕外的数据滚动到屏幕内,
      // 同时屏幕内原有的数据滚动出屏幕,从而显示更多的数据内容。
      listView = (ListView) findViewById(R.id.list);

      //编辑框
      et_send_msg = (EditText) findViewById(R.id.et_send_msg);

      //发送按钮
      btn_send = (Button) findViewById(R.id.btn_send);

      //在聊天视图框中,显示所有的聊天信息
      adapter = new ChatAdapter(chatBeanList, this);
      listView.setAdapter(adapter);

      //为发送按键添加一个点击监听器
      btn_send.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
      sendData(); // 点击发送按钮,发送信息
      }
      });

      //键盘监听:键盘按下enter键时发送消息
      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();
      }
      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_LONG).show();return;
      

      }
      et_send_msg.setText("");
      // 替换空格和换行
      sendMsg = sendMsg.replaceAll(" “, “”).replaceAll(”\n", “”).trim();
      ChatBean chatBean = new ChatBean();
      chatBean.setMessage(sendMsg);

      // SEND表示自己发送的消息 ===>1
      chatBean.setState(chatBean.SEND);
      chatBeanList.add(chatBean);

      // 更新 ListView 列表
      adapter.notifyDataSetChanged();

      // 从服务器获取机器人发送的消息
      getDataFromServer();
      System.out.println(“sendDate:”);
      }

    /**

    • 从服务端接收数据
      */
      public void getDataFromServer() {
      // 用来拼装 json 数据(json数据按照接口文档来书写)
      String startJson = “{“reqType”:0,“perception”:{“inputText”:{“text”:”";
      String endJson = “”}},“userInfo”:{“apiKey”:" + KEY + “,“userId”:”\n" +
      “682469”}}";

      // 封装请求体
      String json = startJson + sendMsg +
      endJson;
      //System.out.println(json);
      RequestBody body = RequestBody.create(
      MediaType.parse(“application/json;charset=utf-8”), json);

      //构建请求,传入url和请求参数(json形式)
      Request request = new Request.Builder()
      .url(WEB_SITE)
      .post(body)
      .build();

      OkHttpClient okHttpClient = new OkHttpClient();
      Call call = okHttpClient.newCall(request);
      // 开启异步线程访问网络
      call.enqueue(new Callback() {

       /*** 获取响应失败* @param call* @param e*/@Overridepublic void onFailure(Call call, IOException e) {
      

// System.out.println(“回调失败”);
e.printStackTrace();
}

        /*** 获取响应成功* @param call* @param response* @throws IOException*/@Overridepublic void onResponse(Call call, Response response) throws IOException {String res = response.body().string();Message message = new Message();message.what = MSG_OK;message.obj = res;mHandler.sendMessage(message);

// System.out.println(“Call回传”+res);
}
});
}

/*** 事件捕获*/
class MHandler extends Handler {@Overridepublic void dispatchMessage(Message msg) {super.dispatchMessage(msg);switch (msg.what) {//成功获取数据后,将消息对象转化成字符串进行解析case MSG_OK:if (msg.obj != null) {String vlResult = (String) msg.obj;parseData(vlResult);}break;}}
}/*** 解析服务器返回的数据* @param JsonData*/
private void parseData(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(“主人,你的网络不好哦”);
// }

    //解析成功更新界面try {JSONObject obj = new JSONObject(JsonData);System.out.println("obj:" + obj);int code = (int) new JSONObject(obj.get("intent").toString()).get("code");String content = obj.getJSONArray("results").getString(0);String s =new JSONObject( new JSONObject(content).get("values").toString()).getString("text");

// System.out.println(“content:” + s);

        // 更新界面updateView(code, s);} catch (JSONException e) {e.printStackTrace();showData("主人,你的网络不好哦");}
}private void showData(String message) {ChatBean chatBean = new ChatBean();chatBean.setMessage(message);// RECEIVE 表示机器人发送的信息chatBean.setState(ChatBean.RECEIVE);// 将机器人发送的信息添加奥chatBeanList集合中chatBeanList.add(chatBean);//更新聊天视图adapter.notifyDataSetChanged();
}private void updateView(int code, String content) {// code 有很多种类,可以参考官网switch (code) {case 4004:showData("主人,今天我累了,我要休息了,明天再来找我玩吧");break;case 40005:showData("主人,你说的是外星语吗?");break;case 40006:showData("主人,我今天要去约会哦,暂时不上班啦");break;case 40007:showData("主人,明天在和你耍啦,我生病了,呜呜......");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(RobotActivity.this, "再按一次退出智能聊天程序!",Toast.LENGTH_SHORT).show();exitTime = System.currentTimeMillis();} else {RobotActivity.this.finish();System.exit(0);}return true;}return super.onKeyDown(keyCode, event);
}

}

Android聊天机器人相关推荐

  1. 10分钟实现android聊天机器人

    Android开发,10分钟使用api,快速实现聊天机器人,功能很强大哦,集成十分十分简单.本例也模仿qq聊天气泡,实现起来也是很简单的 说明,不是单纯的内置聊天信息,机器人会根据您输入的信息,自动回 ...

  2. 手把手教你做Android聊天机器人

    我相信大家应该知道有款应用叫小黄鸡吧! 如果不知道,那你见过那种可以秒回复的聊天应用么? 如果仍然没看到!那你总见过可以迅速回复你的微信公共账吧! 如果仍然....亲出门左拐 好,不多说. 首先大家都 ...

  3. android气泡组件,Android 聊天气泡

    网上搜到的只有一篇是自定义的TextView,其使用比较麻烦,所以采用大众化的方法--使用9.png来实现. 这里主要介绍sdk tool的draw9patch.bat的使用. 这个bat执行文件打开 ...

  4. Android Studio实现一个智能聊天机器人

    项目目录 一.需求分析 1.业务需求分析 2.模型需求分析 3.界面需求分析 二.开发环境介绍 三.聊天功能业务实现 ✨1.申请机器人身份标识 2.搭建聊天界面布局 3.搭建聊天条目布局 4.封装聊天 ...

  5. 自己动手用Android和Xposed编写一个微信聊天机器人——《微信聊天精灵》实现关键词自动回复。

    出于爱好和需要,想着自己来编写一个微信聊天机器人,能实现以下功能: 能实时获取到微信聊天消息: 能进行文本自动回复: 能够设置关键词: 能够根据关键词匹配,进行内容回复: 能实现聊天消息云端备份: 已 ...

  6. Android图灵聊天机器人-薇尔莉特

    智能聊天机器人-图灵机器人项目说明 文章目录 智能聊天机器人-图灵机器人项目说明 1.项目介绍 2.项目用到的技术 3.项目的开发环境 4.开发步骤 1.首先编写主界面(activity_main.x ...

  7. Android智能聊天机器人的实现

    一 .概述 本博客主要介绍了使用android studio接入图灵机器人,实现智能聊天机器人的功能. 二.注册图灵机器人 进入图灵机器人官网,创建自己的图灵机器人 图灵机器人官网 点击机器人,进入机 ...

  8. Android之Android studio实现智能聊天机器人

    Android实现智能聊天机器人 最近在做项目中,突然来了灵感,要做一个聊天机器人.聊天机器人在很多大型App上都有使用,比如QQ群里的QQ小冰,淘宝京东等App上在没有人工客服之前会有机器人跟你聊天 ...

  9. 【NLP】创建强大聊天机器人的初学者指南

    作者 | Louis Teo 编译 | VK 来源 | Towards Data Science 你是否面临着太多来自客户的标准要求和问题,并且难以应对?你是否在寻找一种既不增加成本又扩大客户服务的方 ...

最新文章

  1. zabbix 小纪录
  2. SAP VLPOD 报错 - Update control of movement type is incorrect (entry 107 X X E B _ E) - 之对策
  3. Paul Rayner认为DDD和敏捷可以共存
  4. 【MCtalk】“互联网+”技术融合论坛
  5. python正则判断列表是否有元素,python – 从列表中删除正则表达式元素
  6. 微信小程序js数组初始化_微信小程序 数组(增,删,改,查)等操作实例详解...
  7. 读写锁分离的循环队列
  8. 远程调用python_远的解释|远的意思|汉典“远”字的基本解释
  9. 布丰投针java实现,MATLAB模拟布丰投针实验
  10. android widget 开发实例 : 桌面便签程序的实现具体解释和源代码 (上)
  11. envi查看灰度直方图_ENVI实习直方图匹配校正分类.doc
  12. matlab 神经网络训练 分类器,matlab神经网络分类器
  13. chrome出现Provisional headers are shown
  14. 磁盘/分区克隆:如何将硬盘数据快速迁移至新的硬盘?
  15. 手机电源键关不了屏幕_手机关机关不了,屏幕也划不了,怎么办
  16. lic文件用计算机程序打开,后缀名是lic的文件用什么软件打开?
  17. 二、关于做地图和如何做成mod
  18. ffmpeg实现视频和音频分离,并且将声音切片
  19. docker启动容器之后马上又自动关闭
  20. 用 Python 从 GFF3 格式文件中查找注释信息

热门文章

  1. xml报错:xml.etree.ElementTree.ParseError: not well-formed (invalid token)
  2. 用PaddlePaddle(飞浆)实现车牌识别
  3. 旋转数组(右旋转,js实现,unshift,splicec实现)
  4. springsecurity 不允许session并行登录_Spring Security 实战干货:实现自定义退出登录...
  5. 微型计算机二进制,微型计算机原理二进制十进制十六进制.docx
  6. cocos creator粒子不变色_隐秘的物理粒子系统与渲染 !Cocos Creator LiquidFun !
  7. 为什么微软账号被暂时停用_微软向Win10 20H2推出测试版更新KB4586853修复多种已知问题...
  8. 硬盘清零工具_WinHex使用方法与使用WinHex恢复硬盘实例
  9. linux 查找文件_LINUX常用命令全集
  10. python 字典由值找键_python字典怎么根据值返回键