本博文实现的效果图如上;正如大家所看见的一样,我还没有实现汉语的查询,现在只能用汉语拼音查询。
以后会慢慢实现,其实很简单的。
本此内容主要涉及到的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"); } }
这个主要用来解析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 { } }
主要用来存放获取的天气预报数据。
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; } }
用到的一些方法。
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>