JSON Parsing Tutorial

Hello developers,

Now in want to give you tutorial using volley in Android.
I get this tutorial from AndroidHive
And thanks a lot to AndroidHive

Okay let we started,

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.
You can get this JSON data by accessing http://api.androidhive.info/contacts/
{
    "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.
json parsing structor

Creating New Android Project

So let's start by creating a new android project
1. Create a new project in Eclipse from File ⇒ New ⇒ Android Application Project. I had left my main activity name as MainActivity.java and gave the package name as info.androidhive.jsonparsing
2. As we are fetching the JSON by making HTTP calls, we need to add INTERNET permission in our AndroidManifest.xml file. Open AndroidManifest.xml and add the following permission.
<uses-permission android:name="android.permission.INTERNET" />
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.androidhive.jsonparsing"
    android:versionCode="1"
    android:versionName="1.0" >
 
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />
     
    <!-- Internet permission -->
    <uses-permission android:name="android.permission.INTERNET" />
 
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name="info.androidhive.jsonparsing.MainActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
         
        <!-- Single List Item Activity -->
        <activity
            android:label="Contact"
            android:name="info.androidhive.jsonparsing.SingleContactActivity" >
        </activity>
    </application>
 
</manifest>

The class to handle HTTP calls

I am creating a separate class to handle all HTTP calls. This class is responsible of making a HTTP call and getting the response.
3. So create a new class named ServiceHandler.java and add the following code. In this classmakeServiceCall(String url, int method, List params) method should be called in order to make a HTTP call. And the method parameters are
url - The url to make a http call
method - The http method either GET or POST. We should pass ServiceHandler.GET orServiceHandler.POST as value
params - Any parameters you want to submit to that url. This is optional.
ServiceHandler.java
package info.androidhive.jsonparsing; 
  
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
  
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
  
public class ServiceHandler { 
  
    static String response = null;
    public final static int GET = 1;
    public final static int POST = 2;
  
    public ServiceHandler() { 
  
    } 
  
    /** 
     * Making service call 
     * @url - url to make request 
     * @method - http request method 
     * */ 
    public String makeServiceCall(String url, int method) {
        return this.makeServiceCall(url, method, null);
    } 
  
    /** 
     * Making service call 
     * @url - url to make request 
     * @method - http request method 
     * @params - http request params 
     * */ 
    public String makeServiceCall(String url, int method,
            List<NameValuePair> params) { 
        try { 
            // http client 
            DefaultHttpClient httpClient = new DefaultHttpClient(); 
            HttpEntity httpEntity = null; 
            HttpResponse httpResponse = null; 
              
            // Checking http request method type 
            if (method == POST) { 
                HttpPost httpPost = new HttpPost(url); 
                // adding post params 
                if (params != null) { 
                    httpPost.setEntity(new UrlEncodedFormEntity(params)); 
                } 
  
                httpResponse = httpClient.execute(httpPost); 
  
            } else if (method == GET) { 
                // appending params to url 
                if (params != null) { 
                    String paramString = URLEncodedUtils 
                            .format(params, "utf-8"); 
                    url += "?" + paramString; 
                } 
                HttpGet httpGet = new HttpGet(url); 
  
                httpResponse = httpClient.execute(httpGet); 
  
            } 
            httpEntity = httpResponse.getEntity(); 
            response = EntityUtils.toString(httpEntity); 
  
        } catch (UnsupportedEncodingException e) { 
            e.printStackTrace(); 
        } catch (ClientProtocolException e) { 
            e.printStackTrace(); 
        } catch (IOException e) { 
            e.printStackTrace(); 
        } 
          
        return response; 
  
    } 
} 
4. I am adding a list view to show the parsed JSON data. Open the layout file of your main activity and add a list view element.
activity_main.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="fill_parent"
    android:orientation="vertical">
    <!-- Main ListView 
         Always give id value as list(@android:id/list)
    -->
    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
 
</LinearLayout>
5. We need another layout file which renders a single row in listview. Create another layout file namedlist_item.xml with following content.
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="10dp"
    android:paddingLeft="10dp"
    android:paddingRight="10dp" >
 
    <!-- Name Label -->
 
    <TextView
        android:id="@+id/name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="2dip"
        android:paddingTop="6dip"
        android:textColor="#43bd00"
        android:textSize="16sp"
        android:textStyle="bold" />
 
    <!-- Email label -->
    <TextView
        android:id="@+id/email"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="2dip"
        android:textColor="#acacac" />
 
    <!-- Mobile number label -->
    <TextView
        android:id="@+id/mobile"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="left"
        android:text="Mobile: "
        android:textColor="#5d5d5d"
        android:textStyle="bold" />
 
</LinearLayout>
6. In my main activity class (MainActivity.java) I have declared all the JSON node names and created an instance for the list view. If you haven't worked with list view yet, Android ListView Tutorial will helps you in getting started with list view.
MainActivity.java
public class MainActivity extends ListActivity {
  
    private ProgressDialog pDialog;
  
    // URL to get contacts JSON 
    private static String url = "http://api.androidhive.info/contacts/";
  
    // JSON Node names 
    private static final String TAG_CONTACTS = "contacts";
    private static final String TAG_ID = "id";
    private static final String TAG_NAME = "name";
    private static final String TAG_EMAIL = "email";
    private static final String TAG_ADDRESS = "address";
    private static final String TAG_GENDER = "gender";
    private static final String TAG_PHONE = "phone";
    private static final String TAG_PHONE_MOBILE = "mobile";
    private static final String TAG_PHONE_HOME = "home";
    private static final String TAG_PHONE_OFFICE = "office";
  
    // contacts JSONArray 
    JSONArray contacts = null;
  
    // Hashmap for ListView 
    ArrayList<HashMap<String, String>> contactList;
  
    @Override 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
  
        contactList = new ArrayList<HashMap<String, String>>();
  
        ListView lv = getListView();
    } 
} 

Parsing JSON Data

7. As we are getting the JSON by making HTTP call, I am adding a Async method to make http calls on background thread. Add the follwing method in your main activity class.
In onPreExecute() method I showed a progress dialog before making actual http call.
In doInBackground() method, I called makeServiceCall() method to get the json from url, parsed the JSON and added to HashMap to show the results in List View.
In onPostExecute() method I created a list adapter and assigned it to list view and dismissed the progress dialog.
Also note that I have used getJSONArray() or getJSONObject() method depending on the type of node.
MainActivity.java
public class MainActivity extends ListActivity {
    . 
    . 
    . 
    @Override 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        . 
        . 
        . 
  
        // Calling async task to get json 
        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) {
            // Creating service handler class instance 
            ServiceHandler sh = new ServiceHandler();
  
            // Making a request to url and getting response 
            String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
  
            Log.d("Response: ", "> " + jsonStr);
  
            if (jsonStr != null) { 
                try { 
                    JSONObject jsonObj = new JSONObject(jsonStr); 
                      
                    // Getting JSON Array node 
                    contacts = jsonObj.getJSONArray(TAG_CONTACTS); 
  
                    // looping through All Contacts 
                    for (int i = 0; i < contacts.length(); i++) { 
                        JSONObject c = contacts.getJSONObject(i); 
                          
                        String id = c.getString(TAG_ID); 
                        String name = c.getString(TAG_NAME); 
                        String email = c.getString(TAG_EMAIL); 
                        String address = c.getString(TAG_ADDRESS); 
                        String gender = c.getString(TAG_GENDER); 
  
                        // Phone node is JSON Object 
                        JSONObject phone = c.getJSONObject(TAG_PHONE); 
                        String mobile = phone.getString(TAG_PHONE_MOBILE); 
                        String home = phone.getString(TAG_PHONE_HOME); 
                        String office = phone.getString(TAG_PHONE_OFFICE); 
  
                        // tmp hashmap for single contact 
                        HashMap<String, String> contact = new HashMap<String, String>(); 
  
                        // adding each child node to HashMap key => value 
                        contact.put(TAG_ID, id); 
                        contact.put(TAG_NAME, name); 
                        contact.put(TAG_EMAIL, email); 
                        contact.put(TAG_PHONE_MOBILE, mobile); 
  
                        // adding contact to contact list 
                        contactList.add(contact); 
                    } 
                } catch (JSONException e) { 
                    e.printStackTrace(); 
                } 
            } else { 
                Log.e("ServiceHandler", "Couldn't get any data from the url"); 
            } 
  
            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[] { TAG_NAME, TAG_EMAIL, 
                            TAG_PHONE_MOBILE }, new int[] { R.id.name, 
                            R.id.email, R.id.mobile }); 
  
            setListAdapter(adapter); 
        } 
  
    } 
  
} 
If you run the project, you can see json data populated into list view. The code for list item click event and launching a new activity can be found in the downloaded code of the this article and not explained here as it is not the main concern of this article.
android json parsing list view

Complete Code

MainActivity.java
package info.androidhive.jsonparsing; 
  
import info.androidhive.jsonparsing.R; 
import java.util.ArrayList;
import java.util.HashMap;
  
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
  
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
  
public class MainActivity extends ListActivity {
  
    private ProgressDialog pDialog;
  
    // URL to get contacts JSON 
    private static String url = "http://api.androidhive.info/contacts/";
  
    // JSON Node names 
    private static final String TAG_CONTACTS = "contacts";
    private static final String TAG_ID = "id";
    private static final String TAG_NAME = "name";
    private static final String TAG_EMAIL = "email";
    private static final String TAG_ADDRESS = "address";
    private static final String TAG_GENDER = "gender";
    private static final String TAG_PHONE = "phone";
    private static final String TAG_PHONE_MOBILE = "mobile";
    private static final String TAG_PHONE_HOME = "home";
    private static final String TAG_PHONE_OFFICE = "office";
  
    // contacts JSONArray 
    JSONArray contacts = null;
  
    // Hashmap for ListView 
    ArrayList<HashMap<String, String>> contactList;
  
    @Override 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
  
        contactList = new ArrayList<HashMap<String, String>>();
  
        ListView lv = getListView();
  
        // Listview on item click listener 
        lv.setOnItemClickListener(new OnItemClickListener() { 
  
            @Override 
            public void onItemClick(AdapterView<?> parent, View view, 
                    int position, long id) { 
                // getting values from selected ListItem 
                String name = ((TextView) view.findViewById(R.id.name)) 
                        .getText().toString(); 
                String cost = ((TextView) view.findViewById(R.id.email)) 
                        .getText().toString(); 
                String description = ((TextView) view.findViewById(R.id.mobile)) 
                        .getText().toString(); 
  
                // Starting single contact activity 
                Intent in = new Intent(getApplicationContext(), 
                        SingleContactActivity.class); 
                in.putExtra(TAG_NAME, name); 
                in.putExtra(TAG_EMAIL, cost); 
                in.putExtra(TAG_PHONE_MOBILE, description); 
                startActivity(in); 
  
            } 
        }); 
  
        // Calling async task to get json 
        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) { 
            // Creating service handler class instance 
            ServiceHandler sh = new ServiceHandler(); 
  
            // Making a request to url and getting response 
            String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET); 
  
            Log.d("Response: ", "> " + jsonStr); 
  
            if (jsonStr != null) { 
                try { 
                    JSONObject jsonObj = new JSONObject(jsonStr); 
                      
                    // Getting JSON Array node 
                    contacts = jsonObj.getJSONArray(TAG_CONTACTS); 
  
                    // looping through All Contacts 
                    for (int i = 0; i < contacts.length(); i++) { 
                        JSONObject c = contacts.getJSONObject(i); 
                          
                        String id = c.getString(TAG_ID); 
                        String name = c.getString(TAG_NAME); 
                        String email = c.getString(TAG_EMAIL); 
                        String address = c.getString(TAG_ADDRESS); 
                        String gender = c.getString(TAG_GENDER); 
  
                        // Phone node is JSON Object 
                        JSONObject phone = c.getJSONObject(TAG_PHONE); 
                        String mobile = phone.getString(TAG_PHONE_MOBILE); 
                        String home = phone.getString(TAG_PHONE_HOME); 
                        String office = phone.getString(TAG_PHONE_OFFICE); 
  
                        // tmp hashmap for single contact 
                        HashMap<String, String> contact = new HashMap<String, String>(); 
  
                        // adding each child node to HashMap key => value 
                        contact.put(TAG_ID, id); 
                        contact.put(TAG_NAME, name); 
                        contact.put(TAG_EMAIL, email); 
                        contact.put(TAG_PHONE_MOBILE, mobile); 
  
                        // adding contact to contact list 
                        contactList.add(contact); 
                    } 
                } catch (JSONException e) { 
                    e.printStackTrace(); 
                } 
            } else { 
                Log.e("ServiceHandler", "Couldn't get any data from the url"); 
            } 
  
            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[] { TAG_NAME, TAG_EMAIL, 
                            TAG_PHONE_MOBILE }, new int[] { R.id.name, 
                            R.id.email, R.id.mobile }); 
  
            setListAdapter(adapter); 
        } 
  
    } 
  
}