The Sample JSON
Following is the sample JSON that we are going to parse in this
tutorial. This is very simple JSON which gives us list of contacts where each
node contains contact information like name, email, address, gender and phone
numbers.
{
"contacts":
[
{
"id":
"c200",
"name":
"Ravi Tamada",
"email":
"ravi@gmail.com",
"address":
"xx-xx-xxxx,x - street, x - country",
"gender" : "male",
"phone":
{
"mobile":
"+91 0000000000",
"home":
"00 000000",
"office":
"00 000000"
}
},
{
"id":
"c201",
"name":
"Johnny Depp",
"email":
"johnny_depp@gmail.com",
"address":
"xx-xx-xxxx,x - street, x - country",
"gender" : "male",
"phone":
{
"mobile":
"+91 0000000000",
"home":
"00 000000",
"office":
"00 000000"
}
},
.
.
.
.
]
}
The difference between [ and { – (Square brackets and Curly
brackets)
In general all the JSON nodes will start with a square
bracket or with a curly bracket. The difference between [ and { is, the square
bracket ([) represents starting of an JSONArray node whereas curly bracket ({)
represents JSONObject. So while accessing these nodes we need to call
appropriate method to access the data.
If your JSON node starts with [, then we should use
getJSONArray() method. Same as if the node starts with {, then we should use
getJSONObject() method.
1. Creating New Project
So let’s start by creating a new android project. We’ll
build a simple app which fetches the json from url, parses it and displays the
contacts in a list view. Here we’ll use import java.net libraries (which are
natively supported in android) to make the http call and fetch the json from
url.
1. Create a new project in Android Studio from File ⇒ New Project and fill out the required details.
2. As we are fetching the JSON by making HTTP calls, we need
to add INTERNET permission in AndroidManifest.xml file. Open
AndroidManifest.xml and add the following permission.
<uses-permission android:name="android.permission.INTERNET"
/>
3. Create a class named HttpHandler.java and use the below
code. Here makeServiceCall() makes http call to particular url and fetches the
response. In our case, we use this to get the raw json from the url.
HttpHandler.java
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
/**
* Created by Ravi Tamada on 01/09/16.
* www.androidhive.info
*/
public class HttpHandler {
private static final String TAG = HttpHandler.class.getSimpleName();
public HttpHandler() {
}
public String makeServiceCall(String reqUrl) {
String response = null;
try {
URL url = new URL(reqUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
// read the response
InputStream in = new BufferedInputStream(conn.getInputStream());
response = convertStreamToString(in);
} catch (MalformedURLException e) {
Log.e(TAG, "MalformedURLException: " + e.getMessage());
} catch (ProtocolException e) {
Log.e(TAG, "ProtocolException: " + e.getMessage());
} catch (IOException e) {
Log.e(TAG, "IOException: " + e.getMessage());
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
return response;
}
private String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line).append('\n');
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
4. Before making the http call, let’s add a list view first
in our view. Open the layout file of main activity (activity_main.xml) and add
a ListView element.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <ListView android:id="@+id/list" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </RelativeLayout>
5. Create another layout file named list_item.xml with
following content. This will be used to render single list item view.
list_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="@dimen/activity_horizontal_margin"> <TextView android:id="@+id/name" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingBottom="2dip" android:paddingTop="6dip" android:textColor="@color/colorPrimaryDark" android:textSize="16sp" android:textStyle="bold" /> <TextView android:id="@+id/email" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingBottom="2dip" android:textColor="@color/colorAccent" /> <TextView android:id="@+id/mobile" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#5d5d5d" android:textStyle="bold" /> </LinearLayout>
1.1 Downloading & Parsing the JSON
7. As we are getting the JSON by making HTTP call, I am
adding a Async class GetContacts to make http calls on background thread. Add
the following method in your main activity class.
In onPreExecute() method progress dialog is shown before
making the http call.
In doInBackground() method, makeServiceCall() is called to
get the json from url. Once the json is fetched, it is parsed and each contact
is added to array list.
In onPostExecute() method the progress dialog is dismissed
and the array list data is displayed in list view using an adapter.
Also note that I have used getJSONArray() or getJSONObject()
method depending on the type of node.
MainActivity.java
import android.app.ProgressDialog; import android.os.AsyncTask; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.Toast; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; import java.util.HashMap; public class MainActivity extends AppCompatActivity { private String TAG = MainActivity.class.getSimpleName(); private ProgressDialog pDialog; private ListView lv; // URL to get contacts JSON private static String url = "http://api.androidhive.info/contacts/"; ArrayList<HashMap<String, String>> contactList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); contactList = new ArrayList<>(); lv = (ListView) findViewById(R.id.list); new GetContacts().execute(); } /** * Async task class to get json by making HTTP call */ private class GetContacts extends AsyncTask<Void, Void, Void> { @Override protected void onPreExecute() { super.onPreExecute(); // Showing progress dialog pDialog = new ProgressDialog(MainActivity.this); pDialog.setMessage("Please wait..."); pDialog.setCancelable(false); pDialog.show(); } @Override protected Void doInBackground(Void... arg0) { HttpHandler sh = new HttpHandler(); // Making a request to url and getting response String jsonStr = sh.makeServiceCall(url); Log.e(TAG, "Response from url: " + jsonStr); if (jsonStr != null) { try { JSONObject jsonObj = new JSONObject(jsonStr); // Getting JSON Array node JSONArray contacts = jsonObj.getJSONArray("contacts"); // looping through All Contacts for (int i = 0; i < contacts.length(); i++) { JSONObject c = contacts.getJSONObject(i); String id = c.getString("id"); String name = c.getString("name"); String email = c.getString("email"); String address = c.getString("address"); String gender = c.getString("gender"); // Phone node is JSON Object JSONObject phone = c.getJSONObject("phone"); String mobile = phone.getString("mobile"); String home = phone.getString("home"); String office = phone.getString("office"); // tmp hash map for single contact HashMap<String, String> contact = new HashMap<>(); // adding each child node to HashMap key => value contact.put("id", id); contact.put("name", name); contact.put("email", email); contact.put("mobile", mobile); // adding contact to contact list contactList.add(contact); } } catch (final JSONException e) { Log.e(TAG, "Json parsing error: " + e.getMessage()); runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), "Json parsing error: " + e.getMessage(), Toast.LENGTH_LONG) .show(); } }); } } else { Log.e(TAG, "Couldn't get json from server."); runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), "Couldn't get json from server. Check LogCat for possible errors!", Toast.LENGTH_LONG) .show(); } }); } return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); // Dismiss the progress dialog if (pDialog.isShowing()) pDialog.dismiss(); /** * Updating parsed JSON data into ListView * */ ListAdapter adapter = new SimpleAdapter( MainActivity.this, contactList, R.layout.list_item, new String[]{"name", "email", "mobile"}, new int[]{R.id.name, R.id.email, R.id.mobile}); lv.setAdapter(adapter); } } }