The app creates a second thread with
AsyncTask
.
The thread sends an HTTP GET command to the
Open Weathermap
server.
(Compare the download without the GET in exercise 7 of
Offer.)
See OpenWeatherMap’s documentation for the
zip
,
units
,
and
mode
parameters of the URL.
The response is a
String
containing a string in JSON format representing a JSON object.
We call the constructor for class
JSONObject
to create a
JSONObject
that holds the information in this JSON object,
and call
getJSONObject
,
getDouble
,
and
getLong
to get some of the fields of the JSON object.
MainActivity.java
activity_main.xml
consists of a
RelativeLayout
containing a
ScrollView
containing a
TextView
.
The
ScrollView
lets the
TextView
scroll.
strings.xml
AndroidManifest.xml
has
uses-permission
INTERNET
.
build.gradle
(Module: app).
See Parameters, Weather Condition Codes, and Weather icons.
JSON string downloaded from server = {"coord":{"lon":-74.01,"lat":40.71},"weather":[{"id":701,"main":"Mist","description":"mist","icon":"50n"},{"id":500,"main":"Rain","description":"light rain","icon":"10n"}],"base":"cmc stations","main":{"temp":76.69,"pressure":1015,"humidity":65,"temp_min":70,"temp_max":84.2},"wind":{"speed":7.78,"deg":220},"clouds":{"all":40},"dt":1436324173,"sys":{"type":1,"id":1975,"message":0.006,"country":"US","sunrise":1436347955,"sunset":1436401761},"id":5128581,"name":"New York","cod":200} JSON object = { "id": 5128581, "dt": 1436324173, "clouds": { "all": 40 }, "coord": { "lat": 40.71, "lon": -74.01 }, "wind": { "speed": 7.78, "deg": 220 }, "cod": 200, "sys": { "message": 0.006, "id": 1975, "sunrise": 1436347955, "type": 1, "sunset": 1436401761, "country": "US" }, "name": "New York", "base": "cmc stations", "weather": [ { "id": 701, "icon": "50n", "description": "mist", "main": "Mist" }, { "id": 500, "icon": "10n", "description": "light rain", "main": "Rain" } ], "main": { "temp_min": 70, "temp": 76.69, "humidity": 65, "pressure": 1015, "temp_max": 84.2 } } dt = 1436324173 dt = Tuesday, July 7, 2015 10:56:13 PM EDT main = { "temp_min": 70, "temp": 76.69, "humidity": 65, "pressure": 1015, "temp_max": 84.2 } Temperature in 10003 is 76.69° Fahrenheit.
urlString
is pasted together with
question marks, ampersands, and equal signs.
Instead of pasting it yourself,
create it with a
Uri.Builder
.
It’s like the
AlertDialog.Builder
we saw in
Text.
Uri uri = Uri.parse("http://api.openweathermap.org/data/2.5/weather"); Uri.Builder builder = uri.buildUpon(); builder.appendQueryParameter("zip", zip[0]); builder.appendQueryParameter("units", "imperial"); builder.appendQueryParameter("mode", "json"); uri = builder.build(); String urlString = uri.toString();
You can even do it in a single statement:
String urlString = Uri.parse("http://api.openweathermap.org/data/2.5/weather") .buildUpon() .appendQueryParameter("zip", zip[0]) .appendQueryParameter("units", "imperial") .appendQueryParameter("mode", "json") .build() .toString();
ArrayAdapter<String>
,
and plug the
ArrayAdapter<String>
into a
ListView
.
In
activity_main.xml
,
replace the
TextView
with the following.
<ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="wrap_content"/>
In
doInBackground
in
MainActivity.java
,
String urlString = "http://api.openweathermap.org/data/2.5/forecast/daily" + "?zip=" + zip[0] //7 East 12th Street, New York NY 10003 + "&cnt=5" //number of days + "&units=imperial" //fahrenheit, not celsius + "&mode=json"; //vs. xml or html
Change
useTheResult
to the following.
private void useTheResult(String json) { if (json == null) { return; } String[] a = new String[5]; try { JSONObject jSONObject = new JSONObject(json); JSONArray list = jSONObject.getJSONArray("list"); DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL, Locale.getDefault()); for (int i = 0; i < list.length(); ++i) { JSONObject day = (JSONObject)list.get(i); long seconds = day.getLong("dt"); JSONObject temp = (JSONObject)day.getJSONObject("temp"); double max = temp.getDouble("max"); a[i] = Math.round(max) + "\u00B0 F " + dateFormat.format(1000L * seconds); } } catch (JSONException exception) { Toast toast = Toast.makeText(this, exception.toString(), Toast.LENGTH_LONG); toast.show(); } ArrayAdapter<String> adapter = new ArrayAdapter<String> ( this, android.R.layout.simple_list_item_1, a ); ListView listView = (ListView)findViewById(R.id.listView); listView.setAdapter(adapter); }
The JSON object contains an array named
list
.
The array contains five days in its
[
square brackets]
.
{ "message": 0.0156, "list": [ { "clouds": 12, "dt": 1436288400, "humidity": 84, "pressure": 1010.12, "speed": 4.8, "deg": 221, "weather": [ { "id": 801, "icon": "02n", "description": "few clouds", "main": "Clouds" } ], "temp": { "morn": 75.31, "min": 72.88, "night": 72.88, "eve": 75.31, "max": 75.31, "day": 75.31 } }, { "clouds": 80, "dt": 1436374800, "humidity": 80, "pressure": 1007.54, "speed": 5.96, "deg": 245, "weather": [ { "id": 500, "icon": "10d", "description": "light rain", "main": "Rain" } ], "temp": { "morn": 75.7, "min": 70, "night": 70, "eve": 76.89, "max": 80.15, "day": 80.15 }, "rain": 1.08 }, { "clouds": 56, "dt": 1436461200, "humidity": 87, "pressure": 1009.84, "speed": 3.05, "deg": 162, "weather": [ { "id": 502, "icon": "10d", "description": "heavy intensity rain", "main": "Rain" } ], "temp": { "morn": 67.14, "min": 63.55, "night": 63.55, "eve": 73.22, "max": 74.82, "day": 73.35 }, "rain": 16.8 }, { "clouds": 0, "dt": 1436547600, "humidity": 63, "pressure": 1013.03, "speed": 4.56, "deg": 347, "weather": [ { "id": 800, "icon": "01d", "description": "sky is clear", "main": "Clear" } ], "temp": { "morn": 65.93, "min": 64.27, "night": 64.27, "eve": 72.82, "max": 78.15, "day": 76.89 } }, { "clouds": 5, "dt": 1436634000, "humidity": 0, "pressure": 1016.29, "speed": 2.31, "deg": 298, "weather": [ { "id": 500, "icon": "10d", "description": "light rain", "main": "Rain" } ], "temp": { "morn": 70.93, "min": 68.29, "night": 68.29, "eve": 76.46, "max": 78.33, "day": 78.33 }, "rain": 0.37 } ], "cnt": 5, "cod": "200", "city": { "coord": { "lat": 40.714272, "lon": -74.005966 }, "id": 5128581, "population": 0, "country": "US", "name": "New York" } }