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