安卓网络访问解析XML

安卓网络访问

点击获取完整APK资源下载地址

http://download.csdn.net/detail/mjdouble/9694686

本次实验基于一个如下网站
http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?op=getWeather
这里写图片描述


设置一个app界面,输入城市名,即查询该CityCode的天气情况,对返回的XML文件进行解析后,在app中显示。如下(这就是最后的结果啦,当然根据你输入的城市不同,结果不同,输入城市名和城市代号都是可以识别的)
T T理工男,请无视我的界面设计

这里写图片描述

XML文件内容如下所示(本是要就要解析xml文件获取string标签中的内容,按我们喜欢的格式在app中显示。)

xml

APP开始界面如下所示(那啥,这些都是我初始默认的不用管,就这么个布局)

俺婆婆
首先AS新建一个工程network,布局啥的该设计就设计好,直接从MainActivity开始吧。首先,所有事件,都是基于点击search按钮来进行,点击按钮,首先要判断的是,有没有网络连接,网络连接正常,才回去访问这个url.
本次实验我们固定String url=”http://ws.webxml.com.cn/WebServices/WeatherWS.asmx/getWeather”;
这个跟上面是不同的,可以点击访问一下看看。我们最终需要的是http://ws.webxml.com.cn/WebServices/WeatherWS.asmx/getWeather?theCityCode=2350&theUserID=ecefcf4c81b847a189ff94a159d54dd0(试了好久。)比url多了俩个参数theCityCode和theUserID,就是根据我们的输入城市不同,会请求到不同的url
第一步在 manifest 中添加网络访问权限:

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

检查网络连接是否正常:ConnectivityManager主要管理和网络连接相关的操作 。getActiveNetworkInfo() 方法返回一个 NetworkInfo实例,它表示可以找到的第一个已连接的网络接口,如果返回 null,则表示没有已连接的网络接口(意味着网络连接不可用)
在点击按钮后进行判断,网络访问,则用sendRequestWithHttpURLConnection();函数进行HTTP请求建立连接

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ConnectivityManager connMgr =(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
                if(networkInfo!= null && networkInfo.isConnected())
                {
                    Toast.makeText(MainActivity.this, "you 网络访问", Toast.LENGTH_SHORT).show();

                    sendRequestWithHttpURLConnection();
                }
                else
                    Toast.makeText(MainActivity.this, "无 网络访问", Toast.LENGTH_SHORT).show();

            }
        });
    }

对于HTTP函数,由于网络访问,是比较耗时的操作,所以开个线程慢慢的跑啊跑,不要影响到主线程的耗时,蓝后conection首先要做到就是对我们这次的URL尝试建立连接,然后设置你申请访问的时候的一些超时读取,超时请求的函数等,这些都在HttpURLConnection类中已经申明。然后用DataOutputStream 把我们在app中的输入citycode值,转为字节流传给网页,该网页会作为参数进行递交。后台会把这个参数和之前的URL结合一起组成一个有参数的URL访问。这样才是一个完整的connection。如果你单独访问URL会提示

缺少参数: theCityCode

访问一个网页,正确建立连接时返回的request=200,假如报错,根据request的数值自己百度报错类型解决即可。用InputStream来获取返回的xml文件的字节流吧,(应该是)然后一顿操作变成BufferedReader ,用StringBuilder 读取每一行,再转为字符串来给我们操作= =,这里懵逼了。这边获取了字符串形式的xml文件,主要用于来更新我们APP的UI界面,所以通过Handler来进行,handler.sendEmptyMessage(1);传给消息给他,你可以理解为类似广播的性质,其实是一个对于handler里面一个队列的无限的loop,队列中一有东西进来,就会触发handler进行操作,所以实时的吧,最后吧连接断掉,开启线程。

private void sendRequestWithHttpURLConnection()
    {
        new Thread(new Runnable() {
            @Override
            public void run() {
                HttpURLConnection connection=null;
                try{
                    Log.d("Tag","begin connectin");
                    connection=(HttpURLConnection)((new URL(url).openConnection()));
                    connection.setRequestMethod("POST");
                    connection.setReadTimeout(8000);
                    connection.setConnectTimeout(8000);
                    String request=city.getText().toString();
                    request= URLEncoder.encode(request,"utf-8");
                    connection.connect();

                    DataOutputStream out=new DataOutputStream(connection.getOutputStream());
                    out.writeBytes("theCityCode="+request+"&theUserID=ecefcf4c81b847a189ff94a159d54dd0");//theUserID是本人在那个网站申请的ID,暂时应该还可以用
                    int back =connection.getResponseCode();
                    Log.d("Tag","The response is"+back);
                    InputStream in=connection.getInputStream();
                    BufferedReader reader=new BufferedReader(new InputStreamReader(in));
                    StringBuilder response=new StringBuilder();
                    String line=new String();
                    while((line=reader.readLine())!=null)
                    {
                        response.append(line);
                    }
                    Message message=new Message();
                    //message.what=1;
                    //message.obj=parseXMLWithPull(response.toString());
                    handler.sendEmptyMessage(1);
                    r=new String();
                    r=response.toString();
                    Log.d("Tag",response.toString());
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                    Log.d("Tag","err");
                }
                finally {
                        connection.disconnect();
                }

            }
        }).start();
    }

handler函数,就是接收到一个meeage后根据他是什么来选择操作类型,然后就是根据你电脑去访问,看看他的xml格式,按照格式,用你java学到的一系列字符串数组的方法来进行分割,提取想要的在界面中显示
这里面有一个parseXMLWithPull函数,就是用来提取xml文件里的每个标签的之间的内容然后都扔到一个 ArrayList list=new ArrayList();里面。先要什么就去list里面提取就行,当然也可以用一个map设置,存的时候就处理好key-value,提取的时候就会比较简单,这边我写好了,也就不想改了 T T;然后你就把get到的字符串setText到你的view控件上就ok了。
listview其实也是根据你读到的String,来放到适配器里,动动咱们的小脑瓜应该挺简单的。

    private Handler handler=new Handler()
    {
        public void handleMessage(Message message){
            Log.d("Tag","handle begin");
            switch(message.what)
            {
                case 1:
                {
                    String a=r;
                    Log.d("Tag","String a "+r);
                    parseXMLWithPull(r);
                    String t=list.get(0).toString();
                    cityout.setText(t);
                    t=list.get(3).toString();
                    update.setText(t+" 更新");
                    t=list.get(4).toString();
                    String son= t.substring(7);
                    String[] cut=son.split(";");
                    fengli.setText(cut[1]);
                    shidu.setText(cut[2]);
                    wendu.setText(cut[0]);
                    //Log.d("Tag","arraylist  "+son);
                    t=list.get(13);
                    bodong.setText(t);
                    t=list.get(5);
                    cut=t.split("。");
                    zhiliang.setText(cut[1]);
                    t=list.get(6);
                    cut=t.split("。");
                    List<Map<String, Object>> dataa=  new ArrayList<>();
                    simpleAdapter=new SimpleAdapter(MainActivity.this,dataa,R.layout.item,new String[]{"name"},new int[]{R.id.name});
                    for(int i=0;i<cut.length;i++)
                    {
                        Map<String, Object> temp = new LinkedHashMap<>();
                        temp.put("name",cut[i]);
                        dataa.add(temp);
                    }
                    listview.setAdapter(simpleAdapter);                                   
                    break;
                }
            }
        }
    };

说一下parseXMLWithPull函数吧。对于我们现在一个字符串形式表示的xml文件内容,先用函数转为XmlPullParser 对象实例,然后XmlPullParser 里面有现成的函数调用,会根据标签来一个个读入parser.getEventType();就是读取标签类型,在后面的类中的文件都有申明,有兴趣alt+函数名,自己可以一级一级跳下去看。每次判断标签,我们这次只要标签名为string的具体内容。每次获取后,都add到 list 里面

 private  void parseXMLWithPull(String xmlData){
        try{
            Log.d("TAG", "parseXMLWithPull: begin");
            XmlPullParserFactory factory=XmlPullParserFactory.newInstance();
            XmlPullParser parser=factory.newPullParser();
            parser.setInput(new StringReader(xmlData));
            int eventType=parser.getEventType();
            list=new ArrayList<String>();
            //Log.d("Tag","eventType"+eventType);
            while(eventType!=XmlPullParser.END_DOCUMENT){
            switch (eventType)
            {
                case XmlPullParser.START_TAG:
                    if("string".equals(parser.getName())){
                        String str=parser.nextText();
                        list.add(str);
                        //Log.d("Tag","Get String "+str);
                    }
                    break;
                case XmlPullParser.END_TAG:
                    break;
                default:break;
            }
                eventType=parser.next();
                //Log.d("Tag","eventType"+eventType);
            }
        }
        catch (Exception e)
        {
            Log.d("Tag ","ERR "+e);
        }
    }

转载请注明地址!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值