拥有一个听自己话的女友,是每个程序员的梦想。在我和她的世界里,她永远都是那么可爱乖巧,不会嫌弃我们这些码农,在累的时候,她会安慰我们,在不开心的时候,她会给我们讲故事,永远忠诚幽默。
效果如下:
闲话少说,接下来就带领大家一步一步制作这样的虚拟女友。
一、创建应用
打开网址: https://www.bmobapp.com/
注册登录进去之后,先进行实名认证(实名认证使用支付宝进行实名认证),然后创建应用,获取application id和rest api key。
如下图所示:
二、创建Android工程
这里选择创建一个java语言的Android工程。
三、创建资源文件
主页面布局文件(文件名:res/layout/activity_main.xml)如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"tools:context=".MainActivity"android:layout_width="match_parent"android:layout_height="match_parent"><androidx.recyclerview.widget.RecyclerViewandroid:layout_above="@id/bottom_layout"android:id="@+id/msg_recycler_view"android:layout_width="match_parent"android:layout_height="match_parent"/><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="80dp"android:padding="8dp"android:layout_alignParentBottom="true"android:id="@+id/bottom_layout"><EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"android:id="@+id/message_edit_text"android:background="@drawable/rounded_corner"android:layout_toLeftOf="@id/send_bt"android:hint="输入问题"android:padding="16dp"/><ImageButtonandroid:layout_width="48dp"android:layout_height="48dp"android:id="@+id/send_bt"android:layout_alignParentEnd="true"android:layout_centerInParent="true"android:padding="8dp"android:src="@drawable/baseline_send_24"android:background="?attr/selectableItemBackgroundBorderless"android:layout_marginStart="10dp"/></RelativeLayout></RelativeLayout>
聊天组件资源文件(文件名:res/layout/chat_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="8dp"><LinearLayoutandroid:id="@+id/left_chat_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginEnd="30dp"android:background="@drawable/rounded_corner"android:backgroundTint="#1E88E5"android:padding="15dp"><TextViewandroid:id="@+id/left_chat_text_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text=""android:textColor="@color/white"android:textSize="18sp" /></LinearLayout><LinearLayoutandroid:layout_alignParentEnd="true"android:id="@+id/right_chat_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="30dp"android:background="@drawable/rounded_corner"android:backgroundTint="#7cb342"android:padding="15dp"><TextViewandroid:id="@+id/right_chat_text_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text=""android:textColor="@color/white"android:textSize="18sp" /></LinearLayout>
</RelativeLayout>
发送按钮资源文件(文件名:res/drawable/baseline_send_24.xml)如下:
<vector android:autoMirrored="true" android:height="48dp"android:tint="#1A95BB" android:viewportHeight="24"android:viewportWidth="24" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android"><path android:fillColor="@android:color/white" android:pathData="M2.01,21L23,12 2.01,3 2,10l15,2 -15,2z"/>
</vector>
圆角资源文件(文件名:res/drawable/rounded_corner.xml)如下:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><corners android:radius="10dp"/><stroke android:width="1dp"/><solid android:color="@color/white"/></shape>
四、导入Jar包
从Github中下载jar包(Libs文件夹下)和so包(JniLibs文件夹下),下载地址:Bmob-Android-AI/app/src/main at main · bmob/Bmob-Android-AI · GitHubBmob安卓AI示例. Contribute to bmob/Bmob-Android-AI development by creating an account on GitHub.https://github.com/bmob/Bmob-Android-AI/tree/main/app/src/main
下载之后,在自己的工程中相应创建同样的文件夹,并把对应的jar包和so包放进去。
五、新增依赖
修改build.gradle文件里面的dependencies节点,新增内容如下:
dependencies {implementation fileTree(include: ['*.jar'], dir: 'libs')implementation 'io.reactivex.rxjava2:rxjava:2.2.8'implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'implementation 'com.squareup.okhttp3:okhttp:4.7.2'implementation 'com.squareup.okio:okio:2.2.2'implementation 'com.google.code.gson:gson:2.8.5'implementation 'androidx.recyclerview:recyclerview:1.3.0'implementation files('src\\main\\Libs\\BmobSDK_3.9.0.jar')
}
六、创建Application子类
新建一个类,名为BmobApp,继承自Application类,代码如下:
import android.app.Application;import cn.bmob.v3.Bmob;public class BmobApp extends Application {@Overridepublic void onCreate() {super.onCreate();//初始化Bmob.initialize(this,"第一步获取的application id内容");}
}
七、新增聊天内容对象类
新建一个类,名为 Message,代码如下:
/*** 聊天内容类*/
public class Message {public static String SEND_BY_ME="me";public static String SEND_BY_BOT="bot";String message;/*** 获取聊天内容* @return*/public String getMessage() {return message;}/*** 设置聊天内容* @param message*/public void setMessage(String message) {this.message = message;}/*** 获取发送者* @return*/public String getSendBy() {return sendBy;}/*** 设置发送者* @param sendBy*/public void setSendBy(String sendBy) {this.sendBy = sendBy;}/*** 发送者*/String sendBy;/*** 聊天内容的构造函数* @param message 聊天内容* @param sendBy 发送者*/public Message(String message, String sendBy) {this.message = message;this.sendBy = sendBy;}
}
八、新增RecycleView适配器的子类
新增一个类,名字为 MessageAdapter,代码如下:
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;import java.util.List;/*** 聊天内容的适配器类*/
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MyViewHolder> {List<Message> messageList;public MessageAdapter(List<Message> messageList) {this.messageList = messageList;}@NonNull@Overridepublic MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View chatView = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_item,null);MyViewHolder myViewHolder = new MyViewHolder(chatView);return myViewHolder;}@Overridepublic void onBindViewHolder(@NonNull MyViewHolder holder, int position) {Message message = messageList.get(position);if(message.getSendBy().equals(Message.SEND_BY_ME)){holder.leftChatView.setVisibility(View.GONE);holder.rightChatView.setVisibility(View.VISIBLE);holder.rightTextView.setText(message.getMessage());}else{holder.rightChatView.setVisibility(View.GONE);holder.leftChatView.setVisibility(View.VISIBLE);holder.leftTextView.setText(message.getMessage());}}@Overridepublic int getItemCount() {return messageList.size();}public class MyViewHolder extends RecyclerView.ViewHolder{LinearLayout leftChatView,rightChatView;TextView leftTextView,rightTextView;public MyViewHolder(@NonNull View itemView) {super(itemView);leftChatView = itemView.findViewById(R.id.left_chat_view);rightChatView = itemView.findViewById(R.id.right_chat_view);leftTextView = itemView.findViewById(R.id.left_chat_text_view);rightTextView = itemView.findViewById(R.id.right_chat_text_view);}}
}
九、修改配置文件
修改AndroidManifest.xml配置文件,添加权限和application的名字。
新增权限如下:
<!--允许联网 --><uses-permission android:name="android.permission.INTERNET" /><!--获取GSM(2g)、WCDMA(联通3g)等网络状态的信息 --><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><!--获取wifi网络状态的信息 --><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
application节点内新增android:name,代码如下:
android:name=".BmobApp"
application节点内新增provider节点,代码如下:
<application><providerandroid:name="cn.bmob.v3.util.BmobContentProvider"android:authorities="你自己的应用包名.BmobContentProvider"></provider>
</application>
这里要改为你自己的应用包名。
十、修改主页面代码
修改MAinActivity类,代码如下:
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import java.util.ArrayList;
import java.util.List;
import cn.bmob.v3.ai.BmobAI;
import cn.bmob.v3.ai.ChatMessageListener;public class MainActivity extends AppCompatActivity {RecyclerView recyclerView;EditText messageEditText;ImageButton sendButton;List<Message> messageList;MessageAdapter messageAdapter;BmobAI bmobAI;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//创建Bmob AI实例bmobAI = new BmobAI();//初始化AI内容问答存储messageList = new ArrayList<>();recyclerView = findViewById(R.id.msg_recycler_view);messageEditText = findViewById(R.id.message_edit_text);sendButton = findViewById(R.id.send_bt);messageAdapter = new MessageAdapter(messageList);recyclerView.setAdapter(messageAdapter);LinearLayoutManager llm = new LinearLayoutManager(this);llm.setStackFromEnd(true);recyclerView.setLayoutManager(llm);bmobAI.setPrompt("你叫琪琪,是我的女朋友,年轻漂亮贴心,说话也很幽默,接下来的每一个回复,你都要叫我宝贝");//点击发送提问到AI服务器的按钮sendButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {sendButton.setEnabled(false);//获取问题String quesion = messageEditText.getText().toString().trim();if(quesion.isEmpty() || quesion.trim()=="")return;//连接AI服务器(这个代码为了防止AI连接中断)bmobAI.Connect();//显示问题addToChat(quesion,Message.SEND_BY_ME);messageEditText.setText("");//发送内容到AI中bmobAI.Chat(quesion, "test_user",new ChatMessageListener() {@Overridepublic void onMessage(String s) {//消息流的形式返回AI的结果addToLastMessage(s);Log.d("ai",s);}@Overridepublic void onFinish(String s) {//一次性返回全部结果,这个方法需要等待一段时间,友好性较差//addToChat(s,Message.SEND_BY_BOT);sendButton.setEnabled(true);}@Overridepublic void onClose() {//连接关闭了Log.d("ai","close");sendButton.setEnabled(true);}});}});}/*** 支持流的形式呈现内容到界面* @param s*/public void addToLastMessage(String s){runOnUiThread(new Runnable() {@Overridepublic void run() {if(messageList.size()<=0) return;Message message = messageList.get(messageList.size()-1);if(message.sendBy==Message.SEND_BY_ME){Message newmessage = new Message(s,Message.SEND_BY_BOT);messageList.add(newmessage);messageAdapter.notifyDataSetChanged();recyclerView.smoothScrollToPosition(messageAdapter.getItemCount());}else{message.setMessage(message.getMessage() + s);messageAdapter.notifyDataSetChanged();recyclerView.smoothScrollToPosition(messageAdapter.getItemCount());}}});}/*** 一次性将全部内容呈现到界面* @param message* @param sendBy*/void addToChat(String message,String sendBy){runOnUiThread(new Runnable() {@Overridepublic void run() {messageList.add(new Message(message,sendBy));messageAdapter.notifyDataSetChanged();recyclerView.smoothScrollToPosition(messageAdapter.getItemCount());}});}
}
我们可以看到,最重要的一点就是,BmobAI.setPrompt方法,你可以设置一些你想要的调教词进去,做出各种有趣的产品出来。
最后的尾声
最后放出整个项目的源代码给大家:
https://www.bmobapp.com/欢迎大家私聊(wechat: xiaowon12 )AI改变生活的各种想法。