我们已经看到在Android中使用聊天机器人来回答用户最常见的问题。在本文中,我们将研究Android中Firebase ML Kit智能答复的实现。 Firebase ML Kit智能答复用于对使用Firebase ML Kit的用户提出的问题提供智能答复。
我们将在本文中构建什么?
我们将构建一个简单的应用程序,在该应用程序中,我们将创建一个类似于聊天的界面,用户将在该界面中将其查询发布到聊天框中,并根据用户的查询来查看Firebase ML Kit中的消息。下面提供了一个示例视频,以使您对我们在本文中将要做的事情有个大概的了解。注意,我们将使用Java语言实现该项目。
分步实施
步骤1:创建一个新项目
要在Android Studio中创建新项目,请参阅如何在Android Studio中创建/启动新项目。请注意,选择Java作为编程语言。
第2步:将您的应用连接到Firebase
在Android Studio中创建新项目后,将您的应用连接到Firebase。用于将您的应用程序连接到Firebase。导航到顶部栏上的“工具”。之后,单击Firebase。右侧将打开一个新窗口。在该窗口中,单击Firebase ML,然后在Android中单击“使用Firebase ML工具包”。您可以在屏幕截图下方看到该选项。
在下一个屏幕上单击此选项后,单击“连接到Firebase”选项以将您的应用程序连接到Firebase。
步骤3:添加语言翻译的依赖关系到build.gradle文件
导航到Gradle脚本> build.gradle(Module:app)并将以下依赖项添加到“依赖项”部分。
// dependency for firebase core.
implementation’com.google.firebase:firebase-core:15.0.2′
// Firebase ML dependency
implementation ‘com.google.firebase:firebase-ml-vision:24.0.3’
// dependancy for smart reply
implementation ‘com.google.firebase:firebase-ml-natural-language-smart-reply-model:20.0.7’
在相同的Gradle文件中。在android部分中添加以下代码。
aaptOptions {
noCompress “tflite”
}
现在,同步您的项目,让我们着手实施Firebase ML Kit智能答复。
步骤4:使用activity_main.xml文件
导航到应用程序> res>布局> activity_main.xml,然后将以下代码添加到该文件中。以下是activity_main.xml文件的代码。
XML
Java
public class ChatMsgModal {
// variable for our string and int for a type of message.
// type is to use weather the message in our recycler
// view is from user or from FIrebase ML kit.
private String message;
private int type;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public ChatMsgModal(String message, int type) {
this.message = message;
this.type = type;
}
}
XML
Java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class ChatRVAdapter extends RecyclerView.Adapter {
// variable for context and array list.
private Context context;
private ArrayList chatMsgModalArrayList;
// create a constructor for our context and array list.
public ChatRVAdapter(Context context, ArrayList chatMsgModalArrayList) {
this.context = context;
this.chatMsgModalArrayList = chatMsgModalArrayList;
}
@NonNull
@Override
public ChatRVAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// inside on create view holder method we are inflating our layout file which we created.
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.msg_rv_item, parent, false);
return new ChatRVAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ChatRVAdapter.ViewHolder holder, int position) {
ChatMsgModal modal = chatMsgModalArrayList.get(position);
if (modal.getType() == 0) {
// when we get type as 0 then the
// message will be of user type.
holder.msgTV.setText(modal.getMessage());
} else {
// other than this condition we will display
// the text background color and text color.
holder.msgTV.setText(modal.getMessage());
holder.msgCV.setCardBackgroundColor(context.getResources().getColor(R.color.purple_200));
holder.msgTV.setTextColor(context.getResources().getColor(R.color.white));
}
}
@Override
public int getItemCount() {
// on below line returning
// the size of our array list.
return chatMsgModalArrayList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
// creating variables for our
// card view and text view.
private TextView msgTV;
private CardView msgCV;
public ViewHolder(@NonNull View itemView) {
super(itemView);
// initializing variables for our text view and card view.
msgTV = itemView.findViewById(R.id.idTVMessage);
msgCV = itemView.findViewById(R.id.idCVMessage);
}
}
}
Java
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.firebase.ml.naturallanguage.FirebaseNaturalLanguage;
import com.google.firebase.ml.naturallanguage.smartreply.FirebaseSmartReply;
import com.google.firebase.ml.naturallanguage.smartreply.FirebaseTextMessage;
import com.google.firebase.ml.naturallanguage.smartreply.SmartReplySuggestionResult;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
// on below line we are creating
// a list with Firebase Text Message.
List messageList;
// on below line we are creating variables for
// our edittext, recycler view, floating action button,
// array list for storing our message
// and creating a variable for our adapter class.
private EditText userMsgEdt;
private RecyclerView msgRV;
private FloatingActionButton sendFAB;
private ArrayList chatMsgModalArrayList;
private ChatRVAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initializing all our variables.
userMsgEdt = findViewById(R.id.idEdtUserMsg);
msgRV = findViewById(R.id.idRVMessage);
sendFAB = findViewById(R.id.idBtnFAB);
// initializing our array list.
messageList = new ArrayList<>();
chatMsgModalArrayList = new ArrayList<>();
// initializing our adapter.
adapter = new ChatRVAdapter(MainActivity.this, chatMsgModalArrayList);
// layout manager for our recycler view.
LinearLayoutManager manager = new LinearLayoutManager(MainActivity.this);
// setting layout manager
// for our recycler view.
msgRV.setLayoutManager(manager);
// setting adapter to our recycler view.
msgRV.setAdapter(adapter);
// adding on click listener for our floating action button
sendFAB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// validating if the edit text is empty or not.
if (TextUtils.isEmpty(userMsgEdt.getText().toString())) {
Toast.makeText(MainActivity.this, "Please enter your message..", Toast.LENGTH_SHORT).show();
return;
}
// calling a method to send our message
// and getting the response.
sendMessage();
userMsgEdt.setText("");
}
});
}
private void sendMessage() {
// on below line we are creating a variable for our Firebase text message
// and passing our user input message to it along with time.
FirebaseTextMessage message = FirebaseTextMessage.createForRemoteUser(
userMsgEdt.getText().toString(), // Content of the message
System.currentTimeMillis(), // Time at which the message was sent
"uid" // This has to be unique for every other person involved
// in the chat who is not your user
);
// on below line we are adding
// our message to our message list.
messageList.add(message);
// on below line we are adding our edit text field
// value to our array list and setting type as 0.
// as we are using type as 0 for our user message
// and 1 for our message from Firebase.
chatMsgModalArrayList.add(new ChatMsgModal(userMsgEdt.getText().toString(), 0));
// on below line we are calling a method
// to notify data change in adapter.
adapter.notifyDataSetChanged();
// on below line we are creating a variable for our Firebase
// smart reply and getting instance of it.
FirebaseSmartReply smartReply = FirebaseNaturalLanguage.getInstance().getSmartReply();
// on below line we are calling a method to suggest reply for our user message.
smartReply.suggestReplies(messageList).addOnSuccessListener(new OnSuccessListener() {
@Override
public void onSuccess(SmartReplySuggestionResult smartReplySuggestionResult) {
// inside on success listener method we are checking if the language is not supported.
if (smartReplySuggestionResult.getStatus() == SmartReplySuggestionResult.STATUS_NOT_SUPPORTED_LANGUAGE) {
// displaying toast message if the language is not supported.
Toast.makeText(MainActivity.this, "Language not supported..", Toast.LENGTH_SHORT).show();
} else if (smartReplySuggestionResult.getStatus() == SmartReplySuggestionResult.STATUS_SUCCESS) {
// if we get a successful status message.
// we are adding that message to our
// array list and notifying our adapter
// that data has been changed.
chatMsgModalArrayList.add(new ChatMsgModal(smartReplySuggestionResult.getSuggestions().get(0).getText(), 1));
adapter.notifyDataSetChanged();
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// inside on failure method we are displaying a toast message
Toast.makeText(MainActivity.this, "Fail to get data.." + e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
第5步:创建用于存储数据的模式类
当我们在RecyclerView中显示所有数据时。因此,我们必须将这些数据存储在模式类中。要创建模式类,请导航至应用程序> Java >应用程序的包名称>右键单击它>新建> Java类,并将其命名为ChatMsgModal,然后将以下代码添加到其中。在代码内部添加了注释,以更详细地了解代码。
Java
public class ChatMsgModal {
// variable for our string and int for a type of message.
// type is to use weather the message in our recycler
// view is from user or from FIrebase ML kit.
private String message;
private int type;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public ChatMsgModal(String message, int type) {
this.message = message;
this.type = type;
}
}
步骤6:为消息的每个项目创建一个布局文件
导航到应用程序> res>布局>右键单击它>新建>布局资源文件,并将其命名为msg_rv_item,然后将以下代码添加到其中。
XML格式
步骤7:创建用于显示此数据的适配器类
导航到应用程序> Java >应用程序的程序包名称>右键单击它>新建> Java类,并将其命名为ChatRVAdapter,然后将以下代码添加到其中。
Java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class ChatRVAdapter extends RecyclerView.Adapter {
// variable for context and array list.
private Context context;
private ArrayList chatMsgModalArrayList;
// create a constructor for our context and array list.
public ChatRVAdapter(Context context, ArrayList chatMsgModalArrayList) {
this.context = context;
this.chatMsgModalArrayList = chatMsgModalArrayList;
}
@NonNull
@Override
public ChatRVAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// inside on create view holder method we are inflating our layout file which we created.
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.msg_rv_item, parent, false);
return new ChatRVAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ChatRVAdapter.ViewHolder holder, int position) {
ChatMsgModal modal = chatMsgModalArrayList.get(position);
if (modal.getType() == 0) {
// when we get type as 0 then the
// message will be of user type.
holder.msgTV.setText(modal.getMessage());
} else {
// other than this condition we will display
// the text background color and text color.
holder.msgTV.setText(modal.getMessage());
holder.msgCV.setCardBackgroundColor(context.getResources().getColor(R.color.purple_200));
holder.msgTV.setTextColor(context.getResources().getColor(R.color.white));
}
}
@Override
public int getItemCount() {
// on below line returning
// the size of our array list.
return chatMsgModalArrayList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
// creating variables for our
// card view and text view.
private TextView msgTV;
private CardView msgCV;
public ViewHolder(@NonNull View itemView) {
super(itemView);
// initializing variables for our text view and card view.
msgTV = itemView.findViewById(R.id.idTVMessage);
msgCV = itemView.findViewById(R.id.idCVMessage);
}
}
}
步骤8:使用MainActivity。 Java文件
转到MainActivity。 Java文件并参考以下代码。下面是MainActivity的代码。 Java文件。在代码内部添加了注释,以更详细地了解代码。
Java
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.firebase.ml.naturallanguage.FirebaseNaturalLanguage;
import com.google.firebase.ml.naturallanguage.smartreply.FirebaseSmartReply;
import com.google.firebase.ml.naturallanguage.smartreply.FirebaseTextMessage;
import com.google.firebase.ml.naturallanguage.smartreply.SmartReplySuggestionResult;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
// on below line we are creating
// a list with Firebase Text Message.
List messageList;
// on below line we are creating variables for
// our edittext, recycler view, floating action button,
// array list for storing our message
// and creating a variable for our adapter class.
private EditText userMsgEdt;
private RecyclerView msgRV;
private FloatingActionButton sendFAB;
private ArrayList chatMsgModalArrayList;
private ChatRVAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initializing all our variables.
userMsgEdt = findViewById(R.id.idEdtUserMsg);
msgRV = findViewById(R.id.idRVMessage);
sendFAB = findViewById(R.id.idBtnFAB);
// initializing our array list.
messageList = new ArrayList<>();
chatMsgModalArrayList = new ArrayList<>();
// initializing our adapter.
adapter = new ChatRVAdapter(MainActivity.this, chatMsgModalArrayList);
// layout manager for our recycler view.
LinearLayoutManager manager = new LinearLayoutManager(MainActivity.this);
// setting layout manager
// for our recycler view.
msgRV.setLayoutManager(manager);
// setting adapter to our recycler view.
msgRV.setAdapter(adapter);
// adding on click listener for our floating action button
sendFAB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// validating if the edit text is empty or not.
if (TextUtils.isEmpty(userMsgEdt.getText().toString())) {
Toast.makeText(MainActivity.this, "Please enter your message..", Toast.LENGTH_SHORT).show();
return;
}
// calling a method to send our message
// and getting the response.
sendMessage();
userMsgEdt.setText("");
}
});
}
private void sendMessage() {
// on below line we are creating a variable for our Firebase text message
// and passing our user input message to it along with time.
FirebaseTextMessage message = FirebaseTextMessage.createForRemoteUser(
userMsgEdt.getText().toString(), // Content of the message
System.currentTimeMillis(), // Time at which the message was sent
"uid" // This has to be unique for every other person involved
// in the chat who is not your user
);
// on below line we are adding
// our message to our message list.
messageList.add(message);
// on below line we are adding our edit text field
// value to our array list and setting type as 0.
// as we are using type as 0 for our user message
// and 1 for our message from Firebase.
chatMsgModalArrayList.add(new ChatMsgModal(userMsgEdt.getText().toString(), 0));
// on below line we are calling a method
// to notify data change in adapter.
adapter.notifyDataSetChanged();
// on below line we are creating a variable for our Firebase
// smart reply and getting instance of it.
FirebaseSmartReply smartReply = FirebaseNaturalLanguage.getInstance().getSmartReply();
// on below line we are calling a method to suggest reply for our user message.
smartReply.suggestReplies(messageList).addOnSuccessListener(new OnSuccessListener() {
@Override
public void onSuccess(SmartReplySuggestionResult smartReplySuggestionResult) {
// inside on success listener method we are checking if the language is not supported.
if (smartReplySuggestionResult.getStatus() == SmartReplySuggestionResult.STATUS_NOT_SUPPORTED_LANGUAGE) {
// displaying toast message if the language is not supported.
Toast.makeText(MainActivity.this, "Language not supported..", Toast.LENGTH_SHORT).show();
} else if (smartReplySuggestionResult.getStatus() == SmartReplySuggestionResult.STATUS_SUCCESS) {
// if we get a successful status message.
// we are adding that message to our
// array list and notifying our adapter
// that data has been changed.
chatMsgModalArrayList.add(new ChatMsgModal(smartReplySuggestionResult.getSuggestions().get(0).getText(), 1));
adapter.notifyDataSetChanged();
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// inside on failure method we are displaying a toast message
Toast.makeText(MainActivity.this, "Fail to get data.." + e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
现在运行您的应用程序,并查看该应用程序的输出。
输出:
Note: You will get a certain delay in reply from Firebase for the first time. Also, the response from Firebase will not be accurate as this response are send from the Firebase ML kit model.