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.源码下载
相关文章推荐
- JNI签名-android
- Android基础-Android的生命周期
- 完成一个安卓小项目之后的小感悟
- Android 之SQLite(增 删 改 查)
- 总结开始学习Android至今(大概有一周)
- Android图片海报制作-MaterialDesign使用
- Android xmlns 的作用及其自定义
- 框架模式MVC 在Android中的使用
- Android,在LinearLayout中动态添加TextView,几点疑问
- android 资源(开源项目、library,框架{完善中})
- Android的进化史
- Robotium导入被测源码遇到问题 had used a different Landroid/support/v4/view/ViewPager
- 跟着Google学Android —— 0 积跬步 以至千里
- Android-Service
- Android基础_日期选择器DatePickerDialog时间选择器TimePickerDialog隐藏输入法
- android 常见的补间动画
- 44.Android之Shape设置虚线、圆角和渐变学习
- Android自定义可控最大宽高的Layout
- 高德地图调用中出现的问题
- android view学习(一)