Integration of Yahoo Weather Api in Android

Integration weather api in android has so many choices. But I consider yahoo as the cheap and best api solution. Some other apis are provided by metwit, wunderground,worldweather, etc.

Yahoo Weather Report for Android
Yahoo Weather Report for Android

Yahoo provides a detailed documentation on the usage of their api. Its simple to integrate, however little bit of knowledge on parsing a xml response is needed.

Let me give a sample of parsing yahoo weather data to display current weather and five day forecast in android application.

Read the details given this link  http://developer.yahoo.com/weather/ to follow easily. And note down the WOEID for your city.To find your WOEID, browse or search for your city from the Weather home page.

Let’s create UI. My sample layout.xml looks like this..

<?xml version=”1.0″ encoding=”UTF-8″?>
<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android&#8221;
xmlns:tools=”http://schemas.android.com/tools&#8221;
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:background=”#ffffff”
tools:context=”.Weather” >

<TextView
android:id=”@+id/weather_title”
android:layout_width=”fill_parent”
android:layout_height=”40dp”
android:background=”@layout/searchgradient”
android:gravity=”center_vertical|center_horizontal”
android:text=”Weather Report”
android:textColor=”#ffffff”
android:textSize=”22sp”
android:textStyle=”bold” />

<ImageView
android:id=”@+id/weather_border”
android:layout_width=”fill_parent”
android:layout_height=”2dp”
android:layout_below=”@+id/weather_title”
android:layout_marginBottom=”10dp”
android:background=”#CCCCCC” />

<ScrollView
android:id=”@+id/scrollView1″
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:layout_above=”@+id/footer_border”
android:layout_below=”@+id/weather_border” >

<RelativeLayout
android:layout_width=”fill_parent”
android:layout_height=”wrap_content” >

<TextView
android:id=”@+id/dateText”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentRight=”true”
android:layout_alignTop=”@+id/icon”
android:layout_toRightOf=”@+id/icon”
android:textColor=”#333333″
android:textSize=”16sp” />

<TextView
android:id=”@+id/tempText”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout_below=”@+id/dateText”
android:layout_toRightOf=”@+id/icon”
android:textColor=”#333333″
android:textSize=”16sp” />

<TextView
android:id=”@+id/conditionText”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentRight=”true”
android:layout_below=”@+id/tempText”
android:layout_toRightOf=”@+id/icon”
android:textColor=”#333333″
android:textSize=”16sp” />

<TextView
android:id=”@+id/humidityText”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentRight=”true”
android:layout_below=”@+id/conditionText”
android:layout_toRightOf=”@+id/icon”
android:textColor=”#333333″
android:textSize=”16sp” />

<TextView
android:id=”@+id/windText”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentRight=”true”
android:layout_below=”@+id/humidityText”
android:layout_marginBottom=”10dp”
android:layout_toRightOf=”@+id/icon”
android:paddingBottom=”10dp”
android:textColor=”#333333″
android:textSize=”16sp” />

<ImageView
android:id=”@+id/border2″
android:layout_width=”fill_parent”
android:layout_height=”2dp”
android:layout_below=”@+id/windText”
android:background=”#ff6600″ />

<TextView
android:id=”@+id/forecast_title”
android:layout_width=”fill_parent”
android:layout_height=”40dp”
android:layout_below=”@+id/border2″
android:background=”@layout/listgradient”
android:gravity=”center_vertical|center_horizontal”
android:text=”Forecast”
android:textColor=”#333333″
android:textSize=”18sp”
android:textStyle=”bold” />

<ImageView
android:id=”@+id/forecastBorder”
android:layout_width=”fill_parent”
android:layout_height=”1dp”
android:layout_below=”@+id/forecast_title”
android:background=”#CCCCCC” />

<TextView
android:id=”@+id/day1″
android:layout_width=”wrap_content”
android:layout_height=”40dp”
android:layout_alignParentLeft=”true”
android:layout_alignParentRight=”true”
android:layout_below=”@+id/forecastBorder”
android:background=”@layout/listgradient”
android:gravity=”left|center_vertical”
android:paddingLeft=”10dp”
android:textAlignment=”gravity”
android:textColor=”#333333″
android:textSize=”16sp” />

<TextView
android:id=”@+id/day2″
android:layout_width=”wrap_content”
android:layout_height=”40dp”
android:layout_alignParentLeft=”true”
android:layout_alignParentRight=”true”
android:layout_below=”@+id/day1″
android:background=”@layout/listgradient”
android:gravity=”left|center_vertical”
android:paddingLeft=”10dp”
android:textAlignment=”gravity”
android:textColor=”#333333″
android:textSize=”16sp” />

<TextView
android:id=”@+id/day3″
android:layout_width=”wrap_content”
android:layout_height=”40dp”
android:layout_alignParentLeft=”true”
android:layout_alignParentRight=”true”
android:layout_below=”@+id/day2″
android:background=”@layout/listgradient”
android:gravity=”left|center_vertical”
android:paddingLeft=”10dp”
android:textAlignment=”gravity”
android:textColor=”#333333″
android:textSize=”16sp” />

<TextView
android:id=”@+id/day4″
android:layout_width=”wrap_content”
android:layout_height=”40dp”
android:layout_alignParentLeft=”true”
android:layout_alignParentRight=”true”
android:layout_below=”@+id/day3″
android:background=”@layout/listgradient”
android:gravity=”left|center_vertical”
android:paddingLeft=”10dp”
android:textAlignment=”gravity”
android:textColor=”#333333″
android:textSize=”16sp” />

<ImageView
android:id=”@+id/icon”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentLeft=”true”
android:layout_alignParentTop=”true”
android:padding=”10dp” />
</RelativeLayout>
</ScrollView>

<ImageView

android:id=”@+id/footer_border”

android:layout_width=”fill_parent”

android:layout_height=”2dp”

android:layout_above=”@+id/footer”

android:background=”#CCCCCC” />

 

<ImageView

android:id=”@+id/footer”

android:layout_width=”fill_parent”

android:layout_height=”50dp”

android:layout_alignParentBottom=”true”

android:background=”#E4E4E4″ />

 

<ImageButton

android:id=”@+id/reportBtn”

android:layout_width=”160dp”

android:layout_height=”wrap_content”

android:layout_alignParentBottom=”true”

android:layout_alignParentRight=”true”

android:layout_alignTop=”@+id/footer”

android:background=”@layout/footer_button_gradient”

android:paddingBottom=”5dp”

android:paddingLeft=”10dp”

android:paddingRight=”10dp”

android:paddingTop=”5dp”

android:src=”@drawable/iconreport” />

 

<ImageButton

android:id=”@+id/backBtn”

android:layout_width=”160dp”

android:layout_height=”wrap_content”

android:layout_alignParentBottom=”true”

android:layout_alignParentLeft=”true”

android:layout_alignTop=”@+id/footer”

android:background=”@layout/footer_button_gradient”

android:paddingBottom=”5dp”

android:paddingLeft=”10dp”

android:paddingRight=”10dp”

android:paddingTop=”5dp”

android:src=”@drawable/iconback” />

 

</RelativeLayout>

And my Activity file looks like this.

package com.xxxx.xxxxxx;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.HttpEntity;
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.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Html;
import android.view.Menu;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class Weather extends Activity {

String temperature, date, condition, humidity, wind, link;
Bitmap icon = null;
TextView title, tempText, dateText, conditionText, windText, humidityText,day1,day2, day3, day4;
ImageView image;
ArrayList<String> weather = new ArrayList<String>();
ProgressDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.weather);
image = (ImageView)findViewById(R.id.icon);
title = (TextView) findViewById(R.id.weather_title);
dateText = (TextView) findViewById(R.id.dateText);
tempText = (TextView) findViewById(R.id.tempText);
conditionText = (TextView) findViewById(R.id.conditionText);
humidityText = (TextView) findViewById(R.id.humidityText);
windText = (TextView) findViewById(R.id.windText);
day1 = (TextView)findViewById(R.id.day1);
day2 = (TextView)findViewById(R.id.day2);
day3 = (TextView)findViewById(R.id.day3);
day4 = (TextView)findViewById(R.id.day4);
weatherLink = (TextView)findViewById(R.id.weatherLink);
Typeface tf = Typeface.createFromAsset(getAssets(),
“Fonts/Roboto-Condensed.ttf”);
title.setText(“Madurai Weather Report”);
tempText.setTypeface(tf);
conditionText.setTypeface(tf);
dateText.setTypeface(tf);
humidityText.setTypeface(tf);
windText.setTypeface(tf);
title.setTypeface(tf);
day1.setTypeface(tf);
day2.setTypeface(tf);
day3.setTypeface(tf);
day4.setTypeface(tf);
ImageButton backBtn = (ImageButton) findViewById(R.id.backBtn);
ImageButton report = (ImageButton) findViewById(R.id.reportBtn);

new retrieve_weatherTask().execute();

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.weather, menu);
return true;
}

protected class retrieve_weatherTask extends AsyncTask<Void, String, String> {

protected void onPreExecute(){
dialog = new ProgressDialog(Weather.this);
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setMessage(“Loading…”);
dialog.setCancelable(false);
dialog.show();
}

@Override
protected String doInBackground(Void… arg0) {
// TODO Auto-generated method stub
String qResult = “”;
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet(“http://weather.yahooapis.com/forecastrss?w=2295425&u=c&#8221;);

try {
HttpResponse response = httpClient.execute(httpGet,
localContext);
HttpEntity entity = response.getEntity();

if (entity != null) {
InputStream inputStream = entity.getContent();
Reader in = new InputStreamReader(inputStream);
BufferedReader bufferedreader = new BufferedReader(in);
StringBuilder stringBuilder = new StringBuilder();
String stringReadLine = null;
while ((stringReadLine = bufferedreader.readLine()) != null) {
stringBuilder.append(stringReadLine + “\n”);
}
qResult = stringBuilder.toString();
}

} catch (ClientProtocolException e) {
e.printStackTrace();
Toast.makeText(Weather.this, e.toString(), Toast.LENGTH_LONG)
.show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(Weather.this, e.toString(), Toast.LENGTH_LONG)
.show();
}

Document dest = null;
DocumentBuilderFactory dbFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder parser;
try {
parser = dbFactory.newDocumentBuilder();
dest = parser
.parse(new ByteArrayInputStream(qResult.getBytes()));
} catch (ParserConfigurationException e1) {
e1.printStackTrace();
Toast.makeText(Weather.this, e1.toString(), Toast.LENGTH_LONG)
.show();
} catch (SAXException e) {
e.printStackTrace();
Toast.makeText(Weather.this, e.toString(), Toast.LENGTH_LONG)
.show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(Weather.this, e.toString(), Toast.LENGTH_LONG)
.show();
}

Node temperatureNode = dest.getElementsByTagName(
“yweather:condition”).item(0);
temperature = temperatureNode.getAttributes()
.getNamedItem(“temp”).getNodeValue().toString();
Node tempUnitNode = dest.getElementsByTagName(“yweather:units”).item(0);
temperature = temperature + “°” +tempUnitNode.getAttributes().getNamedItem(“temperature”).getNodeValue().toString();

Node dateNode = dest.getElementsByTagName(“yweather:forecast”)
.item(0);
date = dateNode.getAttributes().getNamedItem(“date”)
.getNodeValue().toString();

Node conditionNode = dest
.getElementsByTagName(“yweather:condition”).item(0);
condition = conditionNode.getAttributes()
.getNamedItem(“text”).getNodeValue().toString();

Node humidityNode = dest
.getElementsByTagName(“yweather:atmosphere”).item(0);
humidity = humidityNode.getAttributes()
.getNamedItem(“humidity”).getNodeValue().toString();
humidity = humidity + “%”;

Node windNode = dest.getElementsByTagName(“yweather:wind”).item(0);
wind = windNode.getAttributes().getNamedItem(“speed”).getNodeValue().toString();
Node windUnitNode = dest.getElementsByTagName(“yweather:units”).item(0);
wind = wind + ” “+windUnitNode.getAttributes().getNamedItem(“speed”)
.getNodeValue().toString();

String desc = dest.getElementsByTagName(“item”).item(0)
.getChildNodes().item(13).getTextContent().toString();
StringTokenizer str = new StringTokenizer(desc, “<=>”);
System.out.println(“Tokens: ” + str.nextToken(“=>”));
String src = str.nextToken();
System.out.println(“src: “+ src);
String url1 = src.substring(1, src.length() – 2);
Pattern TAG_REGEX = Pattern.compile(“(.+?)<br />”);
Matcher matcher = TAG_REGEX.matcher(desc);
while (matcher.find()) {
weather.add(matcher.group(1));
}

Pattern links = Pattern.compile(“(.+?)<BR/>”);
matcher = links.matcher(desc);
while(matcher.find()){
System.out.println(“Match Links: “+ (matcher.group(1)));
link = matcher.group(1);
}

/* String test = (Html.fromHtml(desc)).toString();
System.out.println(“test: “+ test);
StringTokenizer tkn = new StringTokenizer(test);
for(int i=0; i < tkn.countTokens(); i++){
System.out.println(“Remaining: “+tkn.nextToken());
}*/

InputStream in = null;
try {
// in = OpenHttpConnection(url1);
int response = -1;
URL url = new URL(url1);
URLConnection conn = url.openConnection();

if (!(conn instanceof HttpURLConnection))
throw new IOException(“Not an HTTP connection”);
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod(“GET”);
httpConn.connect();

response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
System.out.println(“*********************”);
in = httpConn.getInputStream();
}
icon = BitmapFactory.decodeStream(in);
in.close();
} catch (IOException e1) {
e1.printStackTrace();
}
return qResult;

}

protected void onPostExecute(String result) {
System.out.println(“POST EXECUTE”);
if(dialog.isShowing())
dialog.dismiss();
tempText.setText(“Temperature: “+temperature);
conditionText.setText(“Condition: “+condition);
dateText.setText(“Date: “+date);
humidityText.setText(“Humidity: “+humidity);
windText.setText(“Wind: “+wind);
image.setImageBitmap(icon);
day1.setText(weather.get(3));
day2.setText(weather.get(4));
day3.setText(weather.get(5));
day4.setText(weather.get(6));
weatherLink.setText(Html.fromHtml(link));

}
}

}

Try this code and you can showcase the weather forecast of your city now! Let me know your comments.

22 thoughts on “Integration of Yahoo Weather Api in Android

  1. there are errors no found @layout/searchgradient,@layout/footer_button_gradient,@drawable/iconreport,@drawable/iconback
    can you provide them?

  2. when i use your code on my weather view app that time face error ” E/Fail 2(541): org.xml.sax.SAXParseException: expected: /HR read: BODY (position:END_TAG @14:8 in java.io.InputStreamReader@43e3f740) ”

    also stringReadLine generate this type of html— ”

    Access Denied

    Access Denied


    Description: You are not allowed to access the document you requested.—–


    get value same as your value:
    HttpGet httpGet = new HttpGet(“http://weather.yahooapis.com/forecastrss?w=2295425&u=c”);

    My apps sdk version is 8 api to 19 api .

    please tell me how to solve sax parse error.

  3. Could u send me the complete code,i need the @layout/searchgradient,@layout/footer_button_gradient,@drawable/iconreport,@drawable/iconback
    can you provide them?

Leave a comment