238 lines
12 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.bifan.txtreaderlib.ui;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.bifan.txtreaderlib.R;
import com.bifan.txtreaderlib.adapter.MessageAdapter;
import com.bifan.txtreaderlib.bean.ChatMessage_bmob;
import com.bifan.txtreaderlib.bean.ChatRequest;
import com.bifan.txtreaderlib.bean.ChatResponse;
import com.bifan.txtreaderlib.bean.Message;
import com.bifan.txtreaderlib.interfaces.ChatGPTService;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import cn.bmob.v3.Bmob;
import cn.bmob.v3.BmobQuery;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.FindListener;
import cn.bmob.v3.listener.SaveListener;
import okhttp3.OkHttpClient;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class ChatWithGptActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private MessageAdapter messageAdapter;
private EditText editTextMessage;
private TextView chatbot_title;
private Button buttonSend;
private String bookName = "";
private String userid="";
private ArrayList<Message> messageList = new ArrayList<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chatwithgpt);
Bmob.initialize(this, "8f9f1d1ea520b0ce4f84a6fa83a5f754");
if (getIntent() != null && getIntent().hasExtra("book_name")) {
bookName = getIntent().getStringExtra("book_name");
}
SharedPreferences sharedPreferences = getSharedPreferences("userinf", Context.MODE_PRIVATE);
String userIdFromPrefs = sharedPreferences.getString("user_id", "");
userid = userIdFromPrefs != null ? userIdFromPrefs : "";
recyclerView = findViewById(R.id.chatRecyclerView);
editTextMessage = findViewById(R.id.inputEditText);
buttonSend = findViewById(R.id.sendButton);
chatbot_title=findViewById(R.id.chatbot_title);
messageAdapter = new MessageAdapter(messageList);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(messageAdapter);
init();
buttonSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String text = editTextMessage.getText().toString();
if (!text.isEmpty()) {
messageList.add(new Message(text, 1)); // User message
messageAdapter.notifyItemInserted(messageList.size() - 1);
recyclerView.scrollToPosition(messageList.size() - 1);
editTextMessage.setText("");
sendMessageToChatGPT(text);
ChatMessage_bmob chatMessage_bmob=new ChatMessage_bmob(text,1,bookName,userid);
chatMessage_bmob.save(new SaveListener<String>() {
@Override
public void done(String objectId,BmobException e) {
if(e==null){
// toast("添加数据成功返回objectId为"+objectId);
}else{
//toast("创建数据失败:" + e.getMessage());
}
}
});
}
}
});
}
private void init(){
chatbot_title.setText(bookName);
BmobQuery<ChatMessage_bmob> bmobQuery = new BmobQuery<>();
bmobQuery.addWhereEqualTo("relatedBook", bookName);
bmobQuery.addWhereEqualTo("userid", userid);
bmobQuery.findObjects(new FindListener<ChatMessage_bmob>() {
@Override
public void done(List<ChatMessage_bmob> messages, BmobException e) {
if (e == null && messages != null) {
if (!messages.isEmpty()) {
for (ChatMessage_bmob item : messages) {
if (item.getContent() == null) {
String content = "出现未知错误!";
messageList.add(new Message(content, item.getIsuser()));
} else {
messageList.add(new Message(item.getContent(), item.getIsuser()));
}
}
} else {
// 如果没有消息,添加一条 bot 的欢迎消息
String welcomeMessage = "你好!我是你的阅读助手。我可以帮助你解答关于书籍的各种问题,比如内容概述、作者信息、主要主题和角色分析等。请随时向我提问,现在,你有什么关于《" + bookName + "》的问题吗?";
messageList.add(new Message(welcomeMessage, 0)); // 假设 0 表示系统或助手消息
ChatMessage_bmob chatMessage_bmob=new ChatMessage_bmob(welcomeMessage,0,bookName,userid);
chatMessage_bmob.save(new SaveListener<String>() {
@Override
public void done(String objectId,BmobException e) {
if(e==null){
// toast("添加数据成功返回objectId为"+objectId);
}else{
//toast("创建数据失败:" + e.getMessage());
}
}
});
}
messageAdapter.notifyDataSetChanged();
} else {
Log.e("BookInfo", "Error loading book info: " + (e != null ? e.getMessage() : ""));
}
}
});
}
/**
* 从数据库加载历史对话并构建消息列表
*/
private List<ChatRequest.Message> loadMessagesFromDatabase(String bookName, String userId) {
List<ChatRequest.Message> messages = new ArrayList<>();
BmobQuery<ChatMessage_bmob> bmobQuery = new BmobQuery<>();
bmobQuery.addWhereEqualTo("relatedBook", bookName);
bmobQuery.addWhereEqualTo("userid", userId);
bmobQuery.order("createdAt");
bmobQuery.setLimit(10); //设置上下文最多10条历史对话
bmobQuery.findObjects(new FindListener<ChatMessage_bmob>() {
@Override
public void done(List<ChatMessage_bmob> chatMessages, BmobException e) {
if (e == null && chatMessages != null && !chatMessages.isEmpty()) {
for (ChatMessage_bmob item : chatMessages) {
// 根据消息来源判断角色,假设 0 表示用户1 表示助手
String role = item.getIsuser() == 0 ? "user" : "assistant";
messages.add(new ChatRequest.Message(role, item.getContent()));
Log.d("test",item.getContent());
}
} else {
Log.e("BookInfo", "Error loading book info: " + (e != null ? e.getMessage() : "No error details."));
}
}
});
return messages;
}
private void sendMessageToChatGPT(String messageText) {
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.build();
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.baseUrl("https://api.openai-ch.top/")
.addConverterFactory(GsonConverterFactory.create())
.build();
ChatGPTService service = retrofit.create(ChatGPTService.class);
List<ChatRequest.Message> messages = new ArrayList<>();
String prompt = "你好!我是你的阅读助手。我可以帮助你解答关于书籍的各种问题,比如内容概述、作者信息、主要主题和角色分析等。请随时向我提问,我会用中文简体来回答你。现在,你有什么关于《" + bookName + "》的问题吗?";
messages.add(new ChatRequest.Message("system", prompt));
// messages.add(new ChatRequest.Message("system", "You are a reading assistant. The user will ask you questions about the book '" + bookName + "'."));
messages.addAll(loadMessagesFromDatabase(bookName, userid));
messages.add(new ChatRequest.Message("user", messageText)); // 添加用户消息
ChatRequest request = new ChatRequest(messages); // 使用消息列表创建请求
request.setModel("gpt-4-turbo"); // 根据需要选择不同的模型
request.setMaxTokens(200); // 设置最大 token 数,根据需要调整
request.setTemperature(0.5); // 设置适当的温度
service.postMessage(request).enqueue(new Callback<ChatResponse>() {
@Override
public void onResponse(Call<ChatResponse> call, Response<ChatResponse> response) {
if (response.isSuccessful() && response.body() != null) {
ChatResponse chatResponse = response.body();
if (chatResponse.choices != null && !chatResponse.choices.isEmpty()) {
ChatResponse.Message message = chatResponse.choices.get(0).message;
String reply = message.content; // 这是从 GPT-3.5 响应中提取的内容
runOnUiThread(() -> {
messageList.add(new Message(reply, 0));
messageAdapter.notifyItemInserted(messageList.size() - 1);
recyclerView.scrollToPosition(messageList.size() - 1);
ChatMessage_bmob chatMessage_bmob = new ChatMessage_bmob(reply, 0, bookName, userid);
chatMessage_bmob.save(new SaveListener<String>() {
@Override
public void done(String objectId, BmobException e) {
if (e == null) {
// toast("添加数据成功返回objectId为" + objectId);
} else {
// toast("创建数据失败:" + e.getMessage());
}
}
});
});
}
} else {
try {
String errorBody = response.errorBody() != null ? response.errorBody().string() : "Unknown error";
Log.e("ChatGPT", "Error: " + errorBody);
} catch (IOException e) {
Log.e("ChatGPT", "Error reading error body", e);
}
}
}
@Override
public void onFailure(Call<ChatResponse> call, Throwable t) {
Log.e("ChatGPT", "Failure: " + t.getMessage());
}
});
}
}