聊天机器人,分为2个部分,第一个部分是上面的主体部分是聊天的部分。
主布局文件activity_main.xmxl
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- listView用来放聊天的记录 -->
<ListView
android:id="@+id/lv_list"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:divider="@null"
android:layout_weight="1" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bottom_bar"
android:gravity="center"
android:orientation="vertical" >
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/btn_selector"
android:onClick="startListen"
android:text="点击开始聊天"
android:textColor="#000"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
ListView来表示,其中没说话一次会有一次回复,将这个对话和回复设置为一个item,item中自己的部分是识别的文字部分,robot的回复有文字或者图片,当回复的为其中的一个的时候让另一个不可见。
list_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" >
<TextView
android:id="@+id/tv_ask"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_margin="5dp"
android:background="@drawable/asker_bubble"
android:gravity="center"
android:text="AAA"
android:textColor="#000"
android:textSize="16sp" />
<LinearLayout
android:id="@+id/ll_answer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_ask"
android:layout_margin="5dp"
android:background="@drawable/answer_bubble"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_answer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="BBB"
android:textColor="#000"
android:textSize="16sp" />
<ImageView
android:id="@+id/iv_pic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/m"
android:visibility="gone" />
</LinearLayout>
</RelativeLayout>
将item,想聊天的信息,封装成bean,chatBean.java,数据的保存是以jaon的形式保存的因此使用的时候需要解析json数据
package com.ldw.robot;
/*
* 聊天的信息
*/
public class ChatBean {
public String text;// 内容
public boolean isAsker;// true表示提问者,否则是回答者
public int imageId = -1;// 图片id
public ChatBean(String text, boolean isAsker, int imageId) {
this.text = text;
this.isAsker = isAsker;
this.imageId = imageId;
}
}
语音信息的json的保存
package com.ldw.robot;
import java.util.ArrayList;
/*
* 语音信息的封装json的封装
*/
public class VoiceBean {
public ArrayList<WSBean> ws;
public class WSBean {
public ArrayList<CWBean> cw;
}
public class CWBean {
public String w;
}
}
逻辑代码,初始化listView,然后解析json,将解析的json保存在listView,更新数据
package com.ldw.robot;
import java.util.ArrayList;
import java.util.Random;
import com.google.gson.Gson;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;
import com.ldw.robot.VoiceBean.WSBean;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends Activity {
private ListView lv_list;
private ArrayList<ChatBean> mChatList = new ArrayList<ChatBean>();//聊天的信息
private ChatAdapter mAdapter;
private String[] mMMAnswers = new String[] { "约吗?", "讨厌!", "不要再要了!",
"这是最后一张了!", "漂亮吧?" };
private int[] mMMImageIDs = new int[] { R.drawable.p1, R.drawable.p2,
R.drawable.p3, R.drawable.p4 };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv_list = (ListView) findViewById(R.id.lv_list);
mAdapter = new ChatAdapter();
lv_list.setAdapter(mAdapter);
// 初始化语音引擎
SpeechUtility.createUtility(this, SpeechConstant.APPID + "=54b8bca3");
}
//开始监听语音
private void startListen(View v){
RecognizerDialog iatDialog = new RecognizerDialog(this, null);
// 2.设置听写参数,详见《科大讯飞MSC API手册(Android)》SpeechConstant类
iatDialog.setParameter(SpeechConstant.DOMAIN, "iat");
iatDialog.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
iatDialog.setParameter(SpeechConstant.ACCENT, "mandarin");
iatDialog.setListener(recognizerDialogListener);
iatDialog.show();
}
//创建stringbuffer保存聊天内容
StringBuffer mTextBuffer = new StringBuffer();
private RecognizerDialogListener recognizerDialogListener = new RecognizerDialogListener() {
@Override
public void onResult(RecognizerResult results, boolean isLast) {
// System.out.println(results.getResultString());
// System.out.println("isLast=" + isLast);
//解析语音识别的json数据
String text = parseData(results.getResultString());
//说话还没有结束,需要添加文本
mTextBuffer.append(text);
if (isLast) {// 会话结束
String finalText = mTextBuffer.toString();
// 清理buffer,防止上一次buffer的干扰
mTextBuffer = new StringBuffer();
System.out.println("最终结果:" + finalText);
mChatList.add(new ChatBean(finalText, true, -1));
String answer = "没听清";
int imageId = -1;
if (finalText.contains("你好")) {
answer = "大家好,才是真的好!";
} else if (finalText.contains("你是谁")) {
answer = "我是你的小助手!";
} else if (finalText.contains("天王盖地虎")) {
answer = "小鸡炖蘑菇";
imageId = R.drawable.m;
} else if (finalText.contains("美女")) {
//随机数组图片
Random random = new Random();
int i = random.nextInt(mMMAnswers.length);
int j = random.nextInt(mMMImageIDs.length);
answer = mMMAnswers[i];
imageId = mMMImageIDs[j];
}
// 添加回答数据
mChatList.add(new ChatBean(answer, false, imageId));
// 刷新listview
mAdapter.notifyDataSetChanged();
// 定位到最后一张
lv_list.setSelection(mChatList.size() - 1);
read(answer);
}
}
@Override
public void onError(SpeechError arg0) {
}
};
/*
* 语音朗诵
*/
public void read(String text) {
SpeechSynthesizer mTts = SpeechSynthesizer
.createSynthesizer(this, null);
mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan");
mTts.setParameter(SpeechConstant.SPEED, "50");
mTts.setParameter(SpeechConstant.VOLUME, "80");
mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
mTts.startSpeaking(text, null);
}
/*
* 解析语音数据,语音数据是以json的形式在保存,将解析的数据保存在sb中
*/
protected String parseData(String resultString) {
Gson gson = new Gson();
VoiceBean bean = gson.fromJson(resultString, VoiceBean.class);
//ws就是语音识别的语音的内容
ArrayList<WSBean> ws = bean.ws;
StringBuffer sb = new StringBuffer();
for (WSBean wsBean : ws) {
//解析具体的内容
String text = wsBean.cw.get(0).w;
sb.append(text);
}
return sb.toString();
}
class ChatAdapter extends BaseAdapter {
@Override
public int getCount() {
return mChatList.size();
}
@Override
public ChatBean getItem(int position) {
return mChatList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null){
holder = new ViewHolder();
convertView = View.inflate(MainActivity.this, R.layout.list_item, null);
holder.tv_ask = (TextView) convertView.findViewById(R.id.tv_ask);
holder.tv_answer = (TextView) convertView.findViewById(R.id.tv_answer);
holder.ll_answer = (LinearLayout) convertView.findViewById(R.id.ll_answer);
holder.iv_pic = (ImageView) convertView.findViewById(R.id.iv_pic);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
//获取到item
ChatBean item = getItem(position);
if(item.isAsker){
//如果是提问者,隐藏回答的信息,显示提问信息
holder.tv_ask.setVisibility(View.VISIBLE);
holder.ll_answer.setVisibility(View.GONE);
holder.tv_ask.setText(item.text);
}else{
//如果是回复者,显示回答的信息,隐藏提问信息
holder.tv_ask.setVisibility(View.GONE);
holder.ll_answer.setVisibility(View.VISIBLE);
holder.tv_answer.setText(item.text);
//有图片的回复
if(item.imageId != -1){
holder.iv_pic.setVisibility(View.VISIBLE);
holder.iv_pic.setImageResource(item.imageId);
holder.iv_pic.setImageResource(item.imageId);
}else{
holder.iv_pic.setVisibility(View.GONE);
}
}
return convertView;
}
}
static class ViewHolder{
public TextView tv_ask;
public TextView tv_answer;
public LinearLayout ll_answer;
public ImageView iv_pic;
}
}