raghav-coder
4/12/2018 - 10:43 AM

Parsing JSON

package com.example.android.sunshine.utilities;

import android.content.ContentValues;
import android.content.Context;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.net.HttpURLConnection;

/**
 * Utility functions to handle OpenWeatherMap JSON data.
 */
public final class OpenWeatherJsonUtils {

    /**
     * This method parses JSON from a web response and returns an array of Strings
     * describing the weather over various days from the forecast.
     * <p/>
     * Later on, we'll be parsing the JSON into structured data within the
     * getFullWeatherDataFromJson function, leveraging the data we have stored in the JSON. For
     * now, we just convert the JSON into human-readable strings.
     *
     * @param forecastJsonStr JSON response from server
     *
     * @return Array of Strings describing weather data
     *
     * @throws JSONException If JSON data cannot be properly parsed
     */
    
    // @@1
    public static String[] getSimpleWeatherStringsFromJson(Context context, String forecastJsonStr)
            throws JSONException {

        /* Weather information. Each day's forecast info is an element of the "list" array */
        final String OWM_LIST = "list";

        /* All temperatures are children of the "temp" object */
        final String OWM_TEMPERATURE = "temp";

        /* Max temperature for the day */
        final String OWM_MAX = "max";
        final String OWM_MIN = "min";

        final String OWM_WEATHER = "weather";
        final String OWM_DESCRIPTION = "main";

        final String OWM_MESSAGE_CODE = "cod";

        /* String array to hold each day's weather String */
        String[] parsedWeatherData = null;

        JSONObject forecastJson = new JSONObject(forecastJsonStr);

        /* Is there an error? */
        if (forecastJson.has(OWM_MESSAGE_CODE)) {
            int errorCode = forecastJson.getInt(OWM_MESSAGE_CODE);

            switch (errorCode) {
                case HttpURLConnection.HTTP_OK:
                    break;
                case HttpURLConnection.HTTP_NOT_FOUND:
                    /* Location invalid */
                    return null;
                default:
                    /* Server probably down */
                    return null;
            }
        }

        JSONArray weatherArray = forecastJson.getJSONArray(OWM_LIST);

        parsedWeatherData = new String[weatherArray.length()];

        long localDate = System.currentTimeMillis();
        long utcDate = SunshineDateUtils.getUTCDateFromLocal(localDate);
        long startDay = SunshineDateUtils.normalizeDate(utcDate);

        for (int i = 0; i < weatherArray.length(); i++) {
            String date;
            String highAndLow;

            /* These are the values that will be collected */
            long dateTimeMillis;
            double high;
            double low;
            String description;

            /* Get the JSON object representing the day */
            JSONObject dayForecast = weatherArray.getJSONObject(i);

            /*
             * We ignore all the datetime values embedded in the JSON and assume that
             * the values are returned in-order by day (which is not guaranteed to be correct).
             */
            dateTimeMillis = startDay + SunshineDateUtils.DAY_IN_MILLIS * i;
            date = SunshineDateUtils.getFriendlyDateString(context, dateTimeMillis, false);

            /*
             * Description is in a child array called "weather", which is 1 element long.
             * That element also contains a weather code.
             */
            JSONObject weatherObject =
                    dayForecast.getJSONArray(OWM_WEATHER).getJSONObject(0);
            description = weatherObject.getString(OWM_DESCRIPTION);

            /*
             * Temperatures are sent by Open Weather Map in a child object called "temp".
             *
             * Editor's Note: Try not to name variables "temp" when working with temperature.
             * It confuses everybody. Temp could easily mean any number of things, including
             * temperature, temporary and is just a bad variable name.
             */
            JSONObject temperatureObject = dayForecast.getJSONObject(OWM_TEMPERATURE);
            high = temperatureObject.getDouble(OWM_MAX);
            low = temperatureObject.getDouble(OWM_MIN);
            highAndLow = SunshineWeatherUtils.formatHighLows(context, high, low);

            parsedWeatherData[i] = date + " - " + description + " - " + highAndLow;
        }

        return parsedWeatherData;
    }

    /**
     * Parse the JSON and convert it into ContentValues that can be inserted into our database.
     *
     * @param context         An application context, such as a service or activity context.
     * @param forecastJsonStr The JSON to parse into ContentValues.
     *
     * @return An array of ContentValues parsed from the JSON.
     */
    public static ContentValues[] getFullWeatherDataFromJson(Context context, String forecastJsonStr) {
        /** This will be implemented in a future lesson **/
        return null;
    }
}
{
  "city":   {
    "id": 5375480,
    "name": "Mountain View",
    "coord":     {
      "lon": -122.08384,
      "lat": 37.386051
    },
    "country": "US",
    "population": 0
  },
  "cod": "200",
  "message": 0.0158,
  "cnt": 14,
  "list":   [
        {
      "dt": 1523183551.287,
      "temp":       {
        "day": 29.49,
        "min": 13.32,
        "max": 18.27,
        "night": 9.52,
        "eve": 21.09,
        "morn": 15.42
      },
      "pressure": 996.68,
      "humidity": 96,
      "weather": [      {
        "id": 500,
        "main": "Light Rain",
        "description": "Light Rain",
        "icon": "02d"
      }],
      "speed": 1.2,
      "deg": 0,
      "clouds": 20
    },
        {
      "dt": 1523269951.287,
      "temp":       {
        "day": 29.49,
        "min": 12.66,
        "max": 17.34,
        "night": 9.52,
        "eve": 21.09,
        "morn": 15.42
      },
      "pressure": 996.12,
      "humidity": 97,
      "weather": [      {
        "id": 501,
        "main": "Moderate Rain",
        "description": "Moderate Rain",
        "icon": "02d"
      }],
      "speed": 4.8,
      "deg": 45,
      "clouds": 20
    },
        {
      "dt": 1523356351.287,
      "temp":       {
        "day": 29.49,
        "min": 12.07,
        "max": 16.48,
        "night": 9.52,
        "eve": 21.09,
        "morn": 15.42
      },
      "pressure": 995.7,
      "humidity": 90,
      "weather": [      {
        "id": 800,
        "main": "Clear",
        "description": "Clear",
        "icon": "02d"
      }],
      "speed": 8.2,
      "deg": 90,
      "clouds": 20
    },
        {
      "dt": 1523442751.287,
      "temp":       {
        "day": 29.49,
        "min": 11.53,
        "max": 12.34,
        "night": 9.52,
        "eve": 21.09,
        "morn": 15.42
      },
      "pressure": 1001.22,
      "humidity": 87,
      "weather": [      {
        "id": 802,
        "main": "Scattered Clouds",
        "description": "Scattered Clouds",
        "icon": "02d"
      }],
      "speed": 3.6,
      "deg": 135,
      "clouds": 20
    },
        {
      "dt": 1523529151.287,
      "temp":       {
        "day": 29.49,
        "min": 14.62,
        "max": 15.36,
        "night": 9.52,
        "eve": 21.09,
        "morn": 15.42
      },
      "pressure": 1001.51,
      "humidity": 88,
      "weather": [      {
        "id": 803,
        "main": "Broken Clouds",
        "description": "Broken Clouds",
        "icon": "02d"
      }],
      "speed": 4,
      "deg": 180,
      "clouds": 20
    },
        {
      "dt": 1523615551.287,
      "temp":       {
        "day": 29.49,
        "min": -2,
        "max": -1.1,
        "night": 9.52,
        "eve": 21.09,
        "morn": 15.42
      },
      "pressure": 997.54,
      "humidity": 78,
      "weather": [      {
        "id": 600,
        "main": "Light Snow",
        "description": "Light Snow",
        "icon": "02d"
      }],
      "speed": 2.6,
      "deg": 225,
      "clouds": 20
    },
        {
      "dt": 1523701951.287,
      "temp":       {
        "day": 29.49,
        "min": -1.5,
        "max": -1,
        "night": 9.52,
        "eve": 21.09,
        "morn": 15.42
      },
      "pressure": 996.55,
      "humidity": 80,
      "weather": [      {
        "id": 601,
        "main": "Snow",
        "description": "Snow",
        "icon": "02d"
      }],
      "speed": 3.8,
      "deg": 270,
      "clouds": 20
    },
        {
      "dt": 1523788351.287,
      "temp":       {
        "day": 29.49,
        "min": -1,
        "max": 0.5,
        "night": 9.52,
        "eve": 21.09,
        "morn": 15.42
      },
      "pressure": 996.76,
      "humidity": 85,
      "weather": [      {
        "id": 602,
        "main": "Heavy Snow",
        "description": "Heavy Snow",
        "icon": "02d"
      }],
      "speed": 5.2,
      "deg": 315,
      "clouds": 20
    },
        {
      "dt": 1523874751.287,
      "temp":       {
        "day": 29.49,
        "min": 0.5,
        "max": 2,
        "night": 9.52,
        "eve": 21.09,
        "morn": 15.42
      },
      "pressure": 998.56,
      "humidity": 90,
      "weather": [      {
        "id": 611,
        "main": "Sleet",
        "description": "Sleet",
        "icon": "02d"
      }],
      "speed": 10.3,
      "deg": 0,
      "clouds": 20
    },
        {
      "dt": 1523961151.287,
      "temp":       {
        "day": 29.49,
        "min": 5,
        "max": 7.5,
        "night": 9.52,
        "eve": 21.09,
        "morn": 15.42
      },
      "pressure": 1000.21,
      "humidity": 80,
      "weather": [      {
        "id": 741,
        "main": "Fog",
        "description": "Fog",
        "icon": "02d"
      }],
      "speed": 1.5,
      "deg": 45,
      "clouds": 20
    },
        {
      "dt": 1524047551.287,
      "temp":       {
        "day": 29.49,
        "min": 10.21,
        "max": 12.35,
        "night": 9.52,
        "eve": 21.09,
        "morn": 15.42
      },
      "pressure": 1000.11,
      "humidity": 97,
      "weather": [      {
        "id": 960,
        "main": "Storm",
        "description": "Storm",
        "icon": "02d"
      }],
      "speed": 70.2,
      "deg": 90,
      "clouds": 20
    },
        {
      "dt": 1524133951.287,
      "temp":       {
        "day": 29.49,
        "min": 12.2,
        "max": 19.01,
        "night": 9.52,
        "eve": 21.09,
        "morn": 15.42
      },
      "pressure": 990.01,
      "humidity": 97,
      "weather": [      {
        "id": 960,
        "main": "Storm",
        "description": "Storm",
        "icon": "02d"
      }],
      "speed": 80.1,
      "deg": 135,
      "clouds": 20
    },
        {
      "dt": 1524220351.287,
      "temp":       {
        "day": 29.49,
        "min": 13,
        "max": 18.01,
        "night": 9.52,
        "eve": 21.09,
        "morn": 15.42
      },
      "pressure": 989.01,
      "humidity": 98,
      "weather": [      {
        "id": 901,
        "main": "Tropical Storm",
        "description": "Tropical Storm",
        "icon": "02d"
      }],
      "speed": 110.1,
      "deg": 180,
      "clouds": 20
    },
        {
      "dt": 1524306751.287,
      "temp":       {
        "day": 29.49,
        "min": 12.2,
        "max": 19.01,
        "night": 9.52,
        "eve": 21.09,
        "morn": 15.42
      },
      "pressure": 980.01,
      "humidity": 99,
      "weather": [      {
        "id": 902,
        "main": "Hurricane",
        "description": "Hurricane",
        "icon": "02d"
      }],
      "speed": 148.1,
      "deg": 225,
      "clouds": 20
    }
  ]
}
## Steps 

1. Parsing example