Android---Volley请求天气接口JSON解析

本篇文章主要内容为:运用Volley框架进行网络请求,调用百度天气API并对得到的json数据解析。
天气接口为百度API的,地址:http://apistore.baidu.com/apiworks/servicedetail/478.html。

首先选择要查询天气的城市,然后根据城市名,得到该城市七日天气数据。其中用的城市列表是参考网上的,
原地址:http://www.okbase.net/file/item/33385

1.程序主页面:main.xml

主页面上有一个按钮,点击后进入城市列表选择城市,一个TextView显示标题,一个ListView显示城市七日天气数据。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#F0F0F0"
    android:orientation="vertical" >

    <Button
        android:id="@+id/selectBtn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="选择城市" />

    <TextView 
        android:id="@+id/tv_city"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:textSize="18sp"
        android:textColor="#000"
        />

    <ListView 
        android:id="@+id/list_weather"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:dividerHeight="1dp"
        android:divider="#E0E0E0"
        />

</LinearLayout>

2.ListView 每一项布局文件weather_item.xml

将解析到的数据格式化显示。

<?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="80dp" 
    android:padding="10dp">

    <TextView 
        style="@style/txtStyle"
        android:id="@+id/tv_date"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:text="2016-3-16"
        />

    <TextView 
        style="@style/txtStyle"
        android:id="@+id/tv_status"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/tv_date"
        android:layout_marginLeft="100dp"
        android:gravity="center_horizontal"
        android:text="多云"
        />

    <TextView 
        style="@style/txtStyle"
        android:id="@+id/tv_max"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_toRightOf="@id/tv_date"
        android:layout_below="@id/tv_status"
        android:layout_marginLeft="20dp"
        android:gravity="center_vertical"
        android:text="15"
        />

    <TextView 
        style="@style/txtStyle"
        android:id="@+id/tv_min"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_toRightOf="@id/tv_max"
        android:layout_below="@id/tv_status"
        android:layout_marginLeft="60dp"
        android:gravity="center_vertical"
        android:text="6"
        />

</RelativeLayout>

3.MainActivity.java文件

主要业务是选择城市,通过Volley向天气接口发出请求,解析返回的json数据。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import com.android.volley.AuthFailureError;
import com.android.volley.Request.Method;
import com.android.volley.RequestQueue;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.dialog.CustomProgressDialog;

public class MainActivity extends Activity {

    private Button btn;
    private TextView tv_city;
    private ListView list_weather;
    private WeatherAdapter mAdapter;
    private static final int REQUEST_CITY = 0;
    private RequestQueue mQueue; // volley的请求队列
    private static final String apikey = "1a03add595481b304fdef3660c02d97d";    //此处为你申请的apikey
    private List<Map<String, String>>weatherDatas = new ArrayList<Map<String,String>>();
    private String date,max,min,tv_status;
    private CustomProgressDialog processDialog;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mQueue = Volley.newRequestQueue(getApplicationContext());   //新建请求队列

        tv_city = (TextView) findViewById(R.id.tv_city);
        list_weather = (ListView) findViewById(R.id.list_weather);

        btn = (Button) findViewById(R.id.selectBtn);
        btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, CityList.class);

                //因为要接收城市列表中选择的城市,所以此处用startActivityForResult
                startActivityForResult(intent, REQUEST_CITY);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        switch (requestCode) {
        case REQUEST_CITY:
            if (resultCode == RESULT_OK) {
                showProcessDialog();
                String cityName = data.getStringExtra("cityName");

                //去掉最后一个字"市",因为请求参数中不包含"市"字,(例如:参数是北京,而不是北京市)  所以数据库中的有些城市查询不到
                String city = cityName.substring(0, cityName.length() - 1);
                weatherDatas.clear();       //这句话要加上,否则新的数据会加在原来数据的后面
                getWeather(city);
            }
            break;

        default:
            break;
        }
    }

    private void getWeather(final String city) {
        String url = "http://apis.baidu.com/heweather/weather/free?city="+city;

        //请求成功
        Listener<String>listener = new Listener<String>() {
            @Override
            public void onResponse(String arg0) {
                dismissProcessDialog();
                Log.d("onResponse", arg0);
                tv_city.setText(city + "市七日天气");
                parseData(arg0);
                mAdapter = new WeatherAdapter(MainActivity.this, weatherDatas);
                list_weather.setAdapter(mAdapter);
            }

        };

        //请求失败
        ErrorListener errorListener = new ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError arg0) {
                Log.d("onErrorResponse", arg0.toString());
                tv_city.setText("暂不支持该城市!");
            }
        };

        StringRequest request = new StringRequest(Method.GET, url,
                listener, errorListener){

            @Override
            public Map<String, String> getHeaders()
                    throws AuthFailureError {
                Map<String, String>mHeaders = new HashMap<String, String>();
                mHeaders.put("apikey", apikey);
                return mHeaders;
            }

        };
        mQueue.add(request);      //加入请求队列
    }


    //对返回的json数据进行解析
    private void parseData(String arg0) {
        try {
            JSONArray results = new JSONObject(arg0).optJSONArray("HeWeather data service 3.0");
            JSONArray daily_forecast = results.optJSONObject(0).optJSONArray("daily_forecast");
            for(int i = 0; i < daily_forecast.length(); i++){
                HashMap<String, String>map = new HashMap<String, String>();

                date = daily_forecast.optJSONObject(i).optString("date");
                tv_status = daily_forecast.optJSONObject(i).optJSONObject("cond").optString("txt_d");
                max = daily_forecast.optJSONObject(i).optJSONObject("tmp").optString("max");
                min = daily_forecast.optJSONObject(i).optJSONObject("tmp").optString("min");

                map.put("tv_date", date);
                map.put("tv_status", tv_status);
                map.put("tv_max", max);
                map.put("tv_min", min);

                weatherDatas.add(map);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public void showProcessDialog() {

        if (processDialog == null){
            processDialog = new CustomProgressDialog(this,"loading...");
            processDialog.show();
            processDialog.setCanceledOnTouchOutside(true);
        }
        if (processDialog.isShowing() == false)
            processDialog.show();
    }

    public void dismissProcessDialog() {

        if (processDialog != null)
            processDialog.dismiss();
    }

}

4.天气数据适配器WeatherAdapter.java

public class WeatherAdapter extends BaseAdapter {

    private Context mContext;
    private List<Map<String, String>>datas;
    private LayoutInflater inflater;

    public WeatherAdapter(Context mContext, List<Map<String, String>> datas) {
        this.mContext = mContext;
        this.datas = datas;
        inflater = LayoutInflater.from(mContext);
    }

    @Override
    public int getCount() {
        return datas.size();
    }

    @Override
    public Object getItem(int arg0) {
        return datas.get(arg0);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;

        if(convertView == null){
            convertView = inflater.inflate(R.layout.weather_item, null);
            holder = new ViewHolder();
            holder.tv_date = (TextView) convertView.findViewById(R.id.tv_date);
            holder.tv_status = (TextView) convertView.findViewById(R.id.tv_status);
            holder.tv_max = (TextView) convertView.findViewById(R.id.tv_max);
            holder.tv_min = (TextView) convertView.findViewById(R.id.tv_min);

            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }

        holder.tv_date.setText(datas.get(position).get("tv_date"));
        holder.tv_status.setText(datas.get(position).get("tv_status"));
        holder.tv_max.setText("最高温:" + datas.get(position).get("tv_max"));
        holder.tv_min.setText("最低温:" + datas.get(position).get("tv_min"));

        return convertView;
    }

    static class ViewHolder{
        private TextView tv_date;
        private TextView tv_status;
        private TextView tv_max;
        private TextView tv_min;
    }
}

城市列表部分的代码请见源码

5.运行截图

这里写图片描述
这里写图片描述

6.源码下载

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值