andbook!.pdf - Learning Android Get an anddev.org - Android-Shirt Back to index
anddev.org Header Logo
FAQ Search Top rated articles Browse Feeds anddev.org - Authors Contact Details Register Log in

Android Weather Forecast - Google Weather API - Description

Goto page 1, 2, 3, 4  Next
 
       anddev.org - Android Development Community | Android Tutorials | Index -> Advanced Tutorials
Author Message
plusminus
Site Admin
Site Admin


Joined: 14 Nov 2007
Posts: 2660
Location: College Park, MD

PostPosted: Fri Dec 21, 2007 12:34 am    Post subject: Android Weather Forecast - Google Weather API - Description Reply with quote

Android Weather Forecast - Google Weather API - Description
Arrow Take a look at the Full Source of this Tutorial Arrow Left


What you learn: You will learn how to access the Google Weather API an parse the XML-Result using a SAXParser.

Idea 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 Rolling Eyes). This once again shows the power and flexibility of the Android-Platform Exclamation

Idea 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:
Quote:
// Style:
http://www.google.com/ig/api?weather=QUERY

// Working Examples ( Note: that " "(space) has to be replaced with its html-expression "%20"
// Your browser manages that conversion automatically )
http://www.google.com/ig/api?weather=Schriesheim,Germany
http://www.google.com/ig/api?weather=New%20York,%20USA

The response is always like the following (when the city could be found):
Note: Originally the xml-code responded comes without LineFeeds Exclamation + I added comments Exclamation
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 Smile

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. Exclamation

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" Exclamation 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 Smile

How to create a custom View Source 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:
  1. Call the Google Weather API with what the user typed to the EditText
  2. Create a SAXParser and parse the result of the previous step
  3. 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);
                    }
               }
          });


Smile Thats it. Smile
Arrow Take a look at the Full Source of this Tutorial Arrow Left

Regards,
plusminus

_________________
Download my apps Idea
Please remember, that this board is give & take Smile


| Android Development Community / Tutorials


Last edited by plusminus on Mon Feb 25, 2008 2:00 pm; edited 2 times in total
Back to top
View user's profile Send private message Send e-mail Visit poster's website
wrapware
Freshman
Freshman


Joined: 17 Jan 2008
Posts: 7
Location: Germany

PostPosted: Thu Jan 17, 2008 8:00 pm    Post subject: Reply with quote

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
View user's profile Send private message
wrapware
Freshman
Freshman


Joined: 17 Jan 2008
Posts: 7
Location: Germany

PostPosted: Fri Jan 18, 2008 8:14 am    Post subject: Reply with quote

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
View user's profile Send private message
GodsMoon
Developer
Developer


Joined: 10 Dec 2007
Posts: 26

PostPosted: Mon Jan 21, 2008 10:16 pm    Post subject: Forcast for Current Location Reply with quote

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
View user's profile Send private message Visit poster's website
plusminus
Site Admin
Site Admin


Joined: 14 Nov 2007
Posts: 2660
Location: College Park, MD

PostPosted: Mon Jan 21, 2008 11:59 pm    Post subject: Re: Forcast for Current Location Reply with quote

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. Sad

There has to be sth. out there that we could use. But I only had time for a superficial google-search. (Exams suck Exclamation )

Regards,
plusminus

_________________
Download my apps Idea
Please remember, that this board is give & take Smile


| Android Development Community / Tutorials
Back to top
View user's profile Send private message Send e-mail Visit poster's website
cauchy
Freshman
Freshman


Joined: 10 Jan 2008
Posts: 4
Location: Marseille, France

PostPosted: Tue Jan 22, 2008 9:26 pm    Post subject: Reply with quote

A way for you to convert your GPS coordinates to a City Name could be the following ws PI from geonames.org:

http://ws.geonames.org/findNearbyPlaceName?lat=43.30&lng=5.4

You can easily get the lat and lng parameters from the LocationManager:

Java:

LocationManager lm = (LocationManager) context
                                  .getSystemService( Context.LOCATION_SERVICE);
 
Location current_location = lm.getCurrentLocation( "gps");
final String lat = String.valueOf( current_location.getLatitude());
final String lng = String.valueOf( current_location.getLongitude());


Then all you have to do is a request to the URL I gave at the begining of my message replacing the lat and lng by their values, process the result with a bit of SAX parsing and there you go! Smile

This may be a bit overkill but I can't think of nothing simpler for you problem (if anyone has something else, I'm interrested).

Hope this helps!

Olivier.
Back to top
View user's profile Send private message Send e-mail
plusminus
Site Admin
Site Admin


Joined: 14 Nov 2007
Posts: 2660
Location: College Park, MD

PostPosted: Tue Jan 22, 2008 9:33 pm    Post subject: Reply with quote

Hello cauchy(Oliver),

big thx !!! I'll make a tutorial on parsing the output given by the service you suggested Exclamation (when I finished Exams).

For those who cannot wait Wink I'd suggest this tutorial: Source Parsing XML from the Net - Using the SAXParser

Regards,
plusminus

_________________
Download my apps Idea
Please remember, that this board is give & take Smile


| Android Development Community / Tutorials
Back to top
View user's profile Send private message Send e-mail Visit poster's website
GodsMoon
Developer
Developer


Joined: 10 Dec 2007
Posts: 26

PostPosted: Thu Jan 24, 2008 9:04 pm    Post subject: what a great find Reply with quote

cauchy,

Thank you so much that is an awesome find.

It will be very useful I'm sure.

Thank you for sharing Very Happy
Back to top
View user's profile Send private message Visit poster's website
GodsMoon
Developer
Developer


Joined: 10 Dec 2007
Posts: 26

PostPosted: Thu Jan 24, 2008 9:50 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
cauchy
Freshman
Freshman


Joined: 10 Jan 2008
Posts: 4
Location: Marseille, France

PostPosted: Thu Jan 24, 2008 11:23 pm    Post subject: Reply with quote

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 Wink:

http://ws.geonames.org/findNearestAddress?lat=37.775&lng=-122.19

Olivier.
Back to top
View user's profile Send private message Send e-mail
icer
Once Poster
Once Poster


Joined: 18 Feb 2008
Posts: 1

PostPosted: Mon Feb 18, 2008 2:33 pm    Post subject: Reply with quote

Hey, this is a great tutorial. Smile

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
View user's profile Send private message
plusminus
Site Admin
Site Admin


Joined: 14 Nov 2007
Posts: 2660
Location: College Park, MD

PostPosted: Mon Feb 18, 2008 5:24 pm    Post subject: Reply with quote

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 Wink

Regards,
plusminus

_________________
Download my apps Idea
Please remember, that this board is give & take Smile


| Android Development Community / Tutorials
Back to top
View user's profile Send private message Send e-mail Visit poster's website
to__liuyi
Freshman
Freshman


Joined: 04 Feb 2008
Posts: 4

PostPosted: Mon Feb 25, 2008 11:14 am    Post subject: will you porting this tutorial to m5-rc14? Reply with quote

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
View user's profile Send private message
plusminus
Site Admin
Site Admin


Joined: 14 Nov 2007
Posts: 2660
Location: College Park, MD

PostPosted: Mon Feb 25, 2008 2:03 pm    Post subject: Reply with quote

Just updated it. Smile

Warning The text-colors are pretty shitty now. All grey and with the background I used (see the screenshot) just badly visible.

Regards,
plusminus

_________________
Download my apps Idea
Please remember, that this board is give & take Smile


| Android Development Community / Tutorials
Back to top
View user's profile Send private message Send e-mail Visit poster's website
to__liuyi
Freshman
Freshman


Joined: 04 Feb 2008
Posts: 4

PostPosted: Tue Feb 26, 2008 1:22 am    Post subject: still have problems Reply with quote

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
View user's profile Send private message
Display posts from previous:   
       anddev.org - Android Development Community | Android Tutorials | Index -> Advanced Tutorials All times are GMT + 1 Hour
Goto page 1, 2, 3, 4  Next
Page 1 of 4

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


© 2007, Android Development Community
All rights reserved.
Powered by phpBB.