现在的聊天机器人一般都是通过连接网络API接口实现的,通过对接口的网络访问,实现聊天数据的传输,我这个就是访问图灵机器人的接口实现。

先看效果图:

界面代码:

1.activity_main.xml 主界面布局、包括头部及一个listview和下方的文本输入框与按钮。

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:id="@+id/activity_main"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical"

    tools:context="com.jju.edu.robot.MainActivity">

    <include layout="@layout/title"></include>

    <ListView

        android:id="@+id/list_view"

        android:layout_width="match_parent"

        android:layout_height="0dp"

        android:layout_weight="1"

        android:cacheColorHint="#00000000"></ListView>

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="40dp"

        android:orientation="horizontal">

        <EditText

            android:id="@+id/ed_message"

            android:layout_width="0dp"

            android:layout_height="match_parent"

            android:layout_weight="1"

            android:background="@drawable/shape2"

            />

        <Button

            android:onClick="submit"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:background="@drawable/shape1"

            android:text="发送"/>

    </LinearLayout>

</LinearLayout>

2.title.xml 头部的详细布局里面有左、中、右三个textview,方便代码重复调用(这项目里是没必要的,习惯了!)这里只用到了中间的textview。

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="match_parent"

    android:layout_height="50dp">

    <RelativeLayout

        android:layout_width="match_parent"

        android:background="#0b85ed"

        android:layout_height="match_parent">

        <TextView

            android:id="@+id/left"

            android:layout_width="wrap_content"

            android:layout_height="match_parent"

            android:gravity="center_vertical"

            android:textSize="20sp"

            android:textColor="#FFFFFF"

            android:layout_alignParentLeft="true"

            android:layout_marginLeft="10dp"/>

        <TextView

            android:id="@+id/middle"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_centerInParent="true"

            android:text="标题"

            android:textSize="20sp"

            android:textColor="#ffffff"/>

        <TextView

            android:id="@+id/right"

            android:layout_width="wrap_content"

            android:layout_height="match_parent"

            android:gravity="center_vertical"

            android:textSize="20sp"

            android:textColor="#FFFFFF"

            android:layout_alignParentRight="true"

            android:layout_marginRight="10dp"/>

    </RelativeLayout>

</LinearLayout>

3.这里是listview里面item的两种布局,分别是我们发送信息的显示布局以及收到信息的显示布局。

list_item_left.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"   

    android:layout_width="match_parent"

    android:layout_height="wrap_content">

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:gravity="center_horizontal"

        android:orientation="vertical">

        <TextView

            android:id="@+id/time"

            android:layout_width="wrap_content"

            android:layout_height="20dp"

            android:text="时间"/>

        <LinearLayout

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:orientation="horizontal"

            >

            <LinearLayout

                android:layout_width="50dp"

                android:layout_height="60dp"

                android:orientation="vertical">

                <ImageView

                    android:layout_width="40dp"

                    android:layout_height="40dp"

                    android:layout_marginLeft="10dp"

                    android:background="@drawable/lzk"/>

                <TextView

                    android:layout_width="match_parent"

                    android:layout_height="20dp"

                    android:layout_marginLeft="10dp"

                    android:text="小灵"/>

            </LinearLayout>

            <TextView

                android:id="@+id/content"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:layout_marginLeft="15dp"

                android:layout_marginRight="60dp"

                android:text="内容"

                android:background="@drawable/shape"

                android:textSize="20sp"/>

        </LinearLayout>

    </LinearLayout>

</LinearLayout>

list_item_right.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    android:orientation="vertical">

    <RelativeLayout

        android:layout_width="match_parent"

        android:layout_height="wrap_content">

        <TextView

            android:id="@+id/time"

            android:layout_width="wrap_content"

            android:layout_height="20dp"

            android:layout_centerHorizontal="true"

            android:text="时间" />

        <RelativeLayout

            android:layout_width="match_parent"

            android:layout_height="60dp"

            android:layout_marginTop="20dp">

            <LinearLayout

                android:id="@+id/img"

                android:layout_width="40dp"

                android:layout_height="60dp"

                android:layout_alignParentRight="true"

                android:layout_marginRight="10dp"

                android:gravity="center_horizontal"

                android:orientation="vertical">

                <ImageView

                    android:layout_width="40dp"

                    android:layout_height="40dp"

                    android:background="@drawable/nimingliaotian" />

                <TextView

                    android:layout_width="wrap_content"

                    android:layout_height="20dp"

                    android:text="我" />

            </LinearLayout>

            <TextView

                android:id="@+id/content"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:layout_marginLeft="60dp"

                android:layout_marginRight="10dp"

                android:layout_toLeftOf="@id/img"

                android:background="@drawable/shape1"

                android:text="内容"

                android:textSize="20sp" />

        </RelativeLayout>

    </RelativeLayout>

</LinearLayout>

Java代码:

首先得先找到图灵机器人的API接口,该接口有很多数据平台都会提供,而且完全免费!我这里调用的是聚合数据里的,就以聚合数据的接口示例。

注册后登录,实名认证完成后直接申请数据即可。申请成功,会获得key值及申请示例。下面直接看代码,注释里会解释:

1.MainActivity.class

package com.jju.edu.robot;

import android.app.Activity;

import android.os.Handler;

import android.os.Message;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.view.Window;

import android.widget.EditText;

import android.widget.ListView;

import android.widget.TextView;

import android.widget.Toast;

import org.json.JSONObject;

import java.io.InputStream;

import java.net.HttpURLConnection;

import java.net.URL;

import java.net.URLEncoder;

import java.util.ArrayList;

import java.util.Calendar;

import java.util.List;

public class MainActivity extends Activity {

    private String time;//时间(会在每次发送或接收数据时重新赋值)

    private String path1 = "http://op.juhe.cn/robot/index?info=";//接口路径

    private String path2 = "&dtype=&loc=&lon=&lat=&userid=&key=8a2e2e11c3453a5fd3002b864174e440";//发送的各种参数及key值(这里就不过多设置参数了,直接默认)

    private String text = "";

    private TextView middle;

    private EditText ed_message;

    private List<MessageUtil> list = new ArrayList<MessageUtil>();

    private MyAdapter adapter;

    private ListView list_view;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.activity_main);

        //获取控件

        middle = (TextView) findViewById(R.id.middle);

        ed_message = (EditText) findViewById(R.id.ed_message);

        list_view = (ListView) findViewById(R.id.list_view);

        list_view.setDividerHeight(0);//去掉黑线

        middle.setText("聊天界面");//设置头部标题

        //将初始值放入list集合

        MessageUtil util = new MessageUtil();

        util.setJudge(false);

        util.setTime(getTime());

        util.setMessage("您好!我是小灵!");

        list.add(util);

        //定义自定义适配器并赋值

        adapter = new MyAdapter(MainActivity.this, list);

        //将自定义适配器添加到listview

        list_view.setAdapter(adapter);

    }

    //获取时间,每次调用都会获得调用时的当前时间。

    public String getTime() {

        Calendar c = Calendar.getInstance();

        time = c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-" + c.get(Calendar.DAY_OF_MONTH) + "  " + c.get(Calendar.HOUR_OF_DAY) + ":" + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND);

        Log.e("时间", time);

        return time;

    }

    //按钮点击事件

    public void submit(View view) {

        String message = ed_message.getText().toString();

        //输入不能为空

        if (message == null || message.equals("")) {

            Toast.makeText(MainActivity.this, "输入不能为空!", Toast.LENGTH_SHORT).show();

        } else {

            //添加自己发送的数据到list集合

            MessageUtil util = new MessageUtil();

            util.setJudge(true);

            util.setTime(getTime());

            util.setMessage(message);

            list.add(util);

            //添加改变值

            adapter.notifyDataSetChanged();

            //显示listview最后一个值

            list_view.setSelection(list.size());

            //网络操作

            http_(message);

        }

        ed_message.setText("");

    }

    //网络访问操作

    public void http_(final String string) {

        new Thread() {

            @Override

            public void run() {

                try {

                    //保证编码格式正确

                    String city = URLEncoder.encode(string, "UTF-8");

                    //拼接地址与参数

                    URL url = new URL(path1 + city + path2);

                    //访问

                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                    connection.connect();

                    InputStream is = connection.getInputStream();

                    //获得返回值

                    String info = getInfo(is);

                    Log.e("****", info);

                    //子线程无法操作UI,所以讲数据传递给handler。

                    Message message = handler.obtainMessage();

                    message.obj = info;

                    message.what = 123;

                    handler.sendMessage(message);

                } catch (Exception e) {

                    e.printStackTrace();

                }

            }

        }.start();

    }

    //获得返回数据,调用解析方法

    public Handler handler = new Handler() {

        @Override

        public void handleMessage(Message msg) {

            if (msg.what == 123) {

                text = (String) msg.obj;

                json(text);

            }

        }

    };

    //读取返回数据将其转换成String型并返回

    public String getInfo(InputStream is) {

        String info = null;

        byte[] by = new byte[1024];

        StringBuilder builder = new StringBuilder();

        int count = -1;

        try {

            while ((count = is.read(by)) != -1) {

                builder.append(new String(by, 0, count));

            }

            info = builder.toString();

            is.close();

        } catch (Exception e) {

            e.printStackTrace();

        }

        return info;

    }

    //解析返回的jsons数据,并将值添加到list集合后保存添加数据(应该将解析方法与添加list集合的方法写成两个方法的,这里就懒得分开了)

    public void json(String string) {

        try {

            JSONObject object = new JSONObject(string);

            String back = object.getString("result");

            JSONObject object1 = new JSONObject(back);

            String back_message = object1.getString("text");

            MessageUtil util = new MessageUtil();

            util.setJudge(false);

            util.setTime(getTime());

            util.setMessage(back_message);

            list.add(util);

            adapter.notifyDataSetChanged();

            list_view.setSelection(list.size());

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

2.MessageUtil.class 构造方法类

package com.jju.edu.robot;

/**

 * Created by LingHao on 2016/11/3.

 * 构造方法类

 */

public class MessageUtil {

    private String time;

    private String message;

    private boolean judge;

    public String getTime() {

        return time;

    }

    public void setTime(String time) {

        this.time = time;

    }

    public boolean isJudge() {

        return judge;

    }

    public void setJudge(boolean judge) {

        this.judge = judge;

    }

    public String getMessage() {

        return message;

    }

    public void setMessage(String message) {

        this.message = message;

    }

}

3.MyAdapter.class 自定义适配器类。

package com.jju.edu.robot;

import android.content.Context;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.TextView;

import java.util.List;

/**

 * Created by LingHao on 2016/11/3.

 */

public class MyAdapter extends BaseAdapter {

    private Context context;

    private List<MessageUtil> list;

    private LayoutInflater inflater;

    private int COME_MSG = 0;

    private int TO_MSG = 1;

    public MyAdapter(Context context, List<MessageUtil> list) {

        this.context = context;

        this.list = list;

        inflater = LayoutInflater.from(context);

    }

    @Override

    public int getCount() {

        return list.size();

    }

    @Override

    public Object getItem(int position) {

        return list.get(position);

    }

    @Override

    public long getItemId(int position) {

        return position;

    }

    @Override

    public View getView(int position, View convertView, ViewGroup parent) {

        //缓存机制

        ViewHolder holder = null;

        if (convertView == null) {

            holder = new ViewHolder();

            //判断是发送还是接收,从而设置风格样式靠左还是靠右

            if (list.get(position).isJudge()) {

                convertView = inflater.inflate(R.layout.list_item_right, null);

            } else {

                convertView = inflater.inflate(R.layout.list_item_left, null);

            }

            holder.time = (TextView) convertView.findViewById(R.id.time);

            holder.content = (TextView) convertView.findViewById(R.id.content);

            convertView.setTag(holder);

        } else {

            holder = (ViewHolder) convertView.getTag();

        }

        holder.time.setText(list.get(position).getTime());

        holder.content.setText(list.get(position).getMessage());

        return convertView;

    }

    class ViewHolder {

        TextView time, content;

    }

    @Override

    public int getItemViewType(int position) {

        // 区别两种view的类型,标注两个不同的变量来分别表示各自的类型

        MessageUtil util = list.get(position);

        if (util.isJudge()) {

            return COME_MSG;

        } else {

            return TO_MSG;

        }

    }

    @Override

    public int getViewTypeCount() {

        // 这个方法默认返回1,如果希望listview的item都是一样的就返回1,我们这里有两种风格,返回2

        return 2;

    }

}

注意:运行之前要添加网络权限:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

文章来源:网络  版权归原作者所有

上文内容不用于商业目的,如涉及知识产权问题,请权利人联系小编,我们将立即处理

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐