Android Weather App Get Forecast Report Part (2/3)

By | March 11, 2015

In the previous post we have seen how to get current weather report of any specified place , in this post we will see how to get weather forecast report as you can see in the previous post there is a forecast button at the bottom of the UI on click of it we are starting a new activity by passing the place id  through intent object , in this activity we will make http request and then parse the response json and show it on to listview .

OpenWeatherMap offers below url call to get forecast weather info

http://api.openweathermap.org/data/2.5/forecast?id=place_id

XML Layout

Create forecast.xml file inside layout directory and add ListView to it .

file : forecast.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout
    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” >

    <ListView
        android:id=”@+id/flv”
        android:layout_width=”match_parent”
        android:layout_height=”match_parent” >
    </ListView>

</LinearLayout>

Create list_item.xml file inside layout directory , this layout represents the rows of the listview .

file : list_item.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<RelativeLayout
    xmlns:android=”http://schemas.android.com/apk/res/android”
    android:layout_width=”fill_parent”
    android:layout_height=”fill_parent”
    android:padding=”5dp” >

    <TextView
        android:id=”@+id/fmin_max”
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        android:layout_alignLeft=”@+id/ftemp”
        android:layout_below=”@+id/ftemp”
        android:textColor=”#ffffff”
        android:textSize=”20sp” />

    <com.android.volley.toolbox.NetworkImageView
        android:id=”@+id/ficon”
        android:layout_width=”100dp”
        android:layout_height=”100dp”
        android:layout_alignParentLeft=”true”
        android:layout_alignParentTop=”true”
        android:layout_marginLeft=”5dp”
        android:contentDescription=”desc”
        android:src=”@drawable/ic_launcher” />

    <TextView
        android:id=”@+id/ftemp”
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        android:layout_alignTop=”@+id/ficon”
        android:layout_marginLeft=”8dp”
        android:layout_marginTop=”15dp”
        android:layout_toRightOf=”@+id/ficon”
        android:textColor=”#ffffff”
        android:textSize=”43sp” />

    <TextView
        android:id=”@+id/fdesc”
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        android:layout_alignLeft=”@+id/ficon”
        android:layout_below=”@+id/ficon”
        android:layout_marginLeft=”10dp”
        android:textColor=”#ffffff”
        android:textSize=”20sp” />

    <TextView
        android:id=”@+id/fdate”
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        android:layout_alignParentRight=”true”
        android:layout_alignTop=”@+id/ficon”
        android:background=”@drawable/textborder”
        android:paddingRight=”3dp”
        android:textColor=”#ffffff”
        android:textSize=”18sp” />

</RelativeLayout>

 Java Bean

Create a Bean Class RowItem which is used for setting and getting row data’s of each items in ListView.

file :RowItem.java

package com.example.weatherapp;

public class RowItem {

    int temp, temp_max, temp_min;
    String mdate, description, icon;

    public RowItem(int temp, int temp_max, int temp_min, String description,
            String icon, String mdate) {

        this.temp = temp;
        this.temp_max = temp_max;
        this.temp_min = temp_min;
        this.description = description;
        this.icon = icon;
        this.mdate = mdate;
    }

    public String getMdate() {
        return mdate;
    }

    public void setMdate(String mdate) {
        this.mdate = mdate;
    }

    public int getTemp() {
        return temp;
    }

    public void setTemp(int temp) {
        this.temp = temp;
    }

    public int getTemp_max() {
        return temp_max;
    }

    public void setTemp_max(int temp_max) {
        this.temp_max = temp_max;
    }

    public int getTemp_min() {
        return temp_min;
    }

    public void setTemp_min(int temp_min) {
        this.temp_min = temp_min;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getIcon() {
        return icon;
    }

    public void setIcon(String icon) {
        this.icon = icon;
    }

}

Adapter

Create a custom adapter which extends BaseAdapter , this is used for inflating each row items of the listview .

file : CustomAdapter.java

package com.example.weatherapp;

import java.util.List;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class CustomAdapter extends BaseAdapter {

    Context context;
    List<RowItem> rowItems;
    ImageLoader imageLoader = MyApplication.getInstance().getImageLoader();

    public CustomAdapter(Context context, List<RowItem> rowItems) {

        this.context = context;
        this.rowItems = rowItems;

    }

    @Override
    public int getCount() {

        return rowItems.size();
    }

    @Override
    public Object getItem(int position) {

        return rowItems.get(position);
    }

    @Override
    public long getItemId(int position) {

        return rowItems.indexOf(getItem(position));
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        LayoutInflater mInflater = (LayoutInflater) context
                .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.list_item, null);
        }

        TextView temp_tv, minmax_tv, desc_tv, date_tv;

        NetworkImageView niv;

        temp_tv = (TextView) convertView.findViewById(R.id.ftemp);
        minmax_tv = (TextView) convertView.findViewById(R.id.fmin_max);
        desc_tv = (TextView) convertView.findViewById(R.id.fdesc);
        date_tv = (TextView) convertView.findViewById(R.id.fdate);
        niv = (NetworkImageView) convertView.findViewById(R.id.ficon);

        RowItem item = rowItems.get(position);

        temp_tv.setText(item.getTemp() + “u2103”);
        minmax_tv.setText(item.getTemp_min() + “u2103” + “\”
                + item.getTemp_min() + “u2103”);
        desc_tv.setText(item.getDescription() + “”);
        date_tv.setText(item.getMdate() + “”);

        String icon_url = “http://openweathermap.org/img/w/” + item.getIcon()
                + “.png”;

        niv.setImageUrl(icon_url, imageLoader);

        return convertView;
    }

}

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 (forecast.xml) .
  2. Set the listview with above defined custom adapter .
  3. Inside the onCreate Method make a volley jsonobjectrequest ,and parse the response json and then set the parsed json data on to UI .
  4. The response json contains forecast report upto 5days , and it also contains 3hours interval report for each day so here we will try to get one weather report per day.

file : MainActivity.java

package com.example.weatherapp;

import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

import com.android.volley.Request.Method;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;

public class Forecast extends Activity {

    String forecast_url = “http://api.openweathermap.org/data/2.5/forecast?id=”;

    ProgressDialog PD;

    ListView lv;
    CustomAdapter adapter;
    List<RowItem> rowItems = new ArrayList<RowItem>();

    String place_id, place_name;

    JSONObject mJsonObj;

    @SuppressLint(“NewApi”)
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.forecast);

        lv = (ListView) findViewById(R.id.flv);

        Intent i = getIntent();
        place_id = i.getExtras().getString(“id”);
        place_name = i.getExtras().getString(“name”);

        getActionBar().setSubtitle(place_name);

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

        String full_url = forecast_url + place_id;

        adapter = new CustomAdapter(getApplicationContext(), rowItems);
        lv.setAdapter(adapter);

        lv.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1,
                    int position, long id) {

                Toast.makeText(
                        getApplicationContext(),
                        “Id: ” + place_id + “Date: “
                                + rowItems.get(position).getMdate(),
                        Toast.LENGTH_LONG).show();

                Intent i = new Intent(getApplicationContext(), Interval.class);

                i.putExtra(“placeid”, place_id);
                i.putExtra(“name”, place_name);

                i.putExtra(“mDate”, rowItems.get(position).getMdate());
                i.putExtra(“jo”, mJsonObj.toString());

                startActivity(i);

            }
        });

        makejsonreq(full_url);

    }

    public void makejsonreq(String url) {

        PD.show();
        JsonObjectRequest jsonObjReqq = new JsonObjectRequest(Method.GET, url,
                null, new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {
                        mJsonObj = response;
                        try {
                            JSONArray jlist = response.getJSONArray(“list”);

                            String dt = null;
                            String pre_dt = null;

                            for (int i = 0; i < jlist.length(); i++) {
                                dt = jlist.getJSONObject(i).getString(“dt_txt”)
                                        .substring(8, 10);

                                if (i > 1 || i == 1) {
                                    pre_dt = jlist.getJSONObject(i – 1)
                                            .getString(“dt_txt”)
                                            .substring(8, 10);

                                    if (!(dt.equals(pre_dt))) {

                                        String mdate = jlist.getJSONObject(i)
                                                .getString(“dt_txt”)
                                                .substring(0, 10);

                                        JSONObject main = jlist
                                                .getJSONObject(i)
                                                .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);

                                        JSONArray weather = jlist
                                                .getJSONObject(i).getJSONArray(
                                                        “weather”);

                                        String icon = weather.getJSONObject(0)
                                                .getString(“icon”);
                                        String description = weather
                                                .getJSONObject(0).getString(
                                                        “description”);

                                        RowItem rItem = new RowItem(temp,
                                                temp_max, temp_min,
                                                description, icon, mdate);

                                        rowItems.add(rItem);
                                    } // if end
                                } // if end
                            } // for end

                        } catch (JSONException e) {
                            e.printStackTrace();
                            PD.dismiss();
                        }
                        adapter.notifyDataSetChanged();
                        PD.dismiss();
                    }
                }, new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        PD.dismiss();
                    }
                });

        MyApplication.getInstance().addToReqQueue(jsonObjReqq, “jreqq”);
    }
}

Add the above forecast activity component inside manifest file

<activity android:name=”.Forecast” > </activity>

Next 

In the next tutorial we will see how to get hourly weather report for each forecast .