您的位置:首页 > 移动开发 > Android开发

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

2016-03-16 16:37 543 查看
本篇文章主要内容为:运用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.源码下载

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: