Parse a String in JSON Format

Drag on the TextView to scroll it horizontally and vertically. I don’t know why the android:scrollHorizontally="true" attribute of the TextView didn’t work; I had to call the Java method setHorizontallyScrolling in onCreate instead.

Source code in Json.zip

  1. MainActivity.java
  2. activity_main.xml
  3. strings.xml
  4. AndroidManifest.xml
  5. build.gradle (Module: app).

The string in JSON Format

I sent a query to the OpenWeatherMap server asking for the current weather in zip code 10003, which contains 7 East 12th Street. The reply I got was the following string in JSON format.

{"coord":{"lon":-74.01,"lat":40.71},"weather":[{"id":741,"main":"Fog","description":"fog","icon":"50d"}],"base":"cmc stations","main":{"temp":73.24,"pressure":1017,"humidity":88,"temp_min":69.8,"temp_max":75.2},"wind":{"speed":6.7,"deg":160},"clouds":{"all":75},"dt":1436262811,"sys":{"type":1,"id":2120,"message":0.0068,"country":"US","sunrise":1436261527,"sunset":1436315377},"id":5128581,"name":"New York","cod":200}

In the language Java, a string literal ("Hello, world!") requires a backslash in front of each double quote:

        String jSONString = "{\"coord\":{\"lon\":-74.01,\"lat\":40.71},\"weather\":[{\"id\":741,\"main\":\"Fog\",\"description\":\"fog\",\"icon\":\"50d\"}],\"base\":\"cmc stations\",\"main\":{\"temp\":73.24,\"pressure\":1017,\"humidity\":88,\"temp_min\":69.8,\"temp_max\":75.2},\"wind\":{\"speed\":6.7,\"deg\":160},\"clouds\":{\"all\":75},\"dt\":1436262811,\"sys\":{\"type\":1,\"id\":2120,\"message\":0.0068,\"country\":\"US\",\"sunrise\":1436261527,\"sunset\":1436315377},\"id\":5128581,\"name\":\"New York\",\"cod\":200}";

5128581 is the city id for New York City. For the parameters coord, weather, base, etc., see OpenWeatherMap’s documentation. For id the 741 (fog), see Weather Condition Codes. For the icon 50d (mist/day), see the Icon List.

1436262811 is the number of seconds since January 1, 1970. Verify this with the binary calculator in the Mac Terminal window.

bc -l
scale = 5
1436262811 / (60 * 60 * 24 * 365.25)
45.51242
control-d

The toString method of a JSONObject pretty prints the content of the JSONObject and lets you specify the number of spaces to indent each level. Ditto for the toString method of class JSONArray. The fields are printed in an unpredictable order. This object contains 11 fields: three numbers (id, dt, cod), two strings, (name, base), five objects, (clouds, coord, wind, sys, main), and one array (weather). The array consists of only one element, which is an object containing four fields.

{
    "id": 5128581,
    "dt": 1436262811,
    "clouds": {
        "all": 75
    },
    "coord": {
        "lat": 40.71,
        "lon": -74.01
    },
    "wind": {
        "speed": 6.7,
        "deg": 160
    },
    "cod": 200,
    "sys": {
        "message": 0.0068,
        "id": 2120,
        "sunrise": 1436261527,
        "type": 1,
        "sunset": 1436315377,
        "country": "US"
    },
    "name": "New York",
    "base": "cmc stations",
    "weather": [
        {
            "id": 741,
            "icon": "50d",
            "description": "fog",
            "main": "Fog"
        }
    ],
    "main": {
        "temp_min": 69.8,
        "temp": 73.24,
        "humidity": 88,
        "pressure": 1017,
        "temp_max": 75.2
    }
}

Some of the indentation is missing when the output of Log.d is directed to the logcat window of Android Studio. But all of the indentation is present when the output of Log.d is directed to the standard output of adb as we saw in Text. Run the app and then type the following.

adb devices
List of devices attached
192.168.57.101:5555	device
ca1784a34445a8d0308	device
emulator-5554	device

cd
adb -s 192.168.57.101:5555 logcat -d -v raw myTag:D '*:S' > outfile
ls -l outfile
cat outfile
{
    "id": 5128581,
    "dt": 1436262811,
    "clouds": {
        "all": 75
    },
    "coord": {
        "lat": 40.71,
        "lon": -74.01
    },
    "wind": {
        "speed": 6.7,
        "deg": 160
    },
    "cod": 200,
    "sys": {
        "message": 0.0068,
        "id": 2120,
        "sunrise": 1436261527,
        "type": 1,
        "sunset": 1436315377,
        "country": "US"
    },
    "name": "New York",
    "base": "cmc stations",
    "weather": [
        {
            "id": 741,
            "icon": "50d",
            "description": "fog",
            "main": "Fog"
        }
    ],
    "main": {
        "temp_min": 69.8,
        "temp": 73.24,
        "humidity": 88,
        "pressure": 1017,
        "temp_max": 75.2
    }
}

Output into the TextView

jSONString =
{"coord":{"lon":-74.01,"lat":40.71},"weather":[{"id":741,"main":"Fog","description":"fog","icon":"50d"}],"base":"cmc stations","main":{"temp":73.24,"pressure":1017,"humidity":88,"temp_min":69.8,"temp_max":75.2},"wind":{"speed":6.7,"deg":160},"clouds":{"all":75},"dt":1436262811,"sys":{"type":1,"id":2120,"message":0.0068,"country":"US","sunrise":1436261527,"sunset":1436315377},"id":5128581,"name":"New York","cod":200}

--------------------------------------------------------------

jSONbject =
{
    "id": 5128581,
    "dt": 1436262811,
    "clouds": {
        "all": 75
    },
    "coord": {
        "lat": 40.71,
        "lon": -74.01
    },
    "wind": {
        "speed": 6.7,
        "deg": 160
    },
    "cod": 200,
    "sys": {
        "message": 0.0068,
        "id": 2120,
        "sunrise": 1436261527,
        "type": 1,
        "sunset": 1436315377,
        "country": "US"
    },
    "name": "New York",
    "base": "cmc stations",
    "weather": [
        {
            "id": 741,
            "icon": "50d",
            "description": "fog",
            "main": "Fog"
        }
    ],
    "main": {
        "temp_min": 69.8,
        "temp": 73.24,
        "humidity": 88,
        "pressure": 1017,
        "temp_max": 75.2
    }
}

--------------------------------------------------------------

dt = 1436262811
dt = Tuesday, July 7, 2015 5:53:31 AM EDT

main = {
    "temp_min": 69.8,
    "temp": 73.24,
    "humidity": 88,
    "pressure": 1017,
    "temp_max": 75.2
}

main.temp = 73.24

weather = [
    {
        "id": 741,
        "icon": "50d",
        "description": "fog",
        "main": "Fog"
    }
]

weather[0] = {
    "id": 741,
    "icon": "50d",
    "description": "fog",
    "main": "Fog"
}

weather[0].main = Fog
weather[0].description = fog

Things to try

  1. What happens when you paste the JSON string
    {"coord":{"lon":-74.01,"lat":40.71},"weather":[{"id":741,"main":"Fog","description":"fog","icon":"50d"}],"base":"cmc stations","main":{"temp":73.24,"pressure":1017,"humidity":88,"temp_min":69.8,"temp_max":75.2},"wind":{"speed":6.7,"deg":160},"clouds":{"all":75},"dt":1436262811,"sys":{"type":1,"id":2120,"message":0.0068,"country":"US","sunrise":1436261527,"sunset":1436315377},"id":5128581,"name":"New York","cod":200}
    
    into the pretty printer window at jsonformatter.curiousconcept.com?

  2. Read the jSONString from a string resource in strings.xml. Here are two ways you can paste it in:
        <string name="json">{\"coord\":{\"lon\":-74.01,\"lat\":40.71},\"weather\":[{\"id\":741,\"main\":\"Fog\",\"description\":\"fog\",\"icon\":\"50d\"}],\"base\":\"cmc stations\",\"main\":{\"temp\":73.24,\"pressure\":1017,\"humidity\":88,\"temp_min\":69.8,\"temp_max\":75.2},\"wind\":{\"speed\":6.7,\"deg\":160},\"clouds\":{\"all\":75},\"dt\":1436262811,\"sys\":{\"type\":1,\"id\":2120,\"message\":0.0068,\"country\":\"US\",\"sunrise\":1436261527,\"sunset\":1436315377},\"id\":5128581,\"name\":\"New York\",\"cod\":200}</string>
    
        <string name="json">
    {
        "id": 5128581,
        "dt": 1436262811,
        "clouds": {
            "all": 75
        },
        "coord": {
            "lat": 40.71,
            "lon": -74.01
        },
        "wind": {
            "speed": 6.7,
            "deg": 160
        },
        "cod": 200,
        "sys": {
            "message": 0.0068,
            "id": 2120,
            "sunrise": 1436261527,
            "type": 1,
            "sunset": 1436315377,
            "country": "US"
        },
        "name": "New York",
        "base": "cmc stations",
        "weather": [
            {
                "id": 741,
                "icon": "50d",
                "description": "fog",
                "main": "Fog"
            }
        ],
        "main": {
            "temp_min": 69.8,
            "temp": 73.24,
            "humidity": 88,
            "pressure": 1017,
            "temp_max": 75.2
        }
    }
        </string>
    
            String jSONString = getString(R.string.json);
    

  3. Read the jSONString from a file named response.json in the app’s app/res/raw folder. To create this folder, select the app/res folder in the Android Studio project view and pull down
    File → New → Android resource directory
    Directory name: raw
    Resource type: raw
    OK

    To create a new file named response.json, go to the Android Studio project view and select the app/res/raw folder you just created. Pull down
    File → New → File
    New File
    Enter a new file name: response.json
    OK

    Edit your new file response.json to contain either one of the following.

    {"coord":{"lon":-74.01,"lat":40.71},"weather":[{"id":741,"main":"Fog","description":"fog","icon":"50d"}],"base":"cmc stations","main":{"temp":73.24,"pressure":1017,"humidity":88,"temp_min":69.8,"temp_max":75.2},"wind":{"speed":6.7,"deg":160},"clouds":{"all":75},"dt":1436262811,"sys":{"type":1,"id":2120,"message":0.0068,"country":"US","sunrise":1436261527,"sunset":1436315377},"id":5128581,"name":"New York","cod":200}
    
    {
        "id": 5128581,
        "dt": 1436262811,
        "clouds": {
            "all": 75
        },
        "coord": {
            "lat": 40.71,
            "lon": -74.01
        },
        "wind": {
            "speed": 6.7,
            "deg": 160
        },
        "cod": 200,
        "sys": {
            "message": 0.0068,
            "id": 2120,
            "sunrise": 1436261527,
            "type": 1,
            "sunset": 1436315377,
            "country": "US"
        },
        "name": "New York",
        "base": "cmc stations",
        "weather": [
            {
                "id": 741,
                "icon": "50d",
                "description": "fog",
                "main": "Fog"
            }
        ],
        "main": {
            "temp_min": 69.8,
            "temp": 73.24,
            "humidity": 88,
            "pressure": 1017,
            "temp_max": 75.2
        }
    }
    

    In onCreate, create jSONString as follows.

            String jSONString = "";
            Resources resources = getResources();
            InputStream inputStream = null;
    
            try {
                inputStream = resources.openRawResource(R.raw.response);
                int size = inputStream.available();
                byte[] buffer = new byte[size];
                inputStream.read(buffer);
                jSONString = new String(buffer);
            } catch (Throwable throwable) {
                textView.append(throwable.toString());
                return;
            } finally {
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    }
                    catch (Throwable throwable) {
                        textView.append(throwable.toString());
                    }
                }
    	}
    

  4. Here is another JSON file. For message, list, etc., see the OpenWeatherMap documentation. The JSON object contains a field named list which is an array of five JSON objects.
    {
        "message": 0.0292,
        "list": [
            {
                "clouds": 92,
                "dt": 1436288400,
                "humidity": 96,
                "pressure": 1011.41,
                "speed": 3.69,
                "deg": 168,
                "weather": [
                    {
                        "id": 501,
                        "icon": "10d",
                        "description": "moderate rain",
                        "main": "Rain"
                    }
                ],
                "temp": {
                    "morn": 85.21,
                    "min": 79.39,
                    "night": 79.39,
                    "eve": 85.96,
                    "max": 87.98,
                    "day": 85.21
                },
                "rain": 3.18
            },
            {
                "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": 81.39,
                    "min": 73.13,
                    "night": 73.13,
                    "eve": 80.89,
                    "max": 84.97,
                    "day": 84.97
                },
                "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": 69.44,
                    "min": 63.3,
                    "night": 63.3,
                    "eve": 73.81,
                    "max": 75.83,
                    "day": 74.79
                },
                "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.86,
                    "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"
        }
    }
    
            JSONObject jSONObject = new JSONObject(jSONString);
            JSONArray list = jSONObject.getJSONArray("list");
            DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL, Locale.getDefault());
    
            for (int i = 0; i < list.length(); ++i) {
                JSONObject day = list.getJSONObject(i);
                long dt = day.getLong("dt");
                JSONObject temp = day.getJSONObject("temp");
                double max = temp.getDouble("max");
                textView.append(max + "\u00B0 F " + dateFormat.format(1000L * dt) + "\n");
            }
    

    We should have rounded the maximum temperature to the nearest degree.

    87.98° F Tuesday, July 7, 2015
    84.97° F Wednesday, July 8, 2015
    75.83° F Thursday, July 9, 2015
    78.15° F Friday, July 10, 2015
    78.33° F Saturday, July 11, 2015