安卓中实现天气预报的设计,有两种解析数据源的方法:Json 解析和XML解析;而对应的天气预报源也不同;
一.基于Xml解析的天气预报数据源网址:
http://php.weather.sina.com.cn/xml.php?city=上海&password=DJOYnieT8234jlsK&day=0
其中city部分可替换,但是在开发的时候要注意编码的问题,在编程中最好写成如下格式:
path ="http://php.weather.sina.com.cn/xml.php?city="+java.net.URLEncoder.encode("上海","gb2312")+"&password=DJOYnieT8234jlsK&day=0";
[源码]
MainActivity.java
package com.iotek.httpclient;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SimpleAdapter;
import android.widget.Spinner;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener {
private Spinner sp_cities;
private LinearLayout layout =null;
private Button btn_dowload = null;
private ProgressDialog dialog = null;
private HttpGet get = null;
private String path = null;
private HttpClient client = null;// 用来发送请求的一个客户端类
private TextView tv_show;
String cities[] = {"上海","北京","武汉"};
private ArrayAdapter<String> adapter = null;
private Weather weather;
private ImageView img_weather;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViews();
fillAdapter();
layout.setBackgroundResource(R.drawable.bg_running_dog);
client = new DefaultHttpClient();// 创建一个HttpClient对象
path = "http://php.weather.sina.com.cn/xml.php?city=";
sp_cities.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
try {
path ="http://php.weather.sina.com.cn/xml.php?city="
+java.net.URLEncoder.encode(cities[position],"gb2312")+
"&password=DJOYnieT8234jlsK&day=0";
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
get = new HttpGet(path);// 封装一个Get请求
MyAsynTask task = new MyAsynTask();
task.execute(get);// 向服务端发送get请求
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
private void findViews() {
img_weather = (ImageView) findViewById(R.id.img_weather);
tv_show = (TextView) findViewById(R.id.tv_show);
sp_cities = (Spinner) findViewById(R.id.sp_cities);
layout = (LinearLayout) findViewById(R.id.LinearLayout1);
}
@Override
public void onClick(View v) {
get = new HttpGet(path);// 封装一个Get请求
MyAsynTask task = new MyAsynTask();
task.execute(get);// 向服务端发送get请求
}
private void fillAdapter(){
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,cities);
sp_cities.setAdapter(adapter);
}
private class MyAsynTask extends AsyncTask<HttpGet, Void, Weather> {
@Override
protected void onPreExecute() {
dialog = new ProgressDialog(MainActivity.this);
dialog.setMessage("下载中.....");
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.show();
super.onPreExecute();
}
/*@Override
protected byte[] doInBackground(HttpGet... params) {
byte[] result = null;
try {
HttpGet httpGet = params[0];// 取出传过来的Get请求
// 发送get请求并得到响应内容,所有的内容否封装在HttpResponse对象中
HttpResponse response = client.execute(httpGet);
Header[] allHeaders = response.getAllHeaders();//得到所有的响应都信息
for(Header head:allHeaders){
Log.i("info", head.getName()+"---"+head.getValue());
}
// 查看状态行中的状态码是否为200
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();// 得到响应实体
result = EntityUtils.toByteArray(entity);
}
} catch (Exception e) {
}
return result;
}*/
@Override
protected Weather doInBackground(HttpGet... params) {
byte[] result = null;
String buffer = new String();
try {
HttpGet httpGet = params[0];// 取出传过来的Get请求
// 发送get请求并得到响应内容,所有的内容否封装在HttpResponse对象中
HttpResponse response = client.execute(httpGet);
/*Header[] allHeaders = response.getAllHeaders();//得到所有的响应都信息
for(Header head:allHeaders){
Log.i("info", head.getName()+"---"+head.getValue());
}*/
// 查看状态行中的状态码是否为200
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();// 得到响应实体
// result = EntityUtils.toByteArray(entity);
//buffer = EntityUtils.toString(entity);
/*InputStream in = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String tempStr = "";
while((tempStr=reader.readLine())!=null){
buffer= tempStr+"\n";
}*/
InputStream is = entity.getContent();
XMLParseUtil parseUtil = new XMLParseUtil();
weather = parseUtil.parseXMLByPull(is);
}
} catch (Exception e) {
// TODO: handle exception
}
return weather;
}
@Override
protected void onPostExecute(Weather result) {
dialog.dismiss();
// 设置要显示的图片,把字节数组转换成BitMap对象
/*img_show.setImageBitmap(BitmapFactory.decodeByteArray(result, 0,
result.length));*/
tv_show.setText(result.getCity()+" "+result.getStatus1()+"转"+result.getStatus2()+" "+
result.getTemperature1()+"~"+result.getTemperature2()+"度");
if (result.getStatus1().equals("晴")) {
img_weather.setBackgroundResource(R.drawable.qing_tian);
}else if(result.getStatus1().equals("多云")){
img_weather.setBackgroundResource(R.drawable.duo_yun);
}
super.onPostExecute(result);
}
}
}
//天气实现类
package com.iotek.httpclient;
public class Weather {
private String status1,status2;
private String city;
private String temperature1,temperature2;
public String getStatus1() {
return status1;
}
public void setStatus1(String status1) {
this.status1 = status1;
}
public String getStatus2() {
return status2;
}
public void setStatus2(String status2) {
this.status2 = status2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getTemperature1() {
return temperature1;
}
public void setTemperature1(String temperature1) {
this.temperature1 = temperature1;
}
public String getTemperature2() {
return temperature2;
}
public void setTemperature2(String temperature2) {
this.temperature2 = temperature2;
}
}
//Xml解析
package com.iotek.httpclient;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import android.util.Xml;
public class XMLParseUtil {
private Weather weather = null;
/**
* 解析xml输入流并返回学生对象的集合
*
* @param is
* @return
*/
public Weather parseXMLByPull(InputStream is) throws Exception {
/*// 1、得到解析器工厂类用来产生解析器对象
XmlPullParserFactory xpf=XmlPullParserFactory.newInstance();
// 2、由工厂类创建Pull解析器对象
XmlPullParser xpp = xpf.newPullParser();*/
XmlPullParser xpp=Xml.newPullParser();
// 3、开始解析输入流,确定解析流的编码方式
xpp.setInput(is, "utf-8");
//进入事件解析流程,获得事件类型
int eventType = xpp.getEventType();
//假设没有解析到最后,就继续往下解析
while(eventType!=XmlPullParser.END_DOCUMENT){
if(eventType==XmlPullParser.START_DOCUMENT){
}else if(eventType==XmlPullParser.START_TAG){
String tagName=xpp.getName();//获得当前位置的标签名
if(tagName.equals("city")){
weather=new Weather();
weather.setCity(xpp.nextText());
}else if(tagName.equals("status1")){
weather.setStatus1(xpp.nextText());//获取当前节点的下一个文本节点
}else if(tagName.equals("status2")){
weather.setStatus2(xpp.nextText());//获取当前节点的下一个文本节点
}else if(tagName.equals("temperature1")){
weather.setTemperature1(xpp.nextText());//获取当前节点的下一个文本节点
}else if(tagName.equals("temperature2")){
weather.setTemperature2(xpp.nextText());//获取当前节点的下一个文本节点
}
}else if(eventType==XmlPullParser.END_TAG){
}
eventType=xpp.next();//获得下一个事件
}
return weather;
}
}
二.基于Json解析的天气预报数据源网址:
http://m.weather.com.cn/data/101010100.html
其中可根据城市的代号来查询天气,如上海:101020100.
基于Json解析相对比较简单,在此只把 核心代码写下来
JSONObject jsonObject = new JSONObject(result);
JSONObject object = jsonObject.getJSONObject("weatherinfo");
tv_show.setText(object.getString("city")+" "+object.getString("temp1"));