失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 手把手教你做Android聊天机器人

手把手教你做Android聊天机器人

时间:2019-08-20 16:55:27

相关推荐

手把手教你做Android聊天机器人

我相信大家应该知道有款应用叫小黄鸡吧!

如果不知道,那你见过那种可以秒回复的聊天应用么?

如果仍然没看到!那你总见过可以迅速回复你的微信公共账吧!

如果仍然....亲出门左拐

好,不多说。

首先大家都应该了解程序,程序就是由人为的设定搭建起来的一套系统,

这里的机器人也是,简单的原理就是当你输入关键字后,通过一套算法,

在数据库中找到与之最为匹配的内容在返回给你。这个已经有人实现,我们这节教程就用别人

已经实现好的东西去做一​​个应用来玩耍~~

(当然如果你非要想知道如何去做,给我留言。看情况我会出篇教程去交大家如何去做这个后端的机器人)

首先我们需要设计程序。

需要用到的类

-------ChatMessage.java(自己创建的类,目的是为了在接受与发送的时候把信息封装对象化)

------- Result.java(接受信息时候需要用到的返回信息类)

直到

------- AiaiUntil.java(自己创建的类型,用来发送信息与得到返回信息的工具)

------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- -------

CharMessageAdapter.java (因为是聊天形式的应用,所以布局需要时动态的,这里引用的布局Adapter需要继承BaseAdapter )

MainActivity.java(程序入口,程序的总展示层)

以上就是用到的所有类,很少吧。

为什么这么少,是因为我们借用的是别人写好的机器人后台- 图灵机器人

大家可以点开连接,简单看看里面的API是如何用的。

请求方式

API地址: /openapi/api

请求方式:HTTP GET

数据格式:JSON

返回的数据都是JSON。还有不论是否返回成功都会返回一个代码,用来判断是否返回成功

下面我们就进行代码的编写,首先是封装信息的对象。

ChatMessage。java的

包装com..bean;进口java.util.Date的;公共类ChatMessage {私人字符串名称;私人弦乐味精;私人类型类型;私人时间日期;公共ChatMessage(){}公共ChatMessage(弦乐味精,类型类型,日期为准){this.msg =味精;this.type =类型;this.date =日期;}//定义枚举定义类型//枚举是用来区分数据类型公共枚举类型{来料,OUTCOMING}公共字符串的getName(){返回的名称;}公共无效的setName(字符串名称){this.name =名称;}公共字符串的getMsg(){返回味精;}公共无效setMsg(弦乐味精){this.msg =味精;}公共类型的getType(){返回类型;}公共无效的setType(类型类型){this.type =类型;}公开日期GETDATE(){返回日期;}公共无效的setDate(日期为准){this.date =日期;}}

下面是信息结果类

包装com..bean;/ *** * @author Srain_zhou*为了发送一个对话对象到服务器所需要的映射对象* /公共类结果{//此处注意开头字母组好小写,因为返回的结果键都是小谢的私人诠释代码;私人字符串文本;公众诠释引用代码(){返回代码;}公共无效setCode(INT代码){this.code =代码;}公共字符串的getText(){返回文本;}公共无效的setText(字符串文本){this.text =文本;}}

下面是核心交换类,可以理解为DAO

AiaiUntil.java

包com..until;进口java.io.ByteArrayOutputStream中;进口java.io.IOException的;进口的java.io.InputStream;进口java.io.UnsupportedEncodingException;进口.HttpURLConnection中;进口.MalformedURLException;进口.URLEncoder中;进口java.util.Date的;进口com.google.gson.Gson;进口com..bean.ChatMessage;进口com..bean.ChatMessage.Type;进口com..bean.Result;公共类AiaiUntil {//连接图灵机器人的接口私有静态最后字符串URL =“htt​​p:///openapi/api”;//自己的apikey私有静态最后弦乐API_KEY =“自己去申请的一个APP_KEY体验下开发的快感吧!”;//发送一个消息,得到返回的消息公共静态ChatMessage的sendMessage(弦乐味精){//创建一个封装信息对象ChatMessage chatmessage =新ChatMessage();//此处请看的doGet方法字符串jsonRes =的doGet(MSG);// GSON是谷歌提供的一个JAR包主要用途为序列化的Java对象为JSON字符串,或反序列化JSON字符串成的Java对象。//序列化是为了网路传输GSON GSON =新GSON();结果结果= NULL;尝试{//为了获得返回字符串结果= gson.fromJson(jsonRes,Result.class);chatmessage.setMsg(result.getText());}赶上(例外五){chatmessage.setMsg(“服务器繁忙”);}chatmessage.setDate(新日期());chatmessage.setType(Type.INCOMING);返回chatmessage;}公共静态字符串的doGet(弦乐味精){字符串结果=“”;//拼接网址此处需要详细了解图灵机器人的请求方式字符串URL = setRarams(MSG);//输入流InputStream的是= NULL;// ByteArrayOutputStream此类实现了一个输出流,其中的数据被写入一个字节数组。ByteArrayOutputStream BAOS = NULL;//构建发送请求的对象尝试{的.URL url_net =新的.URL(URL);HttpURLConnection的CONN =(HttpURLConnection类)url_net.openConnection();//设置从主机读取数据超时conn.setReadTimeout(5 * 1000);//设置连接主机超时conn.setConnectTimeout(5 * 1000);//设置连接方式conn.setRequestMethod(“GET”);//获取写入流是= conn.getInputStream();//设置缓冲区整型长度= -1;//设置缓冲区128字节byte []的BUF =新的字节[128];//吧流转换成字符串的类BAOS =新ByteArrayOutputStream();//判断是否读完而((长度= is.​​read(BUF))!= - 1){baos.write(BUF,0,长度);}//清除缓冲区baos.flush();//把流转换为字符串结果=新的String(baos.toByteArray());}赶上(MalformedURLException的E){// TODO自动生成的catch块e.printStackTrace();}赶上(IOException异常E){// TODO自动生成的catch块e.printStackTrace();}最后{//释放资源尝试{如果(BAOS!= NULL){baos.close();}}赶上(IOException异常E){// TODO自动生成的catch块e.printStackTrace();}尝试{如果(是!= NULL){is.close();}}赶上(IOException异常E){// TODO自动生成的catch块e.printStackTrace();}}返回结果;}//构建请求路径的方法公共静态字符串setRarams(弦乐味精){字符串URL_value = NULL;尝试{URL_value =网址+ + + API_KEY“与信息=”+ URLEncoder.encode(MSG,“UTF-8”)“键=?”;}赶上(UnsupportedEncodingException E){// TODO自动生成的catch块e.printStackTrace();}返回URL_value;}}

CharMessageAdapter.java内容提供者,里面关于对话的布局文件你可以按照自己的喜欢自己去设计

简单解释下。其中对话框是一个listView 里面分别是两组不同的ListView(红色与蓝色),请结合下面

代码去模拟定义自己的对话布局,我就觉得我的布局丑,所以就不贴代码了。自己DIY吧~~

包com.;进口java.text.SimpleDateFormat的;进口的java.util.List;进口com..bean.ChatMessage;进口com..bean.ChatMessage.Type;进口android.content.Context;进口android.view.LayoutInflater;进口android.view.View;进口android.view.ViewGroup;进口android.widget.BaseAdapter;进口android.widget.TextView;公共类CharMessageAdapter扩展了BaseAdapter {/ ***对于一个没有被载入或者想要动态载入的界面,都需要使用充气来载入。 *的Andr​​oid里面想要创建一个画面的时候,初学一般都是新建一个类,继承活动基类,*然后在的onCreate里面使用的setContentView方法来载入一个在XML里定义好的界面。 *其实在活动里面就使用了LayoutInflater来载入界面, *通过getSystemService(Context.LAYOUT_INFLATER_SERVICE)方法可以获得一个LayoutInflater, *也可以通过LayoutInflater吹气= getLayoutInflater();*来获得。然后使用充气方法来载入布局的XML, *在实际开发种LayoutInflater这个类还是非常有用的,它的作用类似于findViewById()*不同点是LayoutInflater是用来找布局下的xml布局文件,*并且实例化!而findViewById()是找具体的xml下的具体窗口小部件控件。* ///用来重载布局的对象,是机器人已经帮我们做好的类私人LayoutInflater mInflater;//聊天信息数据集合私人名单<ChatMessage> mDatas;公共CharMessageAdapter(上下文语境,名单<ChatMessage> mDatas){mInflater = LayoutInflater.from(上下文);this.mDatas = mDatas;}//继承BaseAdapter需要重写的方法,获取数据的长度@覆盖公众诠释getCount将(){// TODO自动生成方法存根返回mDatas.size();}//继承BaseAdapter需要重写的方法,获取数据所处的项目@覆盖公共对象的getItem(INT位置){// TODO自动生成方法存根返回mDatas.get(位置);}//继承BaseAdapter需要重写的方法,获取ITEMID@覆盖众长getItemId(整数位){// TODO自动生成方法存根回到位置;}/ ***因为本次需要布局两次不同位置所以需要多写两个方法* /// getItemViewType方法告诉ListView中每行该显示哪种项目@覆盖公众诠释getItemViewType(整数位){ChatMessage chatMessage = mDatas.get(位置);如果(chatMessage.getType()== Type.INCOMING){返回0;}返回1;}// getViewTypeCount这个方法告诉ListView控件我共有多少种项目@覆盖公众诠释getViewTypeCount(){// TODO自动生成方法存根返回2;}/ ***就是一个持有者的类,他里面一般没有方法,*只有属性,作用就是一个临时的储存器,*把你getView方法中每次返回的视图存起来,可以下次再用。*这样做的好处就是不必每次都到布局文件中去拿到你的视图,提高了效率。* /私人final类ViewHolder {TextView的mDate;TextView的MMSG;}//如下这个就是如何动态布局的代码@覆盖公共查看getView(INT位置,查看convertView,父母的ViewGroup){ChatMessage chatMessage = mDatas.get(位置);//上文中说出用处,提高页面效率ViewHolder viewholder = NULL;如果(convertView == NULL){//通过的ItemType设置不同的布局如果(getItemViewType(位置)== 0){convertView = mInflater.inflate(R.layout.item_from_msg,父母,假);viewholder =新ViewHolder();viewholder.mDate =(TextView的)convertView.findViewById(R.id.from_msg_date);viewholder.mMsg =(TextView的)convertView.findViewById(R.id.from_msg);}其他{convertView = mInflater.inflate(R.layout.item_to_msg,父母,假);viewholder =新ViewHolder();viewholder.mDate =(TextView的)convertView.findViewById(R.id.to_msg_date);viewholder.mMsg =(TextView的)convertView.findViewById(R.id.to_msg);}//在使用LayoutInflater对象进行查看扩充的标签的使用//用来标记convertView,如果viewholder对象有就不在重新生成对象,为了效率!convertView.setTag(viewholder);}其他{viewholder =(ViewHolder)convertView.getTag();}//下面这段代码慢慢看,很简单SimpleDateFormat的DF =新的SimpleDateFormat(“YYYY-MM-DD HH:MM:SS”);viewholder.mDate.setText(df.format(chatMessage.getDate()));viewholder.mMsg.setText(chatMessage.getMsg());返回convertView;}}

下面就是最主要的主MainActivity了~~

package com.;import java.util.ArrayList;import java.util.Date;import java.util.List;import com..bean.ChatMessage;import com..bean.ChatMessage.Type;import com..until.AiaiUntil;import android.support.v7.app.ActionBarActivity;import android.text.TextUtils;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.Window;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.ListView;import android.widget.Toast;public class MainActivity extends ActionBarActivity {//最外边的对话布局private ListView mMsg;//内容提供对象private CharMessageAdapter mAdapter;//数据集合private List<ChatMessage> mDatas;//VIEWprivate EditText mInputMsg;private Button mSendMsg;//因为要更新界面所以要用 Handler mHandlerprivate Handler mHandler =new Handler(){public void handleMessage(android.os.Message msg) {//等待ijieshou子线程ChatMessage cm=(ChatMessage)msg.obj;mDatas.add(cm);mAdapter.notifyDataSetChanged();mMsg.setSelection(mDatas.size()-1);};};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_main);//初始化视图initView();//初始化数据initDatas();//初始化监听initListener();}private void initListener() {mSendMsg.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {final String toMsg = mInputMsg.getText().toString();if(TextUtils.isEmpty(toMsg)){Toast.makeText(MainActivity.this, "发送消息不可以为空", Toast.LENGTH_SHORT).show();return;}//为了做聊天的效果ChatMessage toMessage = new ChatMessage();toMessage.setDate(new Date());toMessage.setMsg(toMsg);toMessage.setType(Type.OUTCOMING);mDatas.add(toMessage);mAdapter.notifyDataSetChanged();mMsg.setSelection(mDatas.size()-1);mInputMsg.setText("");new Thread(new Runnable() {public void run() {//网络访问不能用在主线程中应该在子线程中ChatMessage fromMessage =AiaiUntil.sendMessage(toMsg);Message m =Message.obtain();m.obj=fromMessage;//发送后 会在handler中的handleMessage中接受到mHandler.sendMessage(m);}}).start();}});}private void initDatas() {mDatas =new ArrayList<ChatMessage>();mDatas.add(new ChatMessage("你好,我是小艾艾",Type.INCOMING,new Date()));mAdapter = new CharMessageAdapter(this,mDatas);mMsg.setAdapter(mAdapter);}private void initView() {mMsg=(ListView)findViewById(R.id.id_list_view_01);mInputMsg=(EditText)findViewById(R.id.input_msg); mSendMsg=(Button)findViewById(R.id.id_send_msg);}}

希望对大家的学习有帮助~~~

提示!~~~

1如果你编译不出现R文件,也就是说R. 不出来 说明你的XML文件绝对有错误

2在这个APP中,千万别忘记加网络访问权限~

AndroidManifest.xml文件中

加入如下代码

<uses-permission android:name="android.permission.INTERNET"/>加载application 标签外面

如果觉得《手把手教你做Android聊天机器人》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。