| Author |
Message |
plusminus Site Admin

Joined: 14 Nov 2007 Posts: 2025 Location: Germany
|
Posted: Fri Dec 21, 2007 12:34 am Post subject: Android Weather Forecast - Google Weather API - Description |
|
|
What you learn: You will learn how to access the Google Weather API an parse the XML-Result using a SAXParser.
Designed/Tested with sdk-version: m5-rc14
What this contains:
Difficulty: 3.5 of 5
I did this within 2 hours of coding (half for the xml-layout ). This once again shows the power and flexibility of the Android-Platform
Questions/Problems: Simply post below...
What it will look like:
Screenshot taken with SDK-version m3:

Description:
0.) In this tutorial we are going to use the Google (iGoogle) Weather API. We will simply call an URL with the following style:
The response is always like the following (when the city could be found):
Note: Originally the xml-code responded comes without LineFeeds + I added comments
| XML: | <xml_api_reply version="1">
<weather module_id="0" tab_id="0">
<forecast_information>
<!-- Some inner tags containing data about the city found, time and unit-stuff -->
<city data="Schriesheim, BW"/>
<postal_code data="Schriesheim,Germany"/>
<latitude_e6 data=""/>
<longitude_e6 data=""/>
<forecast_date data="2007-12-21"/>
<current_date_time data="2007-12-21 19:50:00 +0000"/>
<unit_system data="US"/>
</forecast_information>
<current_conditions>
<!-- Some inner tags containing data of current weather -->
<condition data="Fog"/>
<temp_f data="23"/>
<temp_c data="-5"/>
<humidity data="Humidity: 93%"/>
<icon data="/images/weather/fog.gif"/>
<wind_condition data="Wind: N at 1 mph"/>
</current_conditions>
<forecast_conditions>
<!-- Some inner tags containing data about future weather -->
<day_of_week data="Today"/>
<low data="24"/>
<high data="37"/>
<icon data="/images/weather/fog.gif"/>
<condition data="Fog"/>
</forecast_conditions>
<forecast_conditions>
<!-- Some inner tags containing data about future weather -->
<day_of_week data="Sat"/>
<low data="24"/>
<high data="37"/>
<icon data="/images/weather/sunny.gif"/>
<condition data="Clear"/>
</forecast_conditions>
<forecast_conditions>
<!-- Another set as above -->
</forecast_conditions>
<forecast_conditions>
<!-- Another set as above -->
</forecast_conditions>
</weather>
</xml_api_reply> |
If we call the Google Weather API with an not existing town, like:
| Quote: | | http://www.google.com/ig/api?weather=FantasyTown,Disneyland |
The "error" xml-return-code for such a bad query is like:
| XML: | <xml_api_reply version="1">
<weather module_id="0" tab_id="0">
<problem_cause data=""/>
</weather>
</xml_api_reply> |
1.) So as we need to extract the information out of the XML-code returned, we have to choose a XML-parser. I decided to use an SAX-Parser (Wiki-Info). SAX stands for Simple API for XML, so it is perfect for us
So the parsing-part follows that Tutorial (one line above). It will parse the XML-Data returned by the Weather API and in the end it "presents" the following Object to us:
| Java: | public class WeatherSet {
// ===========================================================
// Fields
// ===========================================================
private WeatherCurrentCondition myCurrentCondition = null;
private ArrayList<WeatherForecastCondition> myForecastConditions =
new ArrayList<WeatherForecastCondition>(4);
// ===========================================================
// Getter & Setter
// ===========================================================
// Getter & Setter for fields above...
} |
It simply contains two sub-objects: WeatherCurrentCondition which contains the parsed data from the xml-tag <current_conditions> and a list of WeatherForecastInfoSet which contains the parsed data from all the xml-tags <forecast_conditions>.
The parsing part is finished now (see the full source for the actual code).
2.) Lets take a look at the Layout. The layout is a bit more complex as what has been done previously.
This it how it is cascaded:
I'm using so much TableLayouts, because they can easily stretch its child-Views. 
The small entities with the Image and the Temperature-TextView are a customized View ("SingleWeatherInfoView"), which extends LinearLayout.
By extending LinearLayout we've got the ability to set the android:orientation-Attribute to ="horizontal" or to ="vertical" You can see that feature in the picture. The lonely "SingleWeatherInfoView" which shows the WeatherCondition of today, was coded with android:orientation="horizontal". You can see that the "inner" Views appear next to each other. The four "SingleWeatherInfoView" were xml-defined with: android:orientation="vertical", you can see that its "inner" Views appear below each other. This once again shows the power of object-orientated programming at its best
How to create a custom View Separate/Extended Tutorial.
The layout part is finished now (see the full source for the actual code).
3.) So 90% of the work is done now. The last thing we have to do is to put all the parts together.
We apply an OnClickListener to the Submit-Button, which will do the following, when clicked:
- Call the Google Weather API with what the user typed to the EditText
- Create a SAXParser and parse the result of the previous step
- Display the parsed data in the five "SingleWeatherInfoView".
And this is the corresponding code:
| Java: | Button cmd_submit = (Button)findViewById(R.id.cmd_submit);
cmd_submit.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
URL url;
try {
/* Get what user typed to the EditText. */
String cityParamString =
((EditText)findViewById(R.id.edit_input))
.getText().toString();
String queryString =
"http://www.google.com/ig/api?weather="
+ cityParamString;
/* Replace blanks with HTML-Equivalent. */
url = new URL(queryString.replace(" ", "%20"));
/* Get a SAXParser from the SAXPArserFactory. */
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
/* Get the XMLReader of the SAXParser we created. */
XMLReader xr = sp.getXMLReader();
/* Create a new ContentHandler and apply it to the XML-Reader*/
GoogleWeatherHandler gwh = new GoogleWeatherHandler();
xr.setContentHandler(gwh);
/* Parse the xml-data our URL-call returned. */
xr.parse(new InputSource(url.openStream()));
/* Our Handler now provides the parsed weather-data to us. */
WeatherSet ws = gwh.getWeatherSet();
/* Update the SingleWeatherInfoView with the parsed data. */
updateWeatherInfoView(R.id.weather_today, ws.getWeatherCurrentCondition());
updateWeatherInfoView(R.id.weather_1, ws.getWeatherForecastConditions().get(0));
updateWeatherInfoView(R.id.weather_2, ws.getWeatherForecastConditions().get(1));
updateWeatherInfoView(R.id.weather_3, ws.getWeatherForecastConditions().get(2));
updateWeatherInfoView(R.id.weather_4, ws.getWeatherForecastConditions().get(3));
} catch (Exception e) {
resetWeatherInfoViews();
Log.e(DEBUG_TAG, "WeatherQueryError", e);
}
}
}); |
Regards,
plusminus _________________
| Android Development Community / Tutorials
Last edited by plusminus on Mon Feb 25, 2008 2:00 pm; edited 2 times in total |
|
| Back to top |
|
 |
wrapware Freshman
Joined: 17 Jan 2008 Posts: 7 Location: Germany
|
Posted: Thu Jan 17, 2008 8:00 pm Post subject: |
|
|
Really nice behavior.
But there is one question:
Is it possible to modify the xml definition by code in the following manner:
| XML: | <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<view xmlns:android="http://schemas.android.com/apk/res/android"
class="de.xyz.widgets.ImageContainerView"
id="@+id/image1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout> |
and modify the content in the Activity.onCreate method like the following:
| Java: | ImageContainerView oView = (ImageContainerView)findViewById(R.id.image1);
// how can I do this ...
oView.setContent(new ImageContainerView(BitmapFactory.decodeResource(getResources(), R.drawable.image1))); |
Is there a way to load the image1 from the Code (in onCreate) into the 'static' XML-Representation, or must I go the long way like SingleWeatherInfoView?
Any help is welcome. |
|
| Back to top |
|
 |
wrapware Freshman
Joined: 17 Jan 2008 Posts: 7 Location: Germany
|
Posted: Fri Jan 18, 2008 8:14 am Post subject: |
|
|
There is one method availabe, if the view is an ImageView:
| Java: | oView.setImageDrawable(... |
But I'm using a View as base class, so there is still no way ... |
|
| Back to top |
|
 |
GodsMoon Junior Developer
Joined: 10 Dec 2007 Posts: 23
|
Posted: Mon Jan 21, 2008 10:16 pm Post subject: Forcast for Current Location |
|
|
Instead of having the user input the name of the City and State is it possible to read the GPS coordinates (assuming the phone has a GPS) and get the weather from the current location?
I've looked around a little but it seems like google does not provide a weather API for GPS coords, its only for a city names.
Will I have to reengineer the program to work with another service or is there a gps coords to city name converter or did I just miss something in the weather api?
any ideas?
Thanks |
|
| Back to top |
|
 |
plusminus Site Admin

Joined: 14 Nov 2007 Posts: 2025 Location: Germany
|
Posted: Mon Jan 21, 2008 11:59 pm Post subject: Re: Forcast for Current Location |
|
|
Hello GodsMoon,
also haven't seen a functionality in the Google Weather API to query for GPS.
So you probably have to go a way around using another API, but this will probably suck.
There has to be sth. out there that we could use. But I only had time for a superficial google-search. (Exams suck )
Regards,
plusminus _________________
| Android Development Community / Tutorials |
|
| Back to top |
|
 |
cauchy Freshman
Joined: 10 Jan 2008 Posts: 3 Location: Marseille, France
|
|
| Back to top |
|
 |
plusminus Site Admin

Joined: 14 Nov 2007 Posts: 2025 Location: Germany
|
Posted: Tue Jan 22, 2008 9:33 pm Post subject: |
|
|
Hello cauchy(Oliver),
big thx !!! I'll make a tutorial on parsing the output given by the service you suggested (when I finished Exams).
For those who cannot wait I'd suggest this tutorial: Parsing XML from the Net - Using the SAXParser
Regards,
plusminus _________________
| Android Development Community / Tutorials |
|
| Back to top |
|
 |
GodsMoon Junior Developer
Joined: 10 Dec 2007 Posts: 23
|
Posted: Thu Jan 24, 2008 9:04 pm Post subject: what a great find |
|
|
cauchy,
Thank you so much that is an awesome find.
It will be very useful I'm sure.
Thank you for sharing  |
|
| Back to top |
|
 |
GodsMoon Junior Developer
Joined: 10 Dec 2007 Posts: 23
|
Posted: Thu Jan 24, 2008 9:50 pm Post subject: |
|
|
In the US findNearbyPlaceName is very spotty. If it doesn't find a place "nearby" it returns nothing. The zip code lookup is much better.
for example:
http://ws.geonames.org/findNearbyPostalCodes?lat=43.244&lng=-70.1834
I've just been plugging in random values and its seems to return results just about always (not over the ocean of course). It also seems to work in Canda, though I didn't try anywhere else.
If one of the other webservices is better let us know. |
|
| Back to top |
|
 |
cauchy Freshman
Joined: 10 Jan 2008 Posts: 3 Location: Marseille, France
|
Posted: Thu Jan 24, 2008 11:23 pm Post subject: |
|
|
Hi GodsMoon,
Actually there is another really good one they have that gives the full address for a given location.
Unfortunatly it seems to work mainly(if not only) for the US. Anyway, it works fine with the locations provided by the Android Emulator :
http://ws.geonames.org/findNearestAddress?lat=37.775&lng=-122.19
Olivier. |
|
| Back to top |
|
 |
icer Once Poster
Joined: 18 Feb 2008 Posts: 1
|
Posted: Mon Feb 18, 2008 2:33 pm Post subject: |
|
|
Hey, this is a great tutorial.
Is there an API documentation for these weather features? Who owns that weather data and can I freely use it on 3rd party apps? Links please.
TIA
icer |
|
| Back to top |
|
 |
plusminus Site Admin

Joined: 14 Nov 2007 Posts: 2025 Location: Germany
|
Posted: Mon Feb 18, 2008 5:24 pm Post subject: |
|
|
Hello icer,
the weather Data is openly provided by Google and therefore we can us it for free.
I don't know whether there is any document out there describing how to use the API, just use it
Regards,
plusminus _________________
| Android Development Community / Tutorials |
|
| Back to top |
|
 |
to__liuyi Freshman
Joined: 04 Feb 2008 Posts: 4
|
Posted: Mon Feb 25, 2008 11:14 am Post subject: will you porting this tutorial to m5-rc14? |
|
|
I really like the weather forcast tutorial, but it can't run on m5-rc14 SDK. Get Nullpoint exception when start. I think the layout has compatibility issue, but I don't know where.
Will you porting to m5-rc14? |
|
| Back to top |
|
 |
plusminus Site Admin

Joined: 14 Nov 2007 Posts: 2025 Location: Germany
|
Posted: Mon Feb 25, 2008 2:03 pm Post subject: |
|
|
Just updated it.
The text-colors are pretty shitty now. All grey and with the background I used (see the screenshot) just badly visible.
Regards,
plusminus _________________
| Android Development Community / Tutorials |
|
| Back to top |
|
 |
to__liuyi Freshman
Joined: 04 Feb 2008 Posts: 4
|
Posted: Tue Feb 26, 2008 1:22 am Post subject: still have problems |
|
|
plusminus, that very kind of you!
but it still choked.
error msg on emulator say:
| Java: | Application Error:
org.anddev.android.weatherforecast
An error has occurred in org.anddev.android.weatherforecast. Unable to start activity CompoentInfo{org.anddev.android.weatherforecast/org.anddev.android.weatheroforecast.WeatherForcast}:
java.lang.NullPointerException. |
and here is msg on console:
| Java: | [2008-02-26 08:06:10 - WeatherForecast] ------------------------------
[2008-02-26 08:06:10 - WeatherForecast] Android Launch!
[2008-02-26 08:06:10 - WeatherForecast] adb is running normally.
[2008-02-26 08:06:10 - WeatherForecast] Launching: org.anddev.android.weatherforecast.WeatherForecast
[2008-02-26 08:06:10 - WeatherForecast] Automatic Target Mode: launch emulator.
[2008-02-26 08:06:10 - WeatherForecast] Launching a new emulator.
[2008-02-26 08:06:15 - WeatherForecast] New emulator found: emulator-tcp-5555
[2008-02-26 08:07:34 - WeatherForecast] HOME is up on device 'emulator-tcp-5555'
[2008-02-26 08:07:34 - WeatherForecast] Pushing WeatherForecast.apk to /data/app on device 'emulator-tcp-5555'
[2008-02-26 08:07:35 - WeatherForecast] Starting activity on device: org.anddev.android.weatherforecast.WeatherForecast
[2008-02-26 08:07:41 - WeatherForecast] ActivityManager: Starting: Intent { comp={org.anddev.android.weatherforecast/org.anddev.android.weatherforecast.WeatherForecast} } |
by the way, my Eclipse IDE that the AndroidManifest.xml has valiation errors. activity,action and category element must have property named android:name. I have to modify the file to this:
| XML: | <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.anddev.android.weatherforecast">
<application android:icon="@drawable/icon">
<activity android:name="WeatherForecast" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest> |
Do you think it related with the runtime exception? |
|
| Back to top |
|
 |
|