238 lines
12 KiB
Java
Raw Normal View History

2024-05-08 19:14:44 +08:00
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());
}
});
}
}