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"
}
}