当前位置: 移动技术网 > 移动技术>移动开发>Android > 大作业(二)

大作业(二)

2019年04月21日  | 移动技术网移动技术  | 我要评论

3.2使用http访问网络

android上发送http请求的方式一般有两个,httpurlconnection和httpclient,在这里我们使用httpurlconnection。

首先需要获取到httpurlconnection的实例,一般只需new出一个url对象,并传入目标的网络地址,然后调用一下openconnection()方法即可,如下所示:

url url = new url(“https://www.baidu.com”);

httpurlconnection connection =(httpurlconnection) url.openconnection();

得到了httpurlconnection的实例之后,我们可以设置一下http请求所使用的方法。常用的方法主要有两个,get和post。get表示希望从服务器那里获取数据,而post则表示希望提交数据给服务器。接下来就可以进行设置连接超时、读取超时的毫秒数;之后再调用getinputstream()方法就可以获取到服务器返回的输入流了,剩下的任务就是对输入流进行读取;最后将连接关闭掉。

下面我们就在com.wyd.search.common包中新建httputils.java类,代码如下所示:

public final class httputils {
    private static final string log_tag = "httputils connect tag";

    public static string openurl(string url, string method, bundle params,
        string enc) {
        string response = null;

        if (method.equals("get")) {
            url = url + "?" + encodeurl(params);
        }

        try {
            log.d(log_tag, "url:" + url);

            httpurlconnection conn = (httpurlconnection) new url(url).openconnection();
            conn.setrequestproperty("user-agent",
                system.getproperties().getproperty("http.agent"));
            conn.setreadtimeout(10000); //设置超时时间

            if (method.equals("post")) {
                conn.setrequestmethod("post");
                conn.setdooutput(true);
                conn.getoutputstream().write(encodeurl(params).getbytes("utf-8"));
            }

            response = read(conn.getinputstream(), enc);
        } catch (exception e) {
            log.e(log_tag, e.getmessage());
            throw new runtimeexception(e.getmessage(), e);
        }

        return response;
    }

    private static string read(inputstream in, string enc)
        throws ioexception {
        stringbuilder sb = new stringbuilder();
        inputstreamreader isr = null;
        bufferedreader r = null;

        if (enc != null) {
            //按指定的编码读入流
            r = new bufferedreader(new inputstreamreader(in, enc), 1000);
        } else {
            //按默认的编码读入
            r = new bufferedreader(new inputstreamreader(in), 1000);
        }

        for (string line = r.readline(); line != null; line = r.readline()) {
            sb.append(line);
        }

        in.close();

        return sb.tostring();
    }

    public static string encodeurl(bundle parameters) {
        if (parameters == null) {
            return "";
        }

        stringbuilder sb = new stringbuilder();
        boolean first = true;

        for (string key : parameters.keyset()) {
            if (first) {
                first = false;
            } else {
                sb.append("&");
            }

            sb.append(key + "=" + parameters.getstring(key));
        }

        return sb.tostring();
    }
}

3.3查询活动的搜索条件

我们在查询的时候,会有一些限制条件,比如说查询的ip是否合法、手机号码位数是否够......因此要进行一些限制。

我们在com.wyd.search.common包中新建activityutils类,代码如下:

public final class activityutils {
    public static void showdialog(context context, string button, string title,
        string message) {
        new alertdialog.builder(context).settitle(title).setmessage(message)
                                        .setneutralbutton(button, null).create()
                                        .show();
    }

    //校验str是否为空或为""
    public static boolean validatenull(string str) {
        if ((str == null) || str.equals("")) {
            return false;
        } else {
            return true;
        }
    }

    //校验str中是否全部是数字,用到了正则表达式
    public static boolean validatenumber(string str) {
        pattern pattern = pattern.compile("[0-9]");
        matcher matcher = pattern.matcher(str);

        return matcher.matches();
    }

    //校验ip是否合法
    public static boolean validateip(string str) {
        pattern pattern = pattern.compile("[0-9],.");
        matcher matcher = pattern.matcher(str);

        return matcher.matches();
    }
}

4 查询工具创建

在第二阶段,我们进行具体实体类的,首先我们需要申请相应的接口数据,这个我们可以轻松在聚合数据网站上得到,然后把具体的功能一个个实现,我们在第一步新建的包中新建相应的查询实体类。具体实现如下:

4.1快递单号查询

在com.wyd.search.ems包中新建ems.java类,代码如下:

public class ems implements serializable {
private static final long serialversionuid = 1l;
// 变量声明
private string message; //消息体
private string time; //时间
private string context; //状态
private string status; //返回值状态:0,查询失败;1:查询成功
private string company; //快递公司名称
private string order; //单号

接下来新建快递查询的监听类emslistener,代码如下:

public class emssearch extends activity {
    private spinner emscompanies;
    private edittext emsorder;
    private resources res;
    private string[] emscodes;
    private int pos = 0;
    private string selectedcom;
    private search search;@override public void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        this.requestwindowfeature(window.feature_no_title);
        setcontentview(r.layout.ems);
        res = this.getresources();
        emscodes = res.getstringarray(r.array.ems_code);
        emsorder = (edittext) this.findviewbyid(r.id.ems_order);
        emscompanies = (spinner) this.findviewbyid(r.id.ems_com);
        arrayadapter < charsequence > adapter = arrayadapter.createfromresource(this, r.array.ems_company, android.r.layout.simple_spinner_item);
        adapter.setdropdownviewresource(android.r.layout.simple_spinner_dropdown_item);
        emscompanies.setadapter(adapter);
        emscompanies.setonitemselectedlistener(selectedlistener);
        search = new search();
    }
    private adapterview.onitemselectedlistener selectedlistener = new adapterview.onitemselectedlistener() {
        public void onitemselected(adapterview < ?>parent, view v, int position, long id) {
            // 用户选择了,记录下用户选择的公司所对应的代码
            pos = position;
            selectedcom = (string) parent.getitematposition(position);
        }
        public void onnothingselected(adapterview < ?>parent) {
            // todo auto-generated method stub
        }
    };
    public string getcode() {
        return emscodes[pos - 1]; //因为城市spinner中多了一个请选择
    }
    //检验是否选择了一个快递公司
    public boolean validateselect() {
        if (pos < 1 || pos > emscodes.length) {
            return false;
        } else {
            return true;
        }
    }
    public void onclick(view v) {
        if (v.getid() == r.id.ems_search) {
            string order = this.emsorder.gettext().tostring().trim();
            if (this.validateselect()) {
                if (activityutils.validatenull(order)) {
                    //校验成功
                    string companycode = this.getcode();
                    bundle bundle = new bundle();
                    bundle.putstring("company", selectedcom);
                    bundle.putstring("order", order);
                    this.getintent().putextras(bundle); //记录下公司和单号
                    emslistener listener = new emslistener(this);
                    search.asyncrequest(companycode, order, listener);
                } else {
                    activityutils.showdialog(this, res.getstring(r.string.ok), res.getstring(r.string.tip), res.getstring(r.string.ems_order_error));
                }
            } else {
                activityutils.showdialog(this, res.getstring(r.string.ok), res.getstring(r.string.tip), res.getstring(r.string.ems_noselect));
            }
        }
    }
}

最后就是查询后返回相应的数据,新建searchresult.java,代码如下:

public class searchresult extends activity {

    private textview emscompany,
    emsorder,
    emstime,
    emscontext;
    private resources res;
    public void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        this.requestwindowfeature(window.feature_no_title);
        setcontentview(r.layout.ems_info);
        this.emscompany = (textview) this.findviewbyid(r.id.ems_company);
        this.emsorder = (textview) this.findviewbyid(r.id.ems_order);
        this.emstime = (textview) this.findviewbyid(r.id.ems_time);
        this.emscontext = (textview) this.findviewbyid(r.id.ems_context);
        res = this.getresources();
        this.showresult();
    }
    private void showresult() {
        bundle bundle = this.getintent().getextras();
        ems ems = (ems) bundle.getserializable("ems");
        if (ems != null) {
            if (ems.getstatus().equals("1")) {
                this.emscompany.settext(ems.getcompany());
                this.emsorder.settext(ems.getorder());
                this.emstime.settext(ems.gettime());
                this.emscontext.settext(ems.getcontext());
            } else {
                activityutils.showdialog(this, res.getstring(r.string.ok), res.getstring(r.string.tip), ems.getmessage());
            }
        } else {
            activityutils.showdialog(this, res.getstring(r.string.ok), res.getstring(r.string.tip), res.getstring(r.string.ems_fail));
        }
    }
}

4.1手机号归属地查询

我们首先在com.wyd.search.telephone包中新建手机号归属地查询的实体类telephone.java,代码如下:

public class telephone implements serializable{
private static final long serialversionuid = 1l;
private string mobile; //
private string queryresult; //返回结果
private string province; //省份
private string city; //城市
private string areacode; //区号
private string postcode; //
private string corp; //
private string card; //卡类型

我们可在聚合数据网站上申请数据,然后应用网站提供的接口,通过对申请的数据得知,手机号码的查询涵盖中国移动、中国联通和中国电信,查询的结果包括省份、城市、区号和卡类型。

接下来新建快递查询的监听类telephonelistener,代码如下:

public class telephonelistener implements requestlistener {
    private telephonesearch context;
    private progressdialog progress;
    private resources res;
    public telephonelistener(telephonesearch context) {
        this.context = context;
        res = context.getresources();
        progress = progressdialog.show(context, res.getstring(r.string.tel_searching), res.getstring(r.string.getting));
        progress.show();
    }@override public void oncomplete(final string result) {
        this.context.runonuithread(new runnable() {@override public void run() {
                intent intent = new intent();
                bundle bundle = new bundle();
                bundle.putserializable("telephone", parsejson(result));
                intent.putextras(bundle);
                intent.setclass(context, searchresult.class);
                progress.dismiss();
                context.startactivity(intent);
            }
        });
    }
    public void onexception(exception e) {
        this.context.runonuithread(new runnable() {
            public void run() {
                if (progress != null) {
                    progress.dismiss();
                }
                activityutils.showdialog(context, res.getstring(r.string.ok), res.getstring(r.string.tip), res.getstring(r.string.get_nothing));
            }
        });
    }
    public telephone parsejson(string jsonstr) {
        telephone tel = null;
        jsonstr = jsonstr.substring(14, jsonstr.length() - 2);
        try {
            tel = new telephone();
            jsonobject jsonobj = new jsonobject(jsonstr);
            tel.setmobile(jsonobj.getstring("mobile"));
            tel.setqueryresult(jsonobj.getstring("queryresult"));
            tel.setprovince(jsonobj.getstring("province"));
            tel.setcity(jsonobj.getstring("city"));
            tel.setareacode(jsonobj.getstring("areacode"));
            tel.setpostcode(jsonobj.getstring("postcode"));
            tel.setcorp(jsonobj.getstring("corp"));
            tel.setcard(jsonobj.getstring("card"));
        } catch(jsonexception e) {
            log.e(log_tag, e.getmessage());
        }
        return tel;
    }
    private static final string log_tag = "telephonelistener";
}

我们从聚合数据网站上获得的数据可以使用xml和json两种方法解析,这里我们解析成json格式数据,因为相对于xml,json的主要优势在于它的体积更小,在网络上传输的时候可以更省流量。

然而,解析json数据的方法也有很多,我们使用jsonobject,首先将http请求的地址加上,然后在得到了服务器返回的数据后调用parsejsonwithjsonobject()方法来解析数据。每个jsonobject对象中包含mobile、province、areacode和card等这些数据,接下来只需要调用getstring()方法将这些数据取出,并打印出来即可。

最后就是更新ui的问题,要将解析出来的数据显示出来,代码如下:

public class searchresult extends activity {
    private textview mobile,
    province,
    city,
    areacode,
    postcode,
    card;
    public void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        this.requestwindowfeature(window.feature_no_title);
        setcontentview(r.layout.telephone_info);
        mobile = (textview) this.findviewbyid(r.id.telephone_mobile);
        province = (textview) this.findviewbyid(r.id.telephone_province);
        city = (textview) this.findviewbyid(r.id.telephone_city);
        areacode = (textview) this.findviewbyid(r.id.telephone_areacode);
        postcode = (textview) this.findviewbyid(r.id.telephone_postcode);
        card = (textview) this.findviewbyid(r.id.telephone_card);
        this.showresult();
    }

    public void showresult() {
        intent intent = this.getintent();
        bundle bundle = intent.getextras();
        telephone tel = (telephone) bundle.getserializable("telephone");
        if (tel != null) {
            mobile.settext(tel.getmobile());
            province.settext(tel.getprovince());
            city.settext(tel.getcity());
            areacode.settext(tel.getareacode());
            postcode.settext(tel.getpostcode());
            card.settext(tel.getcard());
        }
    }
}

4.3天气的查询

我们首先在com.wyd.search.weather包中新建手机号归属地查询的实体类weather.java,代码如下:

public class weather implements serializable {
private static final long serialversionuid = 13835783478884l;
private string day; //星期
private string date; //日期
private string low; //最低温度
private string high; //最高温度
private string code; //天气状况码
private string text; //天气状况码,对应的天气类型

接着我偶们继续新建search类,代码如下:

public class search {
    //这里使用的是雅虎天气查询url
    private static final string http_url = "https://weather.yahooapis.com/forecastrss";
    private static final string method = "get";
    private static final string log_tag = "com.search.weather.search";

    public string request(string woeid) {
        if (woeid != null) {
            bundle params = new bundle();
            params.putstring("w", woeid); //城市对应的id
            params.putstring("u", "c"); //华氏温度是f,摄氏温度是c。这里采用摄氏度
            return httputils.openurl(http_url, method, params, null);
        } else {
            return null;
        }
    }
    //异步封装
    public void asyncrequest(final string city, final requestlistener listener) {
        //子线程中更新ui
        new thread(new runnable() {@override public void run() {
                try {
                    string response = request(city);
                    listener.oncomplete(response);
                } catch(exception e) {
                    log.e(log_tag, e.getmessage());
                    listener.onexception(e);
                }
            }
        }).start();
    }
}

下面创建weatherlistener.java,代码如下:

public class weatherlistener implements requestlistener {
    private weathersearch context;
    private progressdialog progress;
    private resources res;
    public weatherlistener(weathersearch context) {
        this.context = context;
        res = this.context.getresources();
        this.progress = progressdialog.show(context, res.getstring(r.string.wea_searching), res.getstring(r.string.getting));
        this.progress.show();
    }
    public void oncomplete(final string result) {
        context.runonuithread(new runnable() {
            public void run() {
                try {
                    inputstream is = null;
                    is = new bytearrayinputstream(result.getbytes("utf-8"));
                    list < weather > results = weatherpullparser.getdata(is);
                    if (results.size() >= 2) {
                        weather today = results.get(0);
                        weather tomorrow = results.get(1);
                        intent intent = new intent();
                        bundle bundle = new bundle();
                        bundle.putserializable("today", today);
                        bundle.putserializable("tomorrow", tomorrow);
                        intent.putextras(bundle);
                        intent.setclass(context, searchresult.class);
                        if (progress != null) {
                            progress.dismiss();
                        }
                        context.startactivity(intent);
                    } else {
                        if (progress != null) {
                            progress.dismiss();
                        }
                        activityutils.showdialog(context, res.getstring(r.string.ok), res.getstring(r.string.tip), res.getstring(r.string.xml_error));
                    }

                } catch(unsupportedencodingexception e) {
                    log.e(log_tag, e.getmessage());
                    activityutils.showdialog(context, res.getstring(r.string.ok), res.getstring(r.string.tip), res.getstring(r.string.xml_error));
                }
            }
        });
    }
    public void onexception(final exception e) {
        context.runonuithread(new runnable() {@override public void run() {
                if (progress != null) {
                    progress.dismiss();
                }
                activityutils.showdialog(context, res.getstring(r.string.ok), res.getstring(r.string.tip), res.getstring(r.string.get_nothing));
            }
        });
    }
    private static final string log_tag = "weatherlistener";
}

然后我们就要对服务器返回的数据进行解析了,由于这里我们用的是雅虎天气提供的数据,所以这里我们运用pull的解析方式。

新建weatherpullparser.java,代码如下:

public class weatherpullparser {
    public static list < weather > getdata(inputstream reader) {
        list < weather > result = null;
        xmlpullparser parser = xml.newpullparser();
        weather wea = null;
        string tagname = null;
        try {
            parser.setinput(reader, "utf-8");
            int eventcode = parser.geteventtype(); //返回事件码类型
            while (eventcode != xmlpullparser.end_document) {
                switch (eventcode) {
                case xmlpullparser.start_document:
                    //初始化
                    result = new arraylist < weather > ();
                    break;
                case xmlpullparser.start_tag:
                    //一个元素的开始
                    tagname = parser.getname(); //获取当前标签的名称
                    if (tagname.equalsignorecase("forecast")) {
                        wea = new weather();
                        wea.setday(parser.getattributevalue(null, "day"));
                        wea.setdate(parser.getattributevalue(null, "date"));
                        wea.setlow(parser.getattributevalue(null, "low"));
                        wea.sethigh(parser.getattributevalue(null, "high"));
                        wea.settext(parser.getattributevalue(null, "text"));
                        wea.setcode(parser.getattributevalue(null, "code"));
                        result.add(wea);
                    }
                    break;
                }
                eventcode = parser.next(); //解析下一个元素
            }
        } catch(exception e) {
            log.e("weatherpullparser", e.getmessage());
        }
        return result;
    }
}

最后就是就是就将解析出阿里的数据显示出来,在这个包下新建searchresult.java,代码如下:

public class searchresult extends activity {
    private textview today,
    tomorrow,
    low1,
    low2,
    high1,
    high2;
    private resources res;
    public void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        this.requestwindowfeature(window.feature_no_title);
        setcontentview(r.layout.weather_info);
        today = (textview) this.findviewbyid(r.id.wea_today);
        tomorrow = (textview) this.findviewbyid(r.id.wea_tomorrow);
        low1 = (textview) this.findviewbyid(r.id.wea_low);
        low2 = (textview) this.findviewbyid(r.id.wea_low2);
        high1 = (textview) this.findviewbyid(r.id.wea_high);
        high2 = (textview) this.findviewbyid(r.id.wea_high2);
        res = this.getresources();
        this.showresult();
    }

    private void showresult() {
        intent intent = this.getintent();
        bundle bundle = intent.getextras();
        weather w_today = (weather) bundle.getserializable("today");
        weather w_tomorrow = (weather) bundle.getserializable("tomorrow");
        string unit = res.getstring(r.string.wea_unit);
        if (w_today != null) {
            string today_codition = this.getcondition(w_today.getcode()); //获取code对应的天气
            today.settext(today_codition);
            low1.settext(w_today.getlow() + unit);
            high1.settext(w_today.gethigh() + unit);
        }
        if (w_tomorrow != null) {
            string tommorrow_condition = this.getcondition(w_tomorrow.getcode());
            tomorrow.settext(tommorrow_condition);
            low2.settext(w_tomorrow.getlow() + unit);
            high2.settext(w_tomorrow.gethigh() + unit);
        }
    }
    //根据代码获取对应的天气信息。在weather的string-array中匹配
    private string getcondition(string code) {

        string[] weathers = res.getstringarray(r.array.weather);
        int temp = integer.parseint(code);
        if (temp < 48 && temp >= 0) {
            return weathers[temp];
        }
        return res.getstring(r.string.wea_undefine);
    }
}

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网