If you search on Google Play Store, you’ll find most weather apps either full of ads or require too many permissions, or includes unwanted features that most of us never use.
So, instead, wouldn’t it be great to offer a simple yet best weather app of your own eliminating those unwanted features that are irrelevant?
Today, in this Android weather app tutorial, we’ll learn how to implement OpenWeatherMap API in any android app with a simple user interface to offer current weather conditions.
Let’s Get Started
Create a new project and give name, package name and choose a location for the demo.
In the next tab, choose Mini support SDK.
Lastly, select ‘Add No Activity’.
Now, create XML file for displaying weather data.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" 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" android:orientation="vertical"> <RelativeLayout 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" android:layout_weight="1" > <TextView android:id="@+id/cityText" style="?android:attr/textAppearanceMedium" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#990000" android:layout_alignParentLeft="true"> </TextView> <TextView android:id="@+id/temp" style="@style/tempStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/cityText" android:textColor="#000000" android:textSize="130sp" android:layout_centerHorizontal="true"> </TextView> <TextView android:id="@+id/unittemp" android:layout_width="wrap_content" style="?android:attr/textAppearanceMedium" android:layout_height="wrap_content" android:layout_below="@id/cityText" android:layout_toRightOf="@id/temp" android:layout_alignBaseline="@id/temp"> </TextView> <TextView android:id="@+id/skydesc" android:layout_width="wrap_content" style="?android:attr/textAppearanceMedium" android:layout_height="wrap_content" android:layout_below="@id/temp" android:layout_alignStart="@id/temp" android:layout_toRightOf="@id/temp"> </TextView> <!-- Image weather condition --> <ImageView android:id="@+id/condIcon" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_alignTop="@id/temp" android:layout_toRightOf="@id/temp" /> </RelativeLayout> <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="6" > <android.support.v4.view.PagerTitleStrip android:id="@+id/pager_title_strip" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="top" android:background="#000000" android:paddingBottom="4dp" android:paddingTop="4dp" android:textColor="#fff" /> </android.support.v4.view.ViewPager> </LinearLayout>
Here, Viewpager is used to display 3 days data from today.
Set number of Days to get the data and also set the City and Country.
private static String forecastDaysNum = "3"; String city = "Ahmedabad, IN";
Get all the fields in MainActivity and call the AsyncTask to get the weather data.
cityText = (TextView) findViewById(R.id.cityText); temp = (TextView) findViewById(R.id.temp); unitTemp = (TextView) findViewById(R.id.unittemp); unitTemp.setText("C"); condDescr = (TextView) findViewById(R.id.skydesc); pager = (ViewPager) findViewById(R.id.pager); imgView = (ImageView) findViewById(R.id.condIcon); // AsyncTask to call URL to get Weather data. JSONWeatherTask task = new JSONWeatherTask(); task.execute(new String[]{city, lang}); JSONForecastWeatherTask task1 = new JSONForecastWeatherTask(); task1.execute(new String[]{city, lang, forecastDaysNum});
Create one Class in which Url will be called and we will get the data named “WeatherHttpClient”.
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/"; private static String BASE_FORECAST_URL = "http://api.openweathermap.org/data/2.5/forecast/daily?mode=json&q="; public String getWeatherData(String location, String lang) { HttpURLConnection con = null; InputStream is = null; try { String url = BASE_URL + location; if (lang != null) { url = url + "&lang=" + lang+"&APPID="+"<YOUR API KEY>"; } Log.d("Tag","URL "+url); con = (HttpURLConnection) ( new URL(url)).openConnection(); con.setRequestMethod("GET"); con.setDoInput(true); con.setDoOutput(true); con.connect(); // Let's read the response StringBuffer buffer = null; try { 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"); } } catch (IOException e) { e.printStackTrace(); } 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 String getForecastWeatherData(String location, String lang, String sForecastDayNum) { HttpURLConnection con = null; InputStreamReader is = null; int forecastDayNum = Integer.parseInt(sForecastDayNum); try { // Forecast String url = BASE_FORECAST_URL + location; if (lang != null) { url = url + "&lang=" + lang; } url = url + "&cnt=" + forecastDayNum+"&APPID="; con = (HttpURLConnection) ( new URL(url)).openConnection(); con.setRequestMethod("GET"); con.setDoInput(true); con.setDoOutput(true); con.connect(); StringBuffer buffer1 = null; Log.d("Tag","connection "+con.toString()); try { // Let's read the response buffer1 = new StringBuffer(); is = new InputStreamReader(con.getInputStream());//con.getInputStream(); BufferedReader br1 = new BufferedReader(is); String line1 = null; while ( (line1 = br1 buffer1.append(line1 + "\r\n"); } catch (IOException e) { e.printStackTrace(); } is.close(); con.disconnect(); System.out.println("Buffer [" + buffer1.toString() + "]"); return buffer1.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;
To get API Key you need to create an account in http://api.openweathermap.org and need to create one API key and that key will be used here to get details.
Want To Develop An Android Application?
Need to validate your app idea or consult with an expert? Get a free consultation now!
The details will be returned in JSON format so we have created one JSON parser class.
public class JSONWeatherParser { public static Weather getWeather(String data) throws JSONException { Weather weather = new Weather(); System.out.println("Data ["+data+"]"); // We create out JSONObject from the dataJSONObject jObj = new JSONObject(data); // We start extracting the infoLocation 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; // 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)); // We download the icon to show return weather; } public static WeatherForecast getForecastWeather(String data) throws JSONException { WeatherForecast forecast = new WeatherForecast(); // We create out JSONObject from the data JSONObject jObj = new JSONObject(data); JSONArray jArr = jObj.getJSONArray("list"); // Here we have the forecast for every day // We traverse all the array and parse the data for (int i=0; i < jArr.length(); i++) { JSONObject jDayForecast = jArr.getJSONObject(i); // Now we have the json object so we can extract the data DayForecast df = new DayForecast(); // We retrieve the timestamp (dt) df.timestamp = jDayForecast.getLong("dt"); // Temp is an object JSONObject jTempObj = jDayForecast.getJSONObject("temp"); df.forecastTemp.day = (float) jTempObj.getDouble("day"); df.forecastTemp.min = (float) jTempObj.getDouble("min"); df.forecastTemp.max = (float) jTempObj.getDouble("max"); df.forecastTemp.night = (float) jTempObj.getDouble("night"); df.forecastTemp.eve = (float) jTempObj.getDouble("eve"); df.forecastTemp.morning = (float) jTempObj.getDouble("morn"); // Pressure & Humidity df.weather.currentCondition.setPressure((float) jDayForecast.getDouble("pressure")); df.weather.currentCondition.setHumidity((float) jDayForecast.getDouble("humidity")); // ...and now the weather JSONArray jWeatherArr = jDayForecast.getJSONArray("weather"); JSONObject jWeatherObj = jWeatherArr.getJSONObject(0); df.weather.currentCondition.setWeatherId(getInt("id", jWeatherObj)); df.weather.currentCondition.setDescr(getString("description", jWeatherObj)); df.weather.currentCondition.setCondition(getString("main", jWeatherObj)); df.weather.currentCondition.setIcon(getString("icon", jWeatherObj)); // Wind wObj = jDayForecast.getJSONObject("wind"); df.weather.wind.setSpeed((float) wObj.getDouble("speed")); df.weather.wind.setDeg((float) wObj.getDouble("deg")); // Clouds df.weather.clouds.setPerc(jDayForecast.getInt("clouds")); // We add this object to the list forecast.addForecast(df); } return forecast; } private static JSONObject getObject(String tagName, JSONObject jObj) throws JSONException { return jObj.getJSONObject(tagName); } 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); } }
Final data will be set in below fields.
cityText.setText(weather.location.getCity() + "," + weather.location.getCountry()); temp.setText("" + Math.round((weather.temperature.getTemp() - 275.15))); condDescr.setText( weather.currentCondition.getCondition() + "(" + weather.currentCondition.getDescr() + ")" );
That’s it!
Neat and simple, right?
Though, there are several options to include the weather feature. For instance, news or other relatives apps can integrate the weather feature using OpenWeatherMap API to as an additional feature.
But, in order to do so, you might need to consult with a top Android app development company or contact expert developers to make sure the feature is implemented correctly.
Moreover, implementing this feature will not only make your app informative but adding an extra feature can further enhance your android application.
Useful resources