Tuesday, May 21, 2013

Android weather app: JSON, HTTP and Openweathermap

Topics covered

How to develop weather app

HTTP connection

JSON Parsing

Openweathermap API

This post describes how to create an android weather app that gives current weather information. This android app will use JSON, HTTP connection and AsyncTask to get this information.. As weather provider I will use OpenWeatherMap a free weather service that provides some interesting API really easy to use.I will guide you through the steps necessary to build up a working android weather app. For more information about API, you can visit the OpenWeatherMap web site.
You check this tutorial to  know how to retrieve current user position and the corresponding city name.



How to develop Android Weather app tutorial


I will show to you the final result so you can have an idea about what we will do in this post.



Current weather info – Android HTTP Request and JSON Response

OpenWeatherMap offers several API to use to get weather information. We want to use the one that gives us the current weather info. The URL to call to get this info is:
http://api.openweathermap.org/data/2.5/weather?q=city,country
Let’s suppose we want to know the weather in Rome, IT. Using our browser we can have:

weather_api_search
As we can see we have JSON response. Formatting the response we have
{
"coord":{"lon":12.4958,"lat":41.903},
"sys":{"country":"Italy","sunrise":1369107818,"sunset":1369160979},
"weather":[{
"id":802,"main":"Clouds","description":"scattered clouds",
"icon":"03d"}],
"base":"global stations",
"main":{
"temp":290.38,
"humidity":68,
"pressure":1015,
"temp_min":287.04,
"temp_max":293.71},
"wind":{
"speed":1.75,
"deg":290.002},
"clouds":{"all":32},
"dt":1369122932,
"id":3169070,
"name":"Rome",
"cod":200
}
So the first thing we need to do is creating our data model so that we can parse the response and convert it into Java classes. Analyzing the response we have different “main” tags that we can use as class in Java:
  • coord (object)
  • sys (object)
  • weather (array)
  • main (object)
  • wind (object)
  • name: (String)

The response is quite simple and we can convert it manually. The UML class diagram for the model is shown below:



Android JSON Weather Parser

Once we have created our model we have to parse it. We can create a specific class that handles this task. First we have to create the “root” object that receive as input the entire string containing all the JSON response:
// We create out JSONObject from the data
JSONObject jObj = new JSONObject(data);

Then we start parsing each piece of the response:
// We start extracting the info
Location loc = new Location();

JSONObject coordObj = getObject("coord", jObj);
loc.setLatitude(getFloat("lat", coordObj));
loc.setLongitude(getFloat("lon", coordObj));

JSONObject sysObj = getObject("sys", jObj);
loc.setCountry(getString("country", sysObj));
loc.setSunrise(getInt("sunrise", sysObj));
loc.setSunset(getInt("sunset", sysObj));
loc.setCity(getString("name", jObj));
weather.location = loc;

In the line 4,8 we create two “sub” object (coordObj and sysObj) having as parent the jObj as it clear from the JSON response. As we can see we use some helper methods to get String,int and float values:
private static JSONObject getObject(String tagName, JSONObject jObj)  throws JSONException {
JSONObject subObj = jObj.getJSONObject(tagName);
return subObj;
}

private static String getString(String tagName, JSONObject jObj) throws JSONException {
return jObj.getString(tagName);
}

private static float getFloat(String tagName, JSONObject jObj) throws JSONException {
return (float) jObj.getDouble(tagName);
}

private static int getInt(String tagName, JSONObject jObj) throws JSONException {
return jObj.getInt(tagName);
}

And then we finally parse the weather information. We have to remember that weather tag is an array so we have to handle it differently
// We get weather info (This is an array)
JSONArray jArr = jObj.getJSONArray("weather");

// We use only the first value
JSONObject JSONWeather = jArr.getJSONObject(0);
weather.currentCondition.setWeatherId(getInt("id", JSONWeather));
weather.currentCondition.setDescr(getString("description", JSONWeather));
weather.currentCondition.setCondition(getString("main", JSONWeather));
weather.currentCondition.setIcon(getString("icon", JSONWeather));

JSONObject mainObj = getObject("main", jObj);
weather.currentCondition.setHumidity(getInt("humidity", mainObj));
weather.currentCondition.setPressure(getInt("pressure", mainObj));
weather.temperature.setMaxTemp(getFloat("temp_max", mainObj));
weather.temperature.setMinTemp(getFloat("temp_min", mainObj));
weather.temperature.setTemp(getFloat("temp", mainObj));

// Wind
JSONObject wObj = getObject("wind", jObj);
weather.wind.setSpeed(getFloat("speed", wObj));
weather.wind.setDeg(getFloat("deg", wObj));

// Clouds
JSONObject cObj = getObject("clouds", jObj);
weather.clouds.setPerc(getInt("all", cObj));

At the end we have our Weather class filled with the data retrieved.

Android HTTP Request and Response

Now we have to exchange information between our android app and the remote server using HTTP protocol. We have to send information and then read the response. We covered this topic in the previous post(Android HTTP Client: GET, POST, Download, Upload, Multipart Request) so we won’t describe it again, we simply show the code:
public class WeatherHttpClient {

private static String BASE_URL = "http://api.openweathermap.org/data/2.5/weather?q=";
private static String IMG_URL = "http://openweathermap.org/img/w/";


public String getWeatherData(String location) {
HttpURLConnection con = null ;
InputStream is = null;

try {
con = (HttpURLConnection) ( new URL(BASE_URL + location)).openConnection();
con.setRequestMethod("GET");
con.setDoInput(true);
con.setDoOutput(true);
con.connect();

// Let's read the response
StringBuffer buffer = new StringBuffer();
is = con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
while ( (line = br.readLine()) != null )
buffer.append(line + "\r\n");

is.close();
con.disconnect();
return buffer.toString();
}
catch(Throwable t) {
t.printStackTrace();
}
finally {
try { is.close(); } catch(Throwable t) {}
try { con.disconnect(); } catch(Throwable t) {}
}

return null;

}

public byte[] getImage(String code) {
HttpURLConnection con = null ;
InputStream is = null;
try {
con = (HttpURLConnection) ( new URL(IMG_URL + code)).openConnection();
con.setRequestMethod("GET");
con.setDoInput(true);
con.setDoOutput(true);
con.connect();

// Let's read the response
is = con.getInputStream();
byte[] buffer = new byte[1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream();

while ( is.read(buffer) != -1)
baos.write(buffer);

return baos.toByteArray();
}
catch(Throwable t) {
t.printStackTrace();
}
finally {
try { is.close(); } catch(Throwable t) {}
try { con.disconnect(); } catch(Throwable t) {}
}

return null;

}
}


Android Weather App

Finally, it is the time for our Activity. The layout is very simple and of course it is just a skeleton you need to improve it if you want to have a production app.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >

<TextView
android:id="@+id/cityText"
style="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true" />

<ImageView
android:id="@+id/condIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/cityText" />

<TextView
android:id="@+id/condDescr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/condIcon"
android:layout_alignLeft="@id/condIcon"
/>

<TextView
android:id="@+id/temp"
style="@style/tempStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_alignBaseline="@id/condDescr"
android:layout_toRightOf="@id/condDescr"/>

<TextView
android:id="@+id/pressLab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/condDescr"
android:text="Pressure"
android:layout_marginTop="15dp" />

<TextView
android:id="@+id/press"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/pressLab"
android:layout_toRightOf="@id/pressLab"
style="@style/valData"/>

<TextView
android:id="@+id/humLab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/pressLab"
android:text="Humidity" />

<TextView
android:id="@+id/hum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/humLab"
android:layout_toRightOf="@id/humLab"
android:layout_marginLeft="4dp"
style="@style/valData"/>

<TextView
android:id="@+id/windLab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/humLab"
android:text="Wind" />

<TextView
android:id="@+id/windSpeed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/windLab"
android:layout_toRightOf="@id/windLab"
android:layout_marginLeft="4dp"
style="@style/valData" />

<TextView
android:id="@+id/windDeg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/windLab"
android:layout_toRightOf="@id/windSpeed"
android:layout_marginLeft="4dp"
style="@style/valData"/>

</RelativeLayout>

In onCreate method we simply get the reference to the Views inside the layout so that we can populate them later after the request is completed.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String city = "Rome,IT";

cityText = (TextView) findViewById(R.id.cityText);
condDescr = (TextView) findViewById(R.id.condDescr);
temp = (TextView) findViewById(R.id.temp);
hum = (TextView) findViewById(R.id.hum);
press = (TextView) findViewById(R.id.press);
windSpeed = (TextView) findViewById(R.id.windSpeed);
windDeg = (TextView) findViewById(R.id.windDeg);
imgView = (ImageView) findViewById(R.id.condIcon);

JSONWeatherTask task = new JSONWeatherTask();
task.execute(new String[]{city});
}

and we start an AsyncTask, because as we already know network operations are time consuming so we can run them in the main thread otherwise we could have an ANR problem. The JSONWeatherTask is very simply
protected Weather doInBackground(String... params) {
Weather weather = new Weather();
String data = ( (new WeatherHttpClient()).getWeatherData(params[0]));

try {
weather = JSONWeatherParser.getWeather(data);

// Let's retrieve the icon
weather.iconData = ( (new WeatherHttpClient()).getImage(weather.currentCondition.getIcon()));

} catch (JSONException e) {
e.printStackTrace();
}
return weather;

}

At line 3 we make the HTTP request and then we parse it at line 6.

At line 9 we retrieve the icon that shows the weather condition.
Running the code we have:


The source code available @github.

I've released a new WeatherLib for Android that simplifies the weather app coding helping you in many app details. This lib supports Openweathermap and other weather provider. If you are interested give a look here
You can even join the new community to talk about it.





Android weather app: JSON, HTTP and Openweathermap Rating: 4.5 Diposkan Oleh: Unknown

21 comments:

  1. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  2. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  3. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  4. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  5. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  6. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  7. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  8. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  9. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  10. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  11. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  12. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  13. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  14. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  15. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  16. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  17. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  18. "Search Engine Land
    https://searchengineland.com/
    Search Engine Land is a leading daily publication c. It also features l contributed articles filled with practicatips, tactics and strategies for running successful marketing campaigns."

    ReplyDelete
  19. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  20. Apex Weather is a new weather app from the developers of Apex Launcher, one of the best Android launchers. This weather app is above average. You get your basic stuff like the current, daily, and hourly forecasts. It also includes a weather map, severe weather alerts, and some of the better clock and weather widgets we've seen in a while. It even shows less common stuff like sunrise and sunset times, air pressure, UV index, and more. You can get weather forecasts in the U.S., U.K., Canada, and Australia along with a rather bland news blog if you want one. The ads can be a tad annoying, but otherwise this weather app checks all of the boxes. You can also remove the ads with a single $5.99 payment.

    ReplyDelete
  21. nice post admin thanks for sharing as If you like to check Lyf Jio F220b Flash File

    ReplyDelete