在前一篇《android json解析使用总结(一)》中介绍了一些关于json的基础知识,这一篇主要通过一个例子来实际演示一下android中如何解析从服务器或其他地方返回的json格式的数据。本次主要实现的是天气预报例子,里面主要涉及到“百度车联网API的使用”、“android Json解析”、等知识点,通过这个简单的demo,我们便可以熟悉如何解析json格式的数据。
首先,我们从“百度车联网API官网”中获取key,这是我们能否使用百度提供的服务的关键,具体的步骤不详述。通过这个API我们可以从浏览器端查看获取天气json格式的数据,如下所示:
天气URL:
http://api.map.baidu.com/telematics/v3/weather?location=常州&output=json&ak=ECIqazfmQFiEj0HAZKupo44x
{
"error": 0,
"status": "success",
"date": "2015-08-06",
"results": [
{
"currentCity": "常州",
"pm25": "68",
"index": [
{
"title": "穿衣",
"zs": "炎热",
"tipt": "穿衣指数",
"des": "天气炎热,建议着短衫、短裙、短裤、薄型T恤衫等清凉夏季服装。"
},
{
"title": "洗车",
"zs": "较适宜",
"tipt": "洗车指数",
"des": "较适宜洗车,未来一天无雨,风力较小,擦洗一新的汽车至少能保持一天。"
},
{
"title": "旅游",
"zs": "一般",
"tipt": "旅游指数",
"des": "天气较好,温度高,让人感觉热,幸好风比较大,能缓解炎热的天气。外出旅游请注意防暑降温和防晒。"
},
{
"title": "感冒",
"zs": "少发",
"tipt": "感冒指数",
"des": "各项气象条件适宜,发生感冒机率较低。但请避免长期处于空调房间中,以防感冒。"
},
{
"title": "运动",
"zs": "较适宜",
"tipt": "运动指数",
"des": "天气较好,但因气温较高且风力较强,请适当降低运动强度并注意户外防风。"
},
{
"title": "紫外线强度",
"zs": "中等",
"tipt": "紫外线强度指数",
"des": "属中等强度紫外线辐射天气,外出时建议涂擦SPF高于15、PA+的防晒护肤品,戴帽子、太阳镜。"
}
],
"weather_data": [
{
"date": "周四 08月06日 (实时:31℃)",
"dayPictureUrl": "http://api.map.baidu.com/images/weather/day/duoyun.png",
"nightPictureUrl": "http://api.map.baidu.com/images/weather/night/duoyun.png",
"weather": "多云",
"wind": "东南风3-4级",
"temperature": "36 ~ 27℃"
},
{
"date": "周五",
"dayPictureUrl": "http://api.map.baidu.com/images/weather/day/duoyun.png",
"nightPictureUrl": "http://api.map.baidu.com/images/weather/night/zhenyu.png",
"weather": "多云转阵雨",
"wind": "东南风3-4级",
"temperature": "35 ~ 27℃"
},
{
"date": "周六",
"dayPictureUrl": "http://api.map.baidu.com/images/weather/day/zhenyu.png",
"nightPictureUrl": "http://api.map.baidu.com/images/weather/night/zhenyu.png",
"weather": "阵雨",
"wind": "东风4-5级",
"temperature": "32 ~ 26℃"
},
{
"date": "周日",
"dayPictureUrl": "http://api.map.baidu.com/images/weather/day/zhenyu.png",
"nightPictureUrl": "http://api.map.baidu.com/images/weather/night/zhenyu.png",
"weather": "阵雨",
"wind": "东南风4-5级",
"temperature": "31 ~ 26℃"
}
]
}
]
}
通过以上对json格式的数据分析,我们可以知道:这里面既包含简单的JSONObject对象如“status、date”等节点,又包含复杂的JSONArray对象如“results、index、weather_data”节点,属于一个混合模型的json格式数据,这就需要我们一步一步来解析。
第一步,在本地新建一个WeatherBean用来存放解析到的天气数据,里面主要有“日期、风向、气温...”等字段
package com.lj.weather.model;
public class WeatherInfo {
private String dateWeek="";
private String nightPictureUrl="";
private String dayPictureUrl = "http://api.map.baidu.com/images/weather/day/duoyun.png";
private String weather = "多云转晴";
private String wind = "北风3-4级";
private String temperature = "22 ~ 12℃";
public WeatherInfo() {
};
public void setDateWeek(String dateWeek){
this.dateWeek=dateWeek;
}
public String getDateWeek(){
return dateWeek;
}
public void setdayPictureUrl(String dayPictureUrl){
this.dayPictureUrl=dayPictureUrl;
}
public String getdayPictureUrl(){
return dayPictureUrl;
}
public void setnightPictureUrl(String nightPictureUrl){
this.nightPictureUrl=nightPictureUrl;
}
public String getnightPictureUrl(){
return nightPictureUrl;
}
public void setweather(String weather){
this.weather=weather;
}
public String getweather(){
return weather;
}
public void setwind(String wind){
this.wind=wind;
}
public String getwind(){
return wind;
}
public void settemperature(String temperature){
this.temperature=temperature;
}
public String gettemperature(){
return temperature;
}
}
第二步,写一个工具类,用于网络请求根据url获取json格式的天气数据并将其转化为字符串输出,
package com.lj.weather.utils;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
public class JSONUtils {
public JSONUtils (){};
/**
* 通过url 向服务器发送请求,服务器返回json数据
* @param url
* url地址
* @return
* string类型的json格式数据
*/
public String getJSON(String url){
StringBuilder builder=new StringBuilder();
HttpGet httpRequest=new HttpGet(url);
try {
HttpResponse httpResponse = new DefaultHttpClient().execute(httpRequest);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
BufferedReader reader = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent(),
"UTF-8"));
for (String s = reader.readLine(); s != null; s = reader.readLine()) {
builder.append(s);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return builder.toString();
}
}
第三步,我们便开始具体的解析上面获取到的json格式的字符串天气数据。代码里我都有详细的注释,所以就不多加解释了。
package com.lj.weather.act;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.impl.conn.tsccm.WaitingThread;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.lj.weather.R;
import com.lj.weather.adapter.NextWeatherAdapter;
import com.lj.weather.model.WeatherDetailInfo;
import com.lj.weather.model.WeatherInfo;
import com.lj.weather.utils.JSONUtils;
import android.R.string;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
/**
* 简单的天气预报显示界面
*
* @author Administrator
*
*/
public class WeatherInfoShowAct extends Activity {
private String text = "";
private TextView item_date;
private TextView item_wind;
private TextView item_temperature;
private TextView item_weather;
private JSONUtils jsonUtils;
private WeatherInfo weatherInfo, weatherInfo1;
private List<WeatherInfo> weatherInfoList;
private String uri = "http://api.map.baidu.com/telematics/v3/weather?location=常州&output=json&ak=ECIqazfmQFiEj0HAZKupo44x";
private ListView listView;
private NextWeatherAdapter adapter;
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 1) {
//服务器返回的天气jsonText文本
String infoString = (String) msg.obj;
//天气数据list,今天,明天、后天、大后天
weatherInfoList = getWeatherInfo(infoString);
Log.d("Main", "" + weatherInfoList.size());
adapter = new NextWeatherAdapter(weatherInfoList, WeatherInfoShowAct.this);
listView.setAdapter(adapter);
item_date.setText(weatherInfo1.getDateWeek());
item_wind.setText(weatherInfo1.getwind());
item_temperature.setText(weatherInfo1.gettemperature());
item_weather.setText(weatherInfo1.getweather());
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_weather_main);
initView();
}
private void initView() {
jsonUtils = new JSONUtils();
listView = (ListView) findViewById(R.id.head_list);
new Thread() {
public void run() {
//根据url获得jsontext的天气数据
text = jsonUtils.getJSON(uri);
//刷新UI
Message message = new Message();
message.what = 1;
message.obj = text;
mHandler.sendMessage(message);
};
}.start();
item_date = (TextView) findViewById(R.id.head_date);
item_temperature = (TextView) findViewById(R.id.head_temperature);
item_weather = (TextView) findViewById(R.id.head_weather);
item_wind = (TextView) findViewById(R.id.head_wind);
}
private List<WeatherInfo> getWeatherInfo(String jsonStr) {
try {
JSONObject jsonObjectFirst = new JSONObject(jsonStr);
/** error */
if (jsonObjectFirst.get("error").equals(0)) {
Log.d("error", "" + jsonObjectFirst.get("error"));
Log.d("status", "" + jsonObjectFirst.get("status"));
Log.d("date", "" + jsonObjectFirst.get("date"));
/** results */
JSONArray jsonArrayResults = (JSONArray) jsonObjectFirst.get("results");
/** weather_data */
//为什么要get(0)?因为它属于第一个数组里面,其实总共只有一个数组
JSONObject jsonObjectWeatherData = (JSONObject) jsonArrayResults.get(0);
//获取当前城市
Log.d("currentCity", jsonObjectWeatherData.getString("currentCity"));
//获取当前城市的PM值
Log.d("pm25", jsonObjectWeatherData.getString("pm25"));
JSONArray jsonArrayWeatherData = (JSONArray) jsonObjectWeatherData.get("weather_data");
weatherInfoList = new ArrayList<WeatherInfo>();
for (int i = 0; i < 4; i++) {
JSONObject jsonObjectFour = (JSONObject) jsonArrayWeatherData.get(i);
//明天、后天、大后天数据
if (i >= 1) {
weatherInfo = new WeatherInfo();
weatherInfo.setDateWeek("" + jsonObjectFour.get("date"));
weatherInfo.setdayPictureUrl("" + jsonObjectFour.get("dayPictureUrl"));
weatherInfo.setnightPictureUrl("" + jsonObjectFour.get("nightPictureUrl"));
weatherInfo.setweather("" + jsonObjectFour.get("weather"));
weatherInfo.setwind("" + jsonObjectFour.get("wind"));
weatherInfo.settemperature("" + jsonObjectFour.get("temperature"));
weatherInfoList.add(weatherInfo);
} else {
//今天数据
weatherInfo1 = new WeatherInfo();
weatherInfo1.setDateWeek("" + jsonObjectFour.get("date"));
weatherInfo1.setdayPictureUrl("" + jsonObjectFour.get("dayPictureUrl"));
weatherInfo1.setnightPictureUrl("" + jsonObjectFour.get("nightPictureUrl"));
weatherInfo1.setweather("" + jsonObjectFour.get("weather"));
weatherInfo1.setwind("" + jsonObjectFour.get("wind"));
weatherInfo1.settemperature("" + jsonObjectFour.get("temperature"));
}
}
Log.d("size", "" + weatherInfoList.size());
} else {
Toast.makeText(WeatherInfoShowAct.this, "天气数据解析出错", 1).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
return weatherInfoList;
}
}
最后,我们运行一下查看最后的效果:
以上便是解析的全部过程,在这个demo中主要涉及到了网络请求、线程的使用、百度车联网服务的使用以及json数据的解析,在这个demo基础上,我们可以稍微修改一下,譬如增加刷新按钮、增加城市选择等便可以做出一个天气APP来,最后附上源码。
/**
* 作者:crazyandcoder
* 联系:
* QQ : 275137657
* email: lijiwork@sina.com
* 转载请注明出处!
*/