Android--智能机器人聊天

借助API,可快速实现在安卓手机上的与智能机器人聊天的功能。大体的步骤有:1、异步请求数据;2、解析json数据;3、封装数据;4、实现布局;

源代码下载地址:http://download.csdn.net/detail/leyezhiqiu/9471571

实现效果如下图:

下面一一介绍。

1、在浏览器上获取与机器人对话的数据。

1)打开图灵机器人官网,注册账号www.tuling123.com/openapi 。

2)登录账号,记录下官方分配给账号的key。

3)在账号中查看获得数据的格式,如get的请求方式格式:http://www.tuling123.com/openapi/api?key=XXX&info=XXXXX&userid=XXXXXXX

4)在浏览器上测试能否通过get方式获得对应数据。

2、在Android工程中获取数据。

1)编写异步通信类HttpData.java:发送请求,获取数据,读取数据。

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.os.AsyncTask;

/**
 * 异步通信类
 *
 * @author mingyue
 *
 */
public class HttpData extends AsyncTask<String, Void, String> {

    private HttpClient httpClient;
    private HttpGet httpGet;
    private HttpResponse httpResponse; // 获取请求返回的数据
    private HttpEntity httpEntity;// 创建http实体
    private InputStream in; // 将获取到的数据转化为流文件
    private HttpGetDataListener listener;// 实现自定义的HttpGetDataListener接口,并且构造化传递参数
    private String url;

    public HttpData(String url, HttpGetDataListener listener) {
        this.url = url;
        this.listener = listener;
    }

    @Override
    protected String doInBackground(String... params) {// 实现接口后重写此方法,此方法的作用是:发送get请求后,获取数据
        try {
            httpClient = new DefaultHttpClient();// 实例化客户端
            httpGet = new HttpGet(url);// 使用get方式,通过发送URL来请求
            httpResponse = httpClient.execute(httpGet); // 通过客户端发送请求
            httpEntity = httpResponse.getEntity();// 通过httpResponse对象获取数据

            in = httpEntity.getContent();// 获取实体的具体内容
            BufferedReader br = new BufferedReader(new InputStreamReader(in));// 获取到具体内容后,通过缓冲区进行读取

            String line = null; // 读取数据
            StringBuffer sb = new StringBuffer();// 储存所有数据
            while ((line = br.readLine()) != null) { // 读取缓冲区的数据
                sb.append(line); // 存储数据到StringBuffer中
            }
            return sb.toString();// 转换为String类型
        } catch (Exception e) {
        }
        return null;
    }

    /**
     * 重写此方法,通过这方法获取数据
     */
    @Override
    protected void onPostExecute(String result) {
        listener.getDataUrl(result);// 返回数据
        super.onPostExecute(result);
    }

}

2)由于要将获取到的数据传递给其它页面,所有这里新建一个接口,采用回调的方式。

//HttpGetDataListener.java

public interface HttpGetDataListener {
    void getDataUrl(String data);
}

3)在MainActivity中实现HttpGetDataListener接口,测试能否获得数据。

具体代码如下:

public class MainActivity extends Activity implements HttpGetDataListener{

    private HttpData httpData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        httpData = (HttpData) new HttpData(
                "http://www.tuling123.com/openapi/api?key=XXXXX&info=北京",
                this).execute();//execute()启动异步通信,注意:XXXXX应该是在步骤1获取的key值
    }

    /**
    *实现抽象方法
    */
    @Override
    public void getDataUrl(String data) {
        System.out.println(data);
    }
}

4)运行代码,在logcat中能看到相关的json数据,则说明数据获取成功。

3、解析json数据。

在MainActivity.java中编写parseText()方法,解析数据,在getDataUrl()方法中调用parseText()方法。

代码如下:

    @Override
    public void getDataUrl(String data) {
        System.out.println(data);
        parseText(data);
    }

    public void parseText(String str){
        try {
            JSONObject jb = new JSONObject(str);
            System.out.println(jb.getString("code"));
            System.out.println(jb.getString("text"));
        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

再次运行代码,可看到运行结果如下:

4、封装数据

1)创建ListData.java,用于封装数据,如机器人的对话、时间等,现只是初步封装时间。代码如下:

public class ListData {
    private String content;

    public ListData(String content) {
        this.content = content;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

2)修改MainActivity.java,让解析出的json数据封装好(具体步骤:新建实例化方法initiView() 方法,实例化List lists;在parseText()方法中实例化ListData listData,将解析出的json数据封装到listData,再将listData添加到lists)。完成后,MainActivity.java的代码如下所示。

public class MainActivity extends Activity implements HttpGetDataListener {

    private HttpData httpData;
    private List<ListData> lists;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        httpData = (HttpData) new HttpData(
                "http://www.tuling123.com/openapi/api?key=XXXXX&info=北京",
                this).execute();//execute()启动异步通信,注意:XXXXX应该是在步骤1获取的key值
    }

    /**
     * 实例化方法
     */
    public void initView() {
        lists = new ArrayList<ListData>();
    }

    /**
     * 实现HttpGetDataListener接口的抽象方法,获取到HttpData得到的数据
     */
    @Override
    public void getDataUrl(String data) {
        System.out.println(data);
        parseText(data);
    }

    /**
     * 解析json、封装数据
     *
     * @param data
     */
    public void parseText(String data) {
        System.out.println("data======" + data);
        try {
            JSONObject jb = new JSONObject(data);
            ListData listData;
            listData = new ListData(jb.getString("text"));// 封装数据
            lists.add(listData);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

5、实现布局。

1)在与MainActivity对应的layout中添加控件:一个ListView(作用:显示对话)、一个EditText(作用:对话输入框)、一个Button(作用:发送按钮)。

完整具体代码如下。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <!-- transcriptMode 自动向下滚动    alwaysScroll一直向下滚动状态;   divider设置间隔线效果 ;   listSelector设置没有滑动效果 -->

    <ListView
        android:id="@+id/lv"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:divider="@null"
        android:listSelector="@android:color/transparent"
        android:transcriptMode="alwaysScroll" >
    </ListView>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#229dec"
        android:orientation="horizontal" >

        <EditText
            android:id="@+id/et_sendText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="7dp"
            android:layout_weight="1"
            android:background="@drawable/bg_edittext_selector"
            android:paddingBottom="7dp"
            android:paddingTop="7dp" />

        <Button
            android:id="@+id/btn_send"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="7dp"
            android:background="@drawable/bg_button"
            android:text="@string/send" />
    </LinearLayout>

</LinearLayout>

2)创建与ListView想对应的适配器

(1)要先在ListData中封装一标识flag,用于表示适配器加载哪一个view。因为在聊天对话ListView中,每一个item的中的控件摆放位置是不一样的。同时在ListData中添加String time,表示对话时间数据。ListData完整代码如下所示。

/**
 * 把获取到的数据封装起来
 *
 * @author mingyue
 *
 */
public class ListData {
    public static final int SEND = 1;
    public static final int RECEIVE = 2;
    private String content;
    private int flag;// 标识
    private String time;

    public ListData(String content, int flag, String time) {
        setContent(content);
        setFlag(flag);
        setTime(time);
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public int getFlag() {
        return flag;
    }

    public void setFlag(int flag) {
        this.flag = flag;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }
}

(2)创建名为leftitem.xml的layout,在ListView中对应机器人item:一个TextView(作用:显示时间)、ImageView(作用:显示头像)和TextView(作用:显示对话内容)。代码如下:

<?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="wrap_content" >

    <TextView
        android:id="@+id/tv_time"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:padding="3dp" />

    <ImageView
        android:id="@+id/iv"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentLeft="true"
        android:layout_below="@id/tv_time"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:src="@drawable/person2" />

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv_time"
        android:layout_marginRight="10dp"
        android:layout_marginTop="5dp"
        android:layout_toRightOf="@id/iv"
        android:background="@drawable/left"
        android:gravity="center"
        android:padding="10dp" />

</RelativeLayout>

(3)创建名为rightitem.xml的layout,在ListView中对应用户item:一个TextView(作用:显示时间)、ImageView(作用:显示头像)和TextView(作用:显示对话内容)。

<?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="wrap_content" >

    <TextView
        android:id="@+id/tv_time"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:padding="3dp" />

    <ImageView
        android:id="@+id/iv"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentRight="true"
        android:layout_below="@id/tv_time"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:src="@drawable/person3" />

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv_time"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="5dp"
        android:layout_toLeftOf="@id/iv"
        android:background="@drawable/right"
        android:gravity="center"
        android:padding="12dp" />

</RelativeLayout>

(4)适配器完整代码。

//TextAdapter.java

public class TextAdapter extends BaseAdapter {// /继承BaseAdapter,实现方法

    private List<ListData> lists;// 集合的数据内容
    private Context mContext;// 承接上下文的Context

    private RelativeLayout layout;

    public TextAdapter(List<ListData> lists, Context mContext) {
        this.lists = lists;
        this.mContext = mContext;
    }

    @Override
    public int getCount() {// 返回lists所承载的条数
        return lists.size();
    }

    @Override
    public Object getItem(int position) {
        return lists.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {// convertView表示要加载的view,在本例子中有两个view要加载的,一是机器人说话,二是用户说话,分别对应leftitem和rightitem
        LayoutInflater inflater = LayoutInflater.from(mContext);
        if (lists.get(position).getFlag() == ListData.RECEIVE) {
            layout = (RelativeLayout) inflater.inflate(R.layout.leftitem, null);
        }
        if (lists.get(position).getFlag() == ListData.SEND) {
            layout = (RelativeLayout) inflater
                    .inflate(R.layout.rightitem, null);
        }
        TextView tv = (TextView) layout.findViewById(R.id.tv);// 对话textView
        TextView tv_time = (TextView) layout.findViewById(R.id.tv_time);// 时间textView
        tv.setText(lists.get(position).getContent()); // 将数据内容放进TextView中
        tv_time.setText(lists.get(position).getTime());// 将事件写进TextView
        return layout;
    }
}

3)修改MainActivity.java:设置发送Button的监听事件、将ListView与adapter绑定。代码入下。

public class MainActivity extends Activity implements HttpGetDataListener,
        OnClickListener {

    private HttpData httpData;
    private List<ListData> lists;
    private ListView lv;
    private EditText et_sendText;
    private Button btn_send;
    private TextAdapter adapter;
    private double currentTime, oldTime = 0;// 对话时间
    private String content_str; // 存储在EditText获取到的数据

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    /**
     * 实例化方法
     */
    public void initView() {
        lists = new ArrayList<ListData>();
        lv = (ListView) findViewById(R.id.lv);
        et_sendText = (EditText) findViewById(R.id.et_sendText);
        btn_send = (Button) findViewById(R.id.btn_send);
        btn_send.setOnClickListener(this);
        adapter = new TextAdapter(lists, this);
        lv.setAdapter(adapter);// 绑定adapter
    }

    /**
     * 设置时间
     *
     * @return
     */
    private String getTime() {
        currentTime = System.currentTimeMillis();
        SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日   HH:mm:ss");
        Date curDate = new Date();
        String str = format.format(curDate);
        if (currentTime - oldTime >= 5 * 60 * 1000) {// 如果超过5分钟,显示时间
            oldTime = currentTime;
            return str;
        } else {
            return "";
        }
    }

    /**
     * 实现HttpGetDataListener接口的抽象方法,获取到HttpData得到的数据
     */
    @Override
    public void getDataUrl(String data) {
        System.out.println(data);
        parseText(data);
    }

    /**
     * 解析json、封装数据
     *
     * @param data
     */
    public void parseText(String data) {
        System.out.println("data======" + data);
        try {
            JSONObject jb = new JSONObject(data);
            ListData listData;
            listData = new ListData(jb.getString("text"), ListData.RECEIVE,
                    getTime());// 封装数据
            lists.add(listData);
            adapter.notifyDataSetChanged();// 重新適配
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onClick(View v) {
        content_str = et_sendText.getText().toString();// 获取EditText內容
        et_sendText.setText("");
        String dropk = content_str.replace(" ", "");// 去掉空格
        String droph = dropk.replace("\n", "");// 去掉回车
        ListData listData;
        listData = new ListData(content_str, ListData.SEND, getTime());
        lists.add(listData);
        adapter.notifyDataSetChanged();// 刷新
        httpData = (HttpData) new HttpData(
                "http://www.tuling123.com/openapi/api?key=XXXXX&info=北京",
                this).execute();// 发送已经去掉空格和回车content_str的数据droph
                                // ;execute()启动异步通信
    }
}

4)点9图片处理,作用是处理聊天的对话框,让对话框背景图随对话内容适当拉升,使得界面更美观大方,本例子用模仿的是QQ气泡。点9图片的处理工具:打开sdk/tools/draw9patch.bat,就可以选择图片来处理了。

5)添加欢迎语。

(1)在string.xml中添加string-array。代码如下。

<!-- 添加欢迎语 -->
    <string-array name="welcome_tips">
        <item>主人,您好!O(∩_∩)O</item>
        <item>亲,你回来啦~</item>
        <item>Welcome!!</item>
        <item>呵呵,你来啦~</item>
        <item>Hi, long time no see !</item>
    </string-array>

(2)在MainActivity.java中添加欢迎语方法。

public String getRandomWelcomeTips() {
        String welcome_tip = null;
        welcome_arry = this.getResources().getStringArray(R.array.welcome_tips);// 从string.xml中获取名为welcome_tips的字符串数组
        int index = (int) (Math.random() * (welcome_arry.length - 1));// 获取一个随机数
        welcome_tip = welcome_arry[index];
        return welcome_tip;
    }

6)移除界面过多的信息,比如对话信息超过30条,就只显示最近的30条对话。在MainActivity.java中添加相关代码,如下。

if (lists.size() > 30) {// 如果屏幕上的对话数据多于30,则移除前面的数据
            for (int i = 0; i < lists.size(); i++) {
                lists.remove(i);
            }
        }

6、运行、调试、完善、重构、总结。

时间: 2024-10-10 14:58:00

Android--智能机器人聊天的相关文章

Android 实现智能机器人聊天

背景:其实,关于实现机器人聊天,是偶然的情况下的,公司需要做一个ios版的机器人,用于自动购买东西,然后ios就研发了一个,我觉得这种机器人挺好玩的,想明白到底怎么实现,于是就上了百度,这东西是神器,果断需要好好利用利用. 一:老规矩,先上效果图           二:原理分析 1.接入图灵机器人api 2.根据api完成网络请求消息的发送和接收 3.完成布局界面 4.实现和小家伙的对话 三:实例切割(源码展示) 1.图灵机器人是一个非常强大,方便使用的平台,我们在实现智能机器人聊天的时候,便

慕课网《Android智能机器人“小慕”的实现》项目上手操作与代码解读【1】

慕课网是我所找到的免费教程网站之一(http://www.imooc.com/),上面的项目设计前端.后端.移动开发等很多领域,个人感觉如果对编程感兴趣的话,慕课网绝对是上手项目的最佳选择.这个网站给出的一些项目都很新颖,比一些书上给的不知道沿用了多少年的项目新颖多了,而且在学习的时候如果发现问题可以给老师留言,然后老师都会一一回复.并且每一个项目都会附有源代码及一些资源,如果跟不上老师进度的话可以自己down下来仔细研究.好了,对慕课网我就介绍这么多吧. 因为本人曾经在大三暑假的时候自学过一点

android第三方----&gt;android智能机器人的使用

在网上找了个第三方智能机器人,可以实现聊天语音等功能,比较不错的.今天我们就开始智能机器人聊天的学习,例子中涉及的handler的有关知识和json数据的解析,请参见我的博客:android基础---->JSON数据的解析.android高级---->Handler的原理和android基础---->子线程更新UI 目录导航 获取图灵机器人key 图灵机器人的一些api介绍 在android程序中使用图灵机器人 友情链接 获取图灵机器人key <1>访问图灵机器人官方网站:

Android蓝牙聊天程序的扩展开发(基于Google Sample,类QQ设计)

首先看看程序的效果: 在整个开发过程中涉及的几个关键步骤 1)判断蓝牙设备是否可用 2)若蓝牙设备可用,判断是否开启 是:则不操作 否:开启蓝牙设备 3)让设备可见(在一定的时间范围内) 4)查看已经连接过的设备 5)扫描附近的设备 6)连接设备 7)建立socket连接,读写消息 8)退出程序时结束扫描和连接 程序架构: ChatActivity:UI的变化 接收(发送)来自BluetoothChatService的消息,接收         DeviceListActivity的消息 Dev

Android Socket 聊天工具(一个服务端实现多个客户端间通信)

如果某位朋友也打算做这个Socket聊天工具,本人有个小小的建议,你可以不必太着急些代码,先想清楚自己最终要做到怎样效果,然后把自己的思路都写下来,有一个基本的实现方法.在写代码时就按照自己的思路一步一步地写下去,这样可以很好地避免写代码时由于思路不清左删右改. 以下是本人程序的设计思路 客户端设计思路: 一 用户登录界面 1 用一个EditText作为用户名输入口,用一个按键确定. 2 注册一个广播接收器,专门接收由后来的聊天界面发过来的消息广播(包括发信人,收信人,消息体). 3 创建一个客

以C#编写的Socket服务器的Android手机聊天室Demo

 内容摘要  1.程序架构    2.通信协议    3.服务器源代码    4.客户端源代码    5.运行效果  一.程序架构 在开发一个聊天室程序时,我们可以使用Socket.Remoting.WCF这些具有双向通信的协议或框架.而现在,我正要实现一个C#语言作为服务器端.Android作为客户端的聊天室.由于服务器端和客户端不是同一语言(C#和java),所有我选择了Socket作为通信协议. 图1.1所示,我们可以看出:android手机客户端A向服务器端发送消息,服务器端收到消息后,

自定义android精美聊天界面

编写精美聊天界面,那就肯定要有收到的消息和发送的消息. 首先还是编写主界面,修改activity_chat.xml中的代码,如下所示: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_par

Android之聊天室设计与开发

我们要设计和实现一个有聊天室功能的APP,需要服务器不断读取来自客户端的信息,并即时地将信息发送给每个连接到本服务器上的客户端,每个客户端可以向服务器发送消息,并不断地接收来自服务器的消息,并将消息显示在界面上.这样就实现了客户端与客户端之间的即时聊天功能. 我用草图画了一下流程为: 参考样文:

Android智能聊天机器人

http://www.tuling123.com/       注册一个账号,申请一个KEY值.此网站也有文档,可以查看. 1 package com.tulingdemo; 2 3 import java.text.SimpleDateFormat; 4 import java.util.ArrayList; 5 import java.util.Date; 6 import java.util.List; 7 import org.json.JSONException; 8 import o

(仿微信Android)聊天+红包+直播+朋友圈源码发布了

今天给大伙推荐一个安卓开源项目-“凡信”的最新版本,很值得开发和产品同学们研究一下. 功能概览:IM聊天单聊/群聊/聊天室--基于环信sdk红包功能:1.一对一红包2.群红包(抢红包.答题红包.专属红包)3.钱包(资金及账户管理)直播功能:Ucloud推流 .Ucloud拉流.电台拉流朋友圈.用户体系.好友体系凡信自己服务器维护管理数据详细介绍(凡信)背景介绍:https://github.com/huangfangyi/FanXin2.0_IMhttp://www.imgeek.org/art