打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
记一次用Android studio开发一个小型对话机器人app

前言

  • 偶然在网上看到一个免费机器人接口,所以生此想法,接口地址:http://api.qingyunke.com/,Android开发比爬虫要繁琐得多,所以本文我将细说接口的调用方法,读者可根据思路去网上找一些免费接口拿来玩,其他代码一带而过,详细源码见文末。
  • 成品展示:

开发步骤

(1)新建项目empty,必要可github托管。

(2)先写页面

  • 在res->layout目录下新建两个layout xml file
  • activity_main作为主页面,msg_item为附在其上的消息页面。(具体代码见文末)
  • 这里再acitvity_main采用的不是ListView而是RecyclerView。

(3)写接口调用

  • 首先封装一个RobotManager类,用于接收用户输入之后对Url进行封装。
public class RobotManager {    private static String  url = "http://api.qingyunke.com/api.php?key=free&appid=0&msg=!!";    public static String getUrl(String question){        String real_url = url.replace("!!",question);//将url中的!!替换为用户输入的内容        return real_url;    }}
  • 其次在java->第一个包下创建一个接口GetConnection,用来接收接口返回的返回。
public interface GetConnection {    void onFinish(String response);	//返回正常    void onError(Exception e);	//返回错误}
  • 然后开始写MyConnection类,调用接口,给参,并通过GetConnection接口将网上接口返回的数据传递出去。
public class MyConnection {    public static void getResponse(final String url,final GetConnection getConnection){        new Thread(new Runnable() {            @Override            public void run() {                HttpURLConnection connection;                try{URL Url = new URL(url);connection = (HttpURLConnection) Url.openConnection();connection.setRequestMethod("GET");//Get方法connection.setConnectTimeout(2000);//延时时间connection.setReadTimeout(3000);connection.setDoInput(true);InputStream in = connection.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(in));StringBuilder response = new StringBuilder();String line;while ((line = reader.readLine()) != null) {    response.append(line);}Log.e("result",response.toString());if (getConnection != null) {    getConnection.onFinish(response.toString());}else {    Log.e("WeiNull","WeiNull");//测试时用的,无须关心。}                }catch(IOException io) {if (getConnection != null) {    getConnection.onError(io);}                }            }        }).start();    }}

(4)写页面逻辑

  • 页面逻辑主要是将从接口得到的内容渲染到页面上。首先进行一系列初始化,绑定布局,然后监听按钮点击接收用户输入,调用MyConnection类传入url,输入内容接收接口返回内容,同时用handler动态更新页面。
public class MainActivity extends AppCompatActivity {    private List<Msg> msgList = new ArrayList<Msg>();    private EditText inputText;    private Button send;    private RecyclerView msgRecyclerView;    private MsgAdapter adapter;    private Handler handler = new Handler(){        @Override        public void handleMessage(@NonNull Message msg) {            switch (msg.what){                case 1:{Bundle data = msg.getData();String result = data.getString("result");Msg robotMsg = new Msg(result,Msg.TYPE_RECEIVED);msgList.add(robotMsg);adapter.notifyItemInserted(msgList.size() - 1); // 当有新消息时,刷新ListView中的显示msgRecyclerView.scrollToPosition(msgList.size() - 1); // 将ListView定位到最后一行                }break;                case 2:{}break;                default:break;            }        }    };    private void getInter(String content){        MyConnection.getResponse(RobotManager.getUrl(content), new GetConnection() {            @Override            public void onFinish(String response) {                ContentBean contentBean = new ContentBean();                Log.e("getResult",response);                Message msg = new Message();                Bundle data = new Bundle();                Gson gson = new Gson();                contentBean = gson.fromJson(response,ContentBean.class);	//用Gson将返回内容序列化为ContentBean对象。                if(contentBean.getResult()==0){data.putString("result",contentBean.getContent());                }else{data.putString("result","我听不懂你在说什么呀!");                }                msg.setData(data);                msg.what = 1;                handler.sendMessage(msg);            }            @Override            public void onError(Exception e) {                e.printStackTrace();            }        });    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initMsgs(); // 初始化消息数据        inputText = findViewById(R.id.input_text);        send =  findViewById(R.id.send);        msgRecyclerView =  findViewById(R.id.msg_recycler_view);        LinearLayoutManager layoutManager = new LinearLayoutManager(this);        msgRecyclerView.setLayoutManager(layoutManager);        adapter = new MsgAdapter(msgList);        msgRecyclerView.setAdapter(adapter);        send.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                String content = inputText.getText().toString();                if (!"".equals(content)) {Msg msg = new Msg(content, Msg.TYPE_SENT);msgList.add(msg);getInter(content);Log.e("url",RobotManager.getUrl(content));adapter.notifyItemInserted(msgList.size() - 1); // 当有新消息时,刷新ListView中的显示msgRecyclerView.scrollToPosition(msgList.size() - 1); // 将ListView定位到最后一行inputText.setText(""); // 清空输入框中的内容                }            }        });    }    private void initMsgs() {        Msg msg1 = new Msg("我是菲菲,快来和我聊天吧* ( ´͈ ᵕ `͈ )◞♡", Msg.TYPE_RECEIVED);        msgList.add(msg1);    }}
  • 由于接口返回的数据是Json格式,所以我们需要对Json进行解析,本文采用google的Gson库对其进行解析,将接口内容序列化为一个类ContentBean。解析过程见上面代码。
public class ContentBean {    /**     * result : 0     * content : [04月08日] 邯郸天气:小雨,白天 17℃,夜晚 9℃,微风,<3级转3-4级     */    private int result;    private String content;    public int getResult() {        return result;    }    public void setResult(int result) {        this.result = result;    }    public String getContent() {        return content;    }    public void setContent(String content) {        this.content = content;    }}

(5)其余代码

  • Msg和MsgAdapter用于解析消息是发送方还是接收方
    并展示在消息列表上
  • Msg
public class Msg {    public static final int TYPE_RECEIVED = 0;    public static final int TYPE_SENT = 1;    private String content;    private int type;    public Msg(String content, int type) {        this.content = content;        this.type = type;    }    public String getContent() {        return content;    }    public int getType() {        return type;    }}
  • MsgAdapter
public class MsgAdapter extends RecyclerView.Adapter<MsgAdapter.ViewHolder> {    private List<Msg> mMsgList;    static class ViewHolder extends RecyclerView.ViewHolder {        LinearLayout leftLayout;        LinearLayout rightLayout;        TextView leftMsg;        TextView rightMsg;        public ViewHolder(View view) {            super(view);            leftLayout = (LinearLayout) view.findViewById(R.id.left_layout);            rightLayout = (LinearLayout) view.findViewById(R.id.right_layout);            leftMsg = (TextView) view.findViewById(R.id.left_msg);            rightMsg = (TextView) view.findViewById(R.id.right_msg);        }    }    public MsgAdapter(List<Msg> msgList) {        mMsgList = msgList;    }    @Override    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.msg_item, parent, false);        return new ViewHolder(view);    }    @Override    public void onBindViewHolder(ViewHolder holder, int position) {        Msg msg = mMsgList.get(position);        if (msg.getType() == Msg.TYPE_RECEIVED) {            // 如果是收到的消息,则显示左边的消息布局,将右边的消息布局隐藏            holder.leftLayout.setVisibility(View.VISIBLE);            holder.rightLayout.setVisibility(View.GONE);            holder.leftMsg.setText(msg.getContent());        } else if(msg.getType() == Msg.TYPE_SENT) {            // 如果是发出的消息,则显示右边的消息布局,将左边的消息布局隐藏            holder.rightLayout.setVisibility(View.VISIBLE);            holder.leftLayout.setVisibility(View.GONE);            holder.rightMsg.setText(msg.getContent());        }    }    @Override    public int getItemCount() {        return mMsgList.size();    }}

尾声

  • 以上代码可复制使用,但其中有一些图片,类库什么的需要自行导入,完整代码见geithub:点击此处直达
  • 该项目是我早期项目,只是为了记录当初的开发流程,所以并不存在什么设计模式,代码结构也比较乱,注释也比较少,如果有任何问题,欢迎添加我的QQ询问!

Tip:本文代码,内容均个人原创,个别代码曾经参考过资料,如涉及侵权请联系作者删除。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
API对接实战
【java】接口的作用|实例讲解java接口
深入Struts2
2.1.3 不用模式的解决方案
高德地图api之location定位服务 | 学步园
SignalR 实时通知消息并行推送和批量存储实现
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服