本博文实现的效果图如上;正如大家所看见的一样,我还没有实现汉语的查询,现在只能用汉语拼音查询。
以后会慢慢实现,其实很简单的。
本此内容主要涉及到的XML的解析,如有不懂的地方,查看我上次博文:Android进阶2之SAX方法解析XML
里面有详细介绍,本次就不再阐述了。
基本原理:就是利用谷歌的Url(http://www.google.com/ig/api?hl=zh-cn&weather=beijing" )获取天气预报的XML,在对XML进行解析。
具体实现:
WeatherForecastActivity:
package xiaosi.WeatherForecast;
import java.io.StringReader;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
public class WeatherForecastActivity extends Activity
{
private Button button = null;
private EditText edit = null;
private TextView weatherCT = null;
private TextView weatherCondition = null;
private TextView forecastWeather1 = null;
private TextView forecastWeather2 = null;
private TextView forecastWeather3 = null;
private TextView forecastWeather4 = null;
private TextView text = null;
private ImageView forecastIcon1 = null;
private ImageView forecastIcon2 = null;
private ImageView forecastIcon3 = null;
private ImageView forecastIcon4 = null;
private ImageView weatherConditionIcon = null;
private WeatherConditions weatherConditions = null;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
}
private void init()
{
button = (Button) findViewById(R.id.search);
button.setOnClickListener(new searchListener());
edit = (EditText) findViewById(R.id.edit);
weatherCT = (TextView) findViewById(R.id.weatherCT);
weatherCondition = (TextView) findViewById(R.id.weatherCondition);
forecastWeather1 = (TextView) findViewById(R.id.forecastWeather1);
forecastWeather2 = (TextView) findViewById(R.id.forecastWeather2);
forecastWeather3 = (TextView) findViewById(R.id.forecastWeather3);
forecastWeather4 = (TextView) findViewById(R.id.forecastWeather4);
text = (TextView) findViewById(R.id.text);
weatherConditionIcon = (ImageView) findViewById(R.id.weatherConditionIcon);
forecastIcon1 = (ImageView) findViewById(R.id.forecastIcon1);
forecastIcon2 = (ImageView) findViewById(R.id.forecastIcon2);
forecastIcon3 = (ImageView) findViewById(R.id.forecastIcon3);
forecastIcon4 = (ImageView) findViewById(R.id.forecastIcon4);
weatherConditions = new WeatherConditions();
}
private class searchListener implements OnClickListener
{
@Override
public void onClick(View v)
{
String searchContent = edit.getText().toString().trim();
System.out.println("城市:" + searchContent);
try
{
//XML解析
String weatherXML = WeatherUtils.getWeatherXML(searchContent);
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
XMLReader xmlReader = saxFactory.newSAXParser().getXMLReader();
MyContentHandler contentHandler = new MyContentHandler();
//把解析出来的值复制给weatherConditions对象
contentHandler.setWeather(weatherConditions);
xmlReader.setContentHandler(contentHandler);
xmlReader.parse(new InputSource(new StringReader(weatherXML)));
//UI界面显示
setWeather();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
public void setWeather()
{
// 当前天气预报
weatherCT.setText(weatherConditions.getCity() + "\t\t\t\t" + weatherConditions.getCurrentTime());
String currentWeather = weatherConditions.getCurrentCondition() + "\n摄氏温度:"
+ weatherConditions.getCurrentCTemperature() + "°C|华氏温度:" + weatherConditions.getCurrentFTemperature()
+ "℉\n" + weatherConditions.getCurrentWind() + "\n" + weatherConditions.getCurrentHumidity();
weatherCondition.setText(currentWeather);
Bitmap bitmap = WeatherUtils.getWeatherConditionIcon("http://www.google.com/"
+ weatherConditions.getCurrentIcon());
weatherConditionIcon.setImageBitmap(bitmap);
text.setText("未来四天天气预报");
// 未来四天
// 第一天
Bitmap bitmap1 = WeatherUtils.getWeatherConditionIcon("http://www.google.com/"
+ weatherConditions.getForecastIcon(1));
forecastIcon1.setImageBitmap(bitmap1);
forecastWeather1.setText(weatherConditions.getForecastWeek(1) + "\n"
+ weatherConditions.getForecastCondition(1) + "\n" + weatherConditions.getForecastLowTemperature(1)
+ "°C~" + weatherConditions.getForecastHighTemperature(1) + "°C");
// 第二天
Bitmap bitmap2 = WeatherUtils.getWeatherConditionIcon("http://www.google.com/"
+ weatherConditions.getForecastIcon(2));
forecastIcon2.setImageBitmap(bitmap2);
forecastWeather2.setText(weatherConditions.getForecastWeek(2) + "\n"
+ weatherConditions.getForecastCondition(2) + "\n" + weatherConditions.getForecastLowTemperature(2)
+ "°C~" + weatherConditions.getForecastHighTemperature(2) + "°C");
// 第三天
Bitmap bitmap3 = WeatherUtils.getWeatherConditionIcon("http://www.google.com/"
+ weatherConditions.getForecastIcon(3));
forecastIcon3.setImageBitmap(bitmap3);
forecastWeather3.setText(weatherConditions.getForecastWeek(3) + "\n"
+ weatherConditions.getForecastCondition(3) + "\n" + weatherConditions.getForecastLowTemperature(3)
+ "°C~" + weatherConditions.getForecastHighTemperature(3) + "°C");
// 第四天
Bitmap bitmap4 = WeatherUtils.getWeatherConditionIcon("http://www.google.com/"
+ weatherConditions.getForecastIcon(4));
forecastIcon4.setImageBitmap(bitmap4);
forecastWeather4.setText(weatherConditions.getForecastWeek(4) + "\n"
+ weatherConditions.getForecastCondition(4) + "\n" + weatherConditions.getForecastLowTemperature(4)
+ "°C~" + weatherConditions.getForecastHighTemperature(4) + "°C");
}
}
MyContentHandler:
这个主要用来解析XML,获取数据。
package xiaosi.WeatherForecast;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.util.Log;
public class MyContentHandler extends DefaultHandler
{
String tag = "XIAOSI";
private WeatherConditions weather = null;
private int day = 0;
public void setWeather(WeatherConditions weather){
this.weather = weather;
}
@Override
public void startDocument() throws SAXException
{
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
{
if (localName.equals("postal_code"))
{
Log.i(tag, "地点:" + attributes.getValue(0));
weather.setCity(attributes.getValue(0));
}
else if (localName.equals("forecast_date"))
{
Log.i(tag, "时间:" + attributes.getValue(0));
weather.setCurrentTime(attributes.getValue(0));
}
else if (localName.equals("humidity"))
{
Log.i(tag, "湿度:" + attributes.getValue(0));
weather.setCurrentHumidity(attributes.getValue(0));
}
else if (localName.equals("temp_f"))
{
Log.i(tag, "华氏温度:" + attributes.getValue(0));
weather.setCurrentFTemperature(attributes.getValue(0));
}
else if (localName.equals("temp_c"))
{
Log.i(tag, "摄氏温度:" + attributes.getValue(0));
weather.setCurrentCTemperature(attributes.getValue(0));
}
else if (localName.equals("wind_condition"))
{
Log.i(tag, "风况:" + attributes.getValue(0));
weather.setCurrentWind(attributes.getValue(0));
}
else if (localName.equals("day_of_week"))
{
Log.i(tag, "星期:" + attributes.getValue(0));
weather.setForecastWeek(attributes.getValue(0), day);
}
else if (localName.equals("low"))
{
Log.i(tag, "最低气温:" + attributes.getValue(0));
weather.setForecastLowTemperature(attributes.getValue(0), day);
}
else if (localName.equals("high"))
{
Log.i(tag, "最高气温:" + attributes.getValue(0));
weather.setForecastHighTemperature(attributes.getValue(0), day);
}
else if (localName.equals("condition"))
{
Log.i(tag, "天气:" + attributes.getValue(0));
if(day == 0){
weather.setCurrentCondition(attributes.getValue(0));
}
else{
weather.setForecastCondition(attributes.getValue(0),day);
}
}
else if (localName.equals("icon"))
{
Log.i(tag, "天气图标:" + attributes.getValue(0));
if(day == 0){
weather.setCurrentIcon(attributes.getValue(0));
}
else{
weather.setForecastIcon(attributes.getValue(0),day);
}
}
else if (localName.equals("forecast_conditions"))
{
day++;
Log.i(tag, "forecast_conditions:"+day);
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException
{
Log.i(tag, "characters");
}
@Override
public void endDocument() throws SAXException
{
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException
{
}
}
WeatherConditions:
主要用来存放获取的天气预报数据。
package xiaosi.WeatherForecast;
public class WeatherConditions
{
// 查询城市
private String city = null;
// 当前日期
private String currentTime = null;
// 当前天气
private String currentCondition = null;
// 当前华氏温度
private String currentFTemperature = null;
// 当前摄氏温度
private String currentCTemperature = null;
// 当前湿度
private String currentHumidity = null;
// 当前风况
private String currentWind = null;
// 当前天气图标
private String currentIcon = null;
// 从现在开始连续四天
private String[] forecastWeek = new String[5];
// 从现在开始连续四天最低气温
private String[] forecastLowTemperature = new String[5];
// 从现在开始连续四天最高气温
private String[] forecastHighTemperature = new String[5];
// 从现在开始连续四天天气图标
private String[] forecastIcon = new String[5];
// 从现在开始连续四天天气
private String[] forecastCondition = new String[5];
public String getCity()
{
return city;
}
public void setCity(String city)
{
this.city = city;
}
public String getCurrentTime()
{
return currentTime;
}
public void setCurrentTime(String currentTime)
{
this.currentTime = currentTime;
}
public String getCurrentCondition()
{
return currentCondition;
}
public void setCurrentCondition(String currentCondition)
{
this.currentCondition = currentCondition;
}
public String getCurrentHumidity()
{
return currentHumidity;
}
public void setCurrentHumidity(String currentHumidity)
{
this.currentHumidity = currentHumidity;
}
public String getCurrentWind()
{
return currentWind;
}
public void setCurrentWind(String currentWind)
{
this.currentWind = currentWind;
}
public String getCurrentIcon()
{
return currentIcon;
}
public void setCurrentIcon(String currentIcon)
{
this.currentIcon = currentIcon;
}
public String getForecastWeek(int day)
{
return forecastWeek[day];
}
public void setForecastWeek(String forecastWeek, int day)
{
this.forecastWeek[day] = forecastWeek;
}
public String getForecastLowTemperature(int day)
{
return forecastLowTemperature[day];
}
public void setForecastLowTemperature(String forecastLowTemperature, int day)
{
this.forecastLowTemperature[day] = forecastLowTemperature;
}
public String getForecastHighTemperature(int day)
{
return forecastHighTemperature[day];
}
public void setForecastHighTemperature(String forecastHighTemperature, int day)
{
this.forecastHighTemperature[day] = forecastHighTemperature;
}
public String getForecastIcon(int day)
{
return forecastIcon[day];
}
public void setForecastIcon(String forecastIcon, int day)
{
this.forecastIcon[day] = forecastIcon;
}
public String getForecastCondition(int day)
{
return forecastCondition[day];
}
public void setForecastCondition(String forecastCondition, int day)
{
this.forecastCondition[day] = forecastCondition;
}
public String getCurrentFTemperature()
{
return currentFTemperature;
}
public void setCurrentFTemperature(String currentFTemperature)
{
this.currentFTemperature = currentFTemperature;
}
public String getCurrentCTemperature()
{
return currentCTemperature;
}
public void setCurrentCTemperature(String currentCTemperature)
{
this.currentCTemperature = currentCTemperature;
}
}
WeatherUtils:
用到的一些方法。
package xiaosi.WeatherForecast;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class WeatherUtils
{
/**
* 获取天气预报XML
*
* @param city
* @return
* @throws Exception
*/
public static String getWeatherXML(String city) throws Exception
{
HttpGet httpGet = new HttpGet("http://www.google.com/ig/api?hl=zh-cn&weather=" + city);
HttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse = httpClient.execute(httpGet);
if (httpResponse.getStatusLine().getStatusCode() == 200)
{
String strResult = EntityUtils.toString(httpResponse.getEntity(), HTTP.UTF_8);
System.out.println("信息:" + strResult);
return strResult;
}
else
{
System.out.println("异常");
}
return null;
}
/**
* 这个没有
* @throws Exception
*/
public static void getCityNum() throws Exception
{
String url = "http://www.google.com/ig/cities?hl=zh-cn&country=cn";
HttpGet httpGet = new HttpGet(url);
HttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse = httpClient.execute(httpGet);
if (httpResponse.getStatusLine().getStatusCode() == 200)
{
String strResult = EntityUtils.toString(httpResponse.getEntity(), HTTP.UTF_8);
System.out.println("城市:" + strResult);
}
else
{
System.out.println("异常");
}
}
/**
* 获取天气预报天气的图标
* @param imgUrl
* @return
*/
public static Bitmap getWeatherConditionIcon(String imgUrl)
{
URL myImgUrl = null;
Bitmap bitmap = null;
try
{
myImgUrl = new URL(imgUrl);
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
try
{
HttpURLConnection conn = (HttpURLConnection) myImgUrl.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
is.close();
}
catch (IOException e)
{
e.printStackTrace();
}
return bitmap;
}
}
main.xml
<?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:orientation="vertical" >
<EditText
android:id="@+id/edit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="请输入你要查询的城市......" />
<Button
android:id="@+id/search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查询" />
<TextView
android:id="@+id/weatherCT"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="@+id/weatherConditionIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/weatherCondition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="20dip" />
</LinearLayout>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="100dip"
android:paddingTop="10dip"
android:textColor="#FF3300"/>
<!-- 未来四天 -->
<!-- 一二天 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingTop="10dip" >
<!-- 第一天 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="@+id/forecastIcon1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/forecastWeather1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dip" />
</LinearLayout>
<!-- 第二天 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingLeft="15dip" >
<ImageView
android:id="@+id/forecastIcon2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/forecastWeather2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dip" />
</LinearLayout>
</LinearLayout>
<!-- 三四天 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingTop="10dip" >
<!-- 第三天 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="@+id/forecastIcon3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/forecastWeather3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dip" />
</LinearLayout>
<!-- 第四天 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingLeft="15dip" >
<ImageView
android:id="@+id/forecastIcon4"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/forecastWeather4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dip" />
</LinearLayout>
</LinearLayout>
</LinearLayout>