android开发 聊天机器人简版

首先实现布局文件。


1.用户发出信息

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:paddingTop="30dp"
android:background="#f5f5f5"
android:layout_height="match_parent">

<TextView
android:id="@+id/textMessage"
android:layout_marginTop="20dp"
android:layout_width="200dp"
android:layout_height="60dp"
android:background="#95ec69"
android:layout_toStartOf="@id/imageAvatar"
/>
<ImageView
android:id="@+id/imageAvatar"
android:layout_width="70dp"
android:layout_height="59dp"
android:src="@drawable/img_4"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
/>
</RelativeLayout>

2.机器人回复消息

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="horizontal"
android:paddingTop="30dp"
android:background="#f5f5f5"
android:layout_height="match_parent">


<ImageView
android:id="@+id/imageAvatar"
android:layout_width="70dp"
android:layout_height="59dp"
android:src="@drawable/img_4" />

<TextView
android:id="@+id/textMessage"
android:layout_marginTop="20dp"
android:layout_width="200dp"
android:layout_height="60dp"
android:background="#ffffff"
android:text="你好,我是机器人小冰,现在可以陪你聊天啦!"
/>

</LinearLayout>

3.主页面布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#f5f5f5"
android:layout_height="match_parent">


<!-- 聊天列表 -->

<!-- 输入文本框 -->

<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@null"
android:dividerHeight="0dp"
android:stackFromBottom="true"
android:transcriptMode="alwaysScroll"
android:layout_marginBottom="90dp"/>

<LinearLayout
android:layout_width="match_parent"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:background="#07c160"
android:layout_height="80dp">

<!-- 发送按钮 -->
<EditText
android:id="@+id/editText"
android:layout_width="320dp"
android:layout_height="50dp"
android:layout_marginStart="8dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:background="#d7d7d7"
android:hint="请输入消息" />

<Button
android:id="@+id/buttonSend"
android:layout_width="80dp"
android:layout_marginTop="20dp"
android:layout_height="50dp"
android:layout_alignBottom="@id/editText"
android:text="发送"/>
</LinearLayout>


</RelativeLayout>

java代码

主页面MainActivity5 java代码

package com.example.androiddemo;

import android.os.Bundle;
import android.text.TextUtils;
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 com.google.gson.Gson;

import java.util.ArrayList;
import java.util.List;

public class MainActivity5 extends AppCompatActivity {
private HttpUtils httpUtils; // HttpUtils实例,用于网络请求
private String result; // 用于存储服务器响应的结果

// 定义消息列表和适配器
private List<Message> messageList = new ArrayList<>(); // 消息列表
private MessageAdapter adapter; // 消息适配器
private ListView listView; // 显示消息的ListView
private EditText editText; // 输入消息的EditText
private Button buttonSend; // 发送消息的Button

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main5);

// 初始化消息列表,添加初始消息
messageList.add(new Message("你好,我是机器人小冰,欢迎和我聊天!", false));

// 初始化视图组件
listView = findViewById(R.id.listView);
editText = findViewById(R.id.editText);
buttonSend = findViewById(R.id.buttonSend);

// 初始化HttpUtils实例
httpUtils = new HttpUtils();

// 设置适配器
adapter = new MessageAdapter(this, messageList);
listView.setAdapter(adapter);

// 设置发送按钮的点击事件
buttonSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendMessage(); // 调用发送消息的方法
}
});
}

// 发送消息的方法
private void sendMessage() {
String message = editText.getText().toString().trim(); // 获取输入框的文本并去除首尾空格
if (!message.isEmpty()) {
// 将用户消息添加到消息列表
messageList.add(new Message(message, true));
adapter.notifyDataSetChanged(); // 通知适配器数据已更改
listView.setSelection(adapter.getCount() - 1); // 滚动到列表的最后一行
editText.setText(""); // 清空输入框
parseData(message); // 解析用户输入的数据
} else {
// 如果输入框为空,显示提示信息
Toast.makeText(this, "请输入消息", Toast.LENGTH_SHORT).show();
}
}

// 解析服务器的返回信息
private void parseData(final String request) {
// 创建子线程进行网络请求
new Thread(new Runnable() {
@Override
public void run() {
result = httpUtils.submitPostData(HttpUtils.API_WEBSITE, request); // 获取服务器响应
runOnUiThread(new Runnable() {
@Override
public void run() {
if (TextUtils.isEmpty(result)) {
// 如果结果为空,显示提示信息
Toast.makeText(MainActivity5.this, "模拟器无网络!", Toast.LENGTH_SHORT).show();
} else {
try {
// 通过Gson将JSON字符串(result)解析成DataBean类的实例
DataBean dataBean = new Gson().fromJson(result, DataBean.class);
if (dataBean != null) {
// 获取状态码和回答内容
int code = dataBean.getResult();
String reply = dataBean.getContent();
// 更新视图
updateView(code, reply);
} else {
Toast.makeText(MainActivity5.this, "无法解析服务器响应", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Toast.makeText(MainActivity5.this, "解析响应时发生错误", Toast.LENGTH_SHORT).show();
}
}
}
});
}
}).start();
}

// 更新视图方法
private void updateView(int code, String reply) {
// 根据状态码和回复内容更新UI的逻辑
if (code == 0) {
// 状态码为0表示成功,将回复消息添加到消息列表
messageList.add(new Message(reply, false));
adapter.notifyDataSetChanged(); // 通知适配器数据已更改
listView.setSelection(adapter.getCount() - 1); // 滚动到列表的最后一行
} else {
// 如果状态码不为0,显示访问失败的提示信息
Toast.makeText(MainActivity5.this, "访问失败!", Toast.LENGTH_SHORT).show();
}
}

// DataBean类,用于解析JSON响应
public static class DataBean {
private int result; // 状态码
private String content; // 回复内容

public int getResult() {
return result; // 获取状态码
}

public void setResult(int result) {
this.result = result; // 设置状态码
}

public String getContent() {
return content; // 获取回复内容
}

public void setContent(String content) {
this.content = content; // 设置回复内容
}
}
}

网络请求类HttpUtils类

package com.example.androiddemo;

import android.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpUtils {

// API网址常量,替换为实际API地址
public static final String API_WEBSITE = "http://api.qingyunke.com/api.php?key=free&appid=0&msg=你好";

// 向指定URL提交数据的方法
public String submitPostData(String strUrlPath, String question) {
StringBuilder response = new StringBuilder(); // 用于存储服务器响应的字符串
HttpURLConnection connection = null; // HttpURLConnection对象,用于建立和管理HTTP连接
try {
// 将URL中的"你好"替换为用户输入的问题
String real_url = strUrlPath.replace("你好", question);
URL Url = new URL(real_url); // 创建URL对象
connection = (HttpURLConnection) Url.openConnection(); // 打开HTTP连接
connection.setRequestMethod("GET"); // 使用GET方法
connection.setConnectTimeout(2000); // 连接超时设置为2000毫秒(2秒)
connection.setReadTimeout(3000); // 读取超时设置为3000毫秒(3秒)
connection.setDoInput(true); // 允许输入流
// 获取响应码并检查是否成功
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { // 响应码为200表示成功
// 获取输入流以读取服务器的响应
InputStream in = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
// 按行读取响应内容
while ((line = reader.readLine()) != null) {
response.append(line); // 将每行内容添加到响应字符串中
}
} else {
// 如果响应码不是200,记录错误日志
Log.e("Error", "HTTP error code: " + responseCode);
return null; // 返回null表示失败
}

} catch (IOException e) {
// 捕获IO异常并记录错误日志
Log.e("Error", "IOException occurred", e);
e.printStackTrace();
return null; // 返回null表示失败
} catch (Exception e) {
// 捕获其他异常并记录错误日志
Log.e("Error", "Unexpected exception occurred", e);
e.printStackTrace();
return null; // 返回null表示失败
} finally {
// 在finally块中确保连接被断开
if (connection != null) {
connection.disconnect(); // 断开连接
Log.d("Debug", "Connection disconnected"); // 记录调试日志
}
}
// 返回响应字符串
return response.toString();
}
}

记录信息是谁发送的Message类

package com.example.androiddemo;
public class Message {
private String text;
private boolean isUser;

public Message(String text, boolean isUser) {
this.text = text;
this.isUser = isUser;
}

public String getText() {
return text;
}

public boolean isUser() {
return isUser;
}
}


消息列表适配器类MessageAdapter类

package com.example.androiddemo;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

// 自定义适配器类,用于将消息数据绑定到 ListView
public class MessageAdapter extends ArrayAdapter<Message> {

private LayoutInflater inflater; // 布局加载器,用于加载布局文件

// 构造方法
public MessageAdapter(Context context, List<Message> messages) {
super(context, 0, messages);
inflater = LayoutInflater.from(context); // 初始化布局加载器
}

// 重写 getView 方法,用于生成每一项的视图
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder; // 声明 ViewHolder
// 获取当前位置的消息对象
Message message = getItem(position);
// 如果 convertView 为空,表示需要创建新的视图
if(message.isUser())
{
// 加载 item_message 布局文件,并将其赋值给 convertView
convertView = inflater.inflate(R.layout.right, parent, false);
}
else {
// 加载 item_message 布局文件,并将其赋值给 convertView
convertView = inflater.inflate(R.layout.left, parent, false);
}

// 初始化 ViewHolder,并获取布局中的控件
viewHolder = new ViewHolder();
viewHolder.textMessage = convertView.findViewById(R.id.textMessage); // 消息文本视图
viewHolder.imageAvatar = convertView.findViewById(R.id.imageAvatar); // 头像视图


// 设置消息文本
viewHolder.textMessage.setText(message.getText());

// 根据消息是否是用户发送的,设置不同的头像
if (message.isUser()) {
viewHolder.imageAvatar.setImageResource(R.drawable.img_4); // 用户头像
} else {
viewHolder.imageAvatar.setImageResource(R.drawable.img_1); // 机器人头像
}

// 返回设置好的 convertView
return convertView;
}

// 静态内部类,用于缓存列表项中的控件
private static class ViewHolder {
TextView textMessage; // 消息文本视图
ImageView imageAvatar; // 头像视图
}
}

备注:

http://api.qingyunke.com/api.php?key=free&appid=0&msg=你好     是免费提供的聊天机器人api,直接用就可以了。“你好”是用户输入的问题,将他替换为用户自己输入的问题既可。
        需要在 AndroidManifest.xml清单文件中配置<application
    ...
    android:usesCleartextTraffic="true">
    ...
</application>        

因为该api是http协议的,不是https。因为安全权限问题,需要自己配置权限。不然会访问不了。

  • 23
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值