Android Weather App Get Current Weather Report Part (1/3)

By | March 10, 2015

In this article I’m going to show you how to build your own Android Weather application from scratch , that gives you weather report or information of any specified place ,  to do this i am going to use OpenWeatherMap a free weather service that provides some interesting API really easy to use.


This weather application is split into three part

  1. Current Weather Report
  2. Forecast up to 5days
  3. Each Forecast 3hour interval weather report

In this tutorial we will concentrate on how to get Current weather report , in the upcoming tutorial we will discuss the remaining part

OpenWeatherMap offers below url call to get current weather info

  http://api.openweathermap.org/data/2.5/weather?q=city,country

Internet Permission

add the internet permission inside manifest file .

 <uses-permission android:name=”android.permission.INTERNET” />
 <uses-permission android:name=”android.permission.CHANGE_NETWORK_STATE” />

XML Layout

Create activity_main.xml file inside layout directory.

file :  activity_main.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android”
    android:layout_width=”match_parent”
    android:layout_height=”match_parent”
    android:background=”@drawable/w6″
    android:orientation=”vertical”
    android:padding=”10dp” >

    <EditText
        android:id=”@+id/editText1″
        android:layout_width=”match_parent”
        android:layout_height=”wrap_content”
        android:layout_alignParentTop=”true”
        android:layout_centerHorizontal=”true”
        android:layout_marginTop=”25dp”
        android:ems=”10″
        android:hint=”Enter City….”
        android:textColor=”#ffffff”
        android:textSize=”20sp” >

        <requestFocus />
    </EditText>

    <Button
        android:id=”@+id/button1″
        android:layout_width=”match_parent”
        android:layout_height=”wrap_content”
        android:layout_below=”@+id/editText1″
        android:layout_centerHorizontal=”true”
        android:layout_marginTop=”20dp”
        android:text=”Find”
        android:textColor=”#ffffff”
        android:textSize=”22sp”
         android:textStyle=”bold”
        android:background=”@drawable/progress_btn_default” />

    <TextView
        android:id=”@+id/place”
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        android:layout_alignLeft=”@+id/editText1″
        android:layout_below=”@+id/button1″
        android:layout_marginTop=”24dp”
        android:text=””
        android:textColor=”#ffffff”
        android:textSize=”22sp” />

    <TextView
        android:id=”@+id/min_max”
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        android:layout_alignLeft=”@+id/temp”
        android:layout_below=”@+id/temp”
        android:layout_marginTop=”4dp”
        android:text=””
        android:textColor=”#ffffff”
        android:textSize=”22sp” />

    <TextView
        android:id=”@+id/desc”
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        android:layout_alignParentLeft=”true”
        android:layout_below=”@+id/min_max”
        android:layout_marginLeft=”25dp”
        android:layout_marginTop=”10dp”
        android:text=””
        android:textColor=”#ffffff”
        android:textSize=”22sp” />

    <Button
        android:id=”@+id/forecast”
        android:layout_width=”match_parent”
        android:layout_height=”wrap_content”
        android:layout_alignParentBottom=”true”
        android:text=”Forecast”
        android:textColor=”#ffffff”
        android:textSize=”22sp”
        android:textStyle=”bold”
        android:visibility=”gone”
        android:background=”@drawable/progress_btn_default”/>

    <TextView
        android:id=”@+id/temp”
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        android:layout_alignBottom=”@+id/icon”
        android:layout_alignLeft=”@+id/desc”
        android:text=””
        android:textColor=”#ffffff”
        android:textSize=”60sp”
         />

    <com.android.volley.toolbox.NetworkImageView
        android:id=”@+id/icon”
        android:layout_width=”150dp”
        android:layout_height=”130dp”
        android:layout_centerVertical=”true”
        android:layout_marginLeft=”10dp”
        android:layout_toRightOf=”@+id/temp”
        android:src=”@drawable/ic_launcher” />

</RelativeLayout>

Application Object

Create a class MyApplication which extends Application ,this application object represents singleton pattern , the purpose of this class is make volley request available  through out of the application

  1. The getInstance method of application class returns application object.
  2. The getReqQueue method returns the RequestQueue object
  3. Inside addToReqQueue method we are adding calling add() method upon RequestObject and passing request as paramter to it .
  4. Inside getImageLoader method were we are calling to a constructor of ImageLoader Class by passing requestQueue object and BitmapLruCache object as parameter.

file : MyApplication.java

package com.example.weatherapp;

import android.app.Application;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

public class MyApplication extends Application {

    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private static MyApplication mInstance;

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }

    public static synchronized MyApplication getInstance() {
        return mInstance;
    }

    public RequestQueue getReqQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }

        return mRequestQueue;
    }

    public <T> void addToReqQueue(Request<T> req, String tag) {

        getReqQueue().add(req);
    }

    public <T> void addToReqQueue(Request<T> req) {

        getReqQueue().add(req);
    }

    public ImageLoader getImageLoader() {
        getReqQueue();
        if (mImageLoader == null) {
            mImageLoader = new ImageLoader(this.mRequestQueue,
                    new BitmapLruCache());
        }
        return this.mImageLoader;
    }

    public void cancelPendingReq(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }
}

BitMap Cache

Create a class BitmapLruCache which extends LruCache and override the required method as this class is used for caching the image.

file : BitmapLruCache.java

package com.example.weatherapp;

import android.graphics.Bitmap;
import android.util.LruCache;
import com.android.volley.toolbox.ImageLoader.ImageCache;

public class BitmapLruCache extends LruCache<String, Bitmap> implements
        ImageCache {
    public static int getDefaultLruCacheSize() {
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;

        return cacheSize;
    }

    public BitmapLruCache() {
        this(getDefaultLruCacheSize());
    }

    public BitmapLruCache(int sizeInKiloBytes) {
        super(sizeInKiloBytes);
    }

    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight() / 1024;
    }

    @Override
    public Bitmap getBitmap(String url) {
        return get(url);
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        put(url, bitmap);
    }
}

MainActivity

  1. Create a class MainActivity and extend this class to Activity class and set the content of this activity with above defined XML Layout (activity_main.xml) .
  2. Set the onclick listener for “find” button and inside the onclick method construct the url call to get current weather info
  3. make a volley jsonobjectrequest ,parse the json and then set the parsed json data on to UI .

file : MainActivity.java

package com.example.weatherapp;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.android.volley.Request.Method;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.NetworkImageView;

public class MainActivity extends Activity implements OnClickListener {

    public String Current_URL = “http://api.openweathermap.org/data/2.5/weather?q=”;

    Button btn, forecast_btn;
    TextView temp_tv, min_max_tv, desc_tv, place_tv;
    EditText et;
    NetworkImageView iv;

    ProgressDialog PD;

    String name, id, country, description, icon;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        btn = (Button) findViewById(R.id.button1);
        forecast_btn = (Button) findViewById(R.id.forecast);

        forecast_btn.setOnClickListener(this);

        et = (EditText) findViewById(R.id.editText1);

        place_tv = (TextView) findViewById(R.id.place);
        temp_tv = (TextView) findViewById(R.id.temp);
        min_max_tv = (TextView) findViewById(R.id.min_max);
        desc_tv = (TextView) findViewById(R.id.desc);

        iv = (NetworkImageView) findViewById(R.id.icon);

        btn.setOnClickListener(this);

    }

    public void makejsonreq(String full_url) {

        PD.show();

        JsonObjectRequest jsonObjReq = new JsonObjectRequest(Method.GET,
                full_url, null, new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {

                        try {

                            name = response.getString(“name”);
                            id = response.getString(“id”);

                            JSONObject main = response.getJSONObject(“main”);

                            int temp, temp_max, temp_min;
                            temp = (int) (main.getDouble(“temp”) – 273.15);
                            temp_max = (int) (main.getDouble(“temp_max”) – 273.15);
                            temp_min = (int) (main.getDouble(“temp_min”) – 273.15);

                            JSONObject sys = response.getJSONObject(“sys”);

                            country = sys.getString(“country”);

                            JSONArray weather = response
                                    .getJSONArray(“weather”);

                            JSONObject jo = weather.getJSONObject(0);

                            description = jo.getString(“description”);
                            icon = jo.getString(“icon”);

                            // icon url
                            String icon_url = “http://openweathermap.org/img/w/”
                                    + icon + “.png”;

                            ImageLoader imageLoader = MyApplication
                                    .getInstance().getImageLoader();

                            place_tv.setText(name + “,” + country);

                            temp_tv.setText(temp + “u2103”);
                            min_max_tv.setText(temp_min + “u2103 /” + temp_max
                                    + “u2103”);
                            desc_tv.setText(description);

                            iv.setImageUrl(icon_url, imageLoader);

                            forecast_btn.setVisibility(View.VISIBLE);

                        } catch (JSONException e) {
                            e.printStackTrace();
                            PD.dismiss();
                        }

                        PD.dismiss();

                    }

                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        PD.dismiss();
                    }
                });
        MyApplication.getInstance().addToReqQueue(jsonObjReq, “jreq”);

    }

    @Override
    public void onClick(View view) {

        switch (view.getId()) {
        case R.id.button1:

            PD = new ProgressDialog(MainActivity.this);
            PD.setMessage(“Loading…..”);
            PD.setCancelable(false);

            String city = et.getText().toString();

            String full_url = Current_URL + city;

            makejsonreq(full_url);
            break;

        case R.id.forecast:

            Intent forecast_intent = new Intent(getApplicationContext(),
                    Forecast.class);

            forecast_intent.putExtra(“id”, id);
            forecast_intent.putExtra(“name”, name);

            startActivity(forecast_intent);

            break;
        }

    }

}

Next

In the Next Tutorial we will see how to get the forecast report up to 5days .

  • Error after click button FIND.
    MAKEJSONREQ
    help
    Mauro

  • 1. Make Sure you have build your project with volley library
    check out : http://www.tutorialsbuzz.com/2014/11/android-volley-library-build-project.html

    2. Make Sure you have added internet permission inside manifest.xml file

  • I Have Also Same Error
    I Have Completed Both The Stapes.
    But Still Same Error.

    FATAL EXCEPTION: main
    Process: com.example.vinayak.weather, PID: 10004
    java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.vinayak.weather.MyApplication.addToReqQueue(com.android.volley.Request, java.lang.String)' on a null object reference
    at com.example.vinayak.weather.MainActivity.makejsonreq(MainActivity.java:128)
    at com.example.vinayak.weather.MainActivity.onClick(MainActivity.java:146)

  • Hi, I do the same thing , but i have nothing on the screen when i run the app?
    Help please