JSON Parsing in Android over HTTP

JSON (JavaScript Object Notation) is a syntax used to store and exchange data between the application and the server. It is the best alternative to XML. JSON is easy to read and understand. In this tutorial, we will learn how to retrieve JSON data from the server using HttpURLConnection, parse the JSON and display it in a customized ListVew.

Understanding the JSON Structure

JSON comprises of JSON Objects and JSON Arrays.
JSON Structure

JSON Object:

A JSON object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma).

JSON Array:

A JSON array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).

Values:

A value can be another JSON Object, JSON array, String, Number, Boolean value or NULL.  

Creating Project and Adding Permissions

1. Create a Project named JSON Parsing in Android Studio.
2. Create the following package structure.
JSON Parsing Package Structure
3. Add INTERNET permission to AndroidManifest.xml, since we are fetching the JSON data from the server. Open AndroidManifest.xml and add the following line:
  <uses-permission android:name=”android.permission.INTERNET” />
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
	package="com.androiddeft.jsonparsing">

	<uses-permission android:name="android.permission.INTERNET" />
	<application
		android:allowBackup="true"
		android:icon="@mipmap/ic_launcher"
		android:label="@string/app_name"
		android:supportsRtl="true"
		android:theme="@style/AppTheme">
		<activity android:name=".MainActivity">
			<intent-filter>
				<action android:name="android.intent.action.MAIN" />

				<category android:name="android.intent.category.LAUNCHER" />
			</intent-filter>
		</activity>
	</application>

</manifest>

Parsing JSON using HttpJsonParser

Inside utils package, create a class named HttpJsonParser. This class helps in retrieving the JSON data from the server using HttpURLConnection.
package com.androiddeft.jsonparsing.utils;

/**
 * Created by Abhi on 19 Jun 2017 019.
 */


import android.net.Uri;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.util.Map;

public class HttpJsonParser {

    private static InputStream is = null;
    private static JSONObject jObj = null;
    private static String json = "";
    private HttpURLConnection urlConnection = null;

    /**
     * This method helps in retrieving data from HTTP server using HttpURLConnection.
     *
     * @param url    The HTTP URL where JSON data is exposed
     * @param method HTTP method: GET or POST
     * @param params Query parameters for the request
     * @return This method returns the JSON object fetched from the server
     */
    public JSONObject makeHttpRequest(String url, String method,
                                      Map<String, String> params) {

        try {
            Uri.Builder builder = new Uri.Builder();
            URL urlObj;
            String encodedParams = "";
            if (params != null) {
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    builder.appendQueryParameter(entry.getKey(), entry.getValue());
                }
            }
            if (builder.build().getEncodedQuery() != null) {
                encodedParams = builder.build().getEncodedQuery();

            }
            if ("GET".equals(method)) {
                url = url + "?" + encodedParams;
                urlObj = new URL(url);
                urlConnection = (HttpURLConnection) urlObj.openConnection();
                urlConnection.setRequestMethod(method);


            } else {
                urlObj = new URL(url);
                urlConnection = (HttpURLConnection) urlObj.openConnection();
                urlConnection.setRequestMethod(method);
                urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                urlConnection.setRequestProperty("Content-Length", String.valueOf(encodedParams.getBytes().length));
                urlConnection.getOutputStream().write(encodedParams.getBytes());
            }
            //Connect to the server
            urlConnection.connect();
            //Read the response
            is = urlConnection.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            StringBuilder sb = new StringBuilder();
            String line;

            //Parse the response
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            json = sb.toString();
            //Convert the response to JSON Object
            jObj = new JSONObject(json);


        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        } catch (Exception e) {
            Log.e("Exception", "Error parsing data " + e.toString());
        }

        // return JSON Object
        return jObj;

    }
}

Creating EmployeeDetails Class

We will be handling employee data in this tutorial. So let’s create a Java bean called EmployeeDetails inside beans package.

package com.androiddeft.jsonparsing.beans;

/**
 * Created by Abhi on 03 Sep 2017 003.
 */

public class EmployeeDetails {
    private Integer employeeId;
    private String name;
    private String dob;
    private String designation;
    private String contactNumber;
    private String email;
    private String salary;

    public Integer getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(Integer employeeId) {
        this.employeeId = employeeId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDob() {
        return dob;
    }

    public void setDob(String dob) {
        this.dob = dob;
    }

    public String getDesignation() {
        return designation;
    }

    public void setDesignation(String designation) {
        this.designation = designation;
    }


    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getSalary() {
        return salary;
    }

    public void setSalary(String salary) {
        this.salary = salary;
    }

    public String getContactNumber() {
        return contactNumber;
    }

    public void setContactNumber(String contactNumber) {
        this.contactNumber = contactNumber;
    }
}

The UI for Displaying the Data

We will have customized List View for displaying the data.

Open activity_main.xml and add a List View.

<?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:id="@+id/activity_main"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:paddingBottom="8dp"
	android:paddingLeft="8dp"
	android:paddingRight="8dp"
	android:paddingTop="8dp"
	tools:context="com.androiddeft.jsonparsing.MainActivity">

	<ListView
		android:layout_marginTop="8dp"
		android:layout_marginLeft="8dp"
		android:layout_marginRight="8dp"
		android:id="@+id/employeeList"
		android:layout_width="fill_parent"
		android:layout_height="match_parent"
		android:divider="@android:color/transparent"
		android:dividerHeight="5dp"
		android:scrollbars="vertical"
		 />
</RelativeLayout>

Now create a file employee_row.xml in layout folder, which contains Text Views to display employee data.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:background="@drawable/employee_background"
	android:orientation="vertical">

	<TextView
		android:id="@+id/employeeId"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:fontFamily="serif"
		android:padding="10dp"
		android:textColor="@android:color/holo_blue_light"
		android:textSize="18sp" />

	<TextView
		android:id="@+id/name"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:fontFamily="serif"
		android:padding="10dp"
		android:textColor="@android:color/holo_purple"
		android:textSize="18sp" />

	<TextView
		android:id="@+id/dob"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:fontFamily="serif"
		android:padding="10dp"
		android:textColor="@android:color/holo_purple"
		android:textSize="18sp" />

	<TextView
		android:id="@+id/designation"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:fontFamily="serif"
		android:padding="10dp"
		android:textColor="@android:color/holo_purple"
		android:textSize="18sp" />

	<TextView
		android:id="@+id/contact_number"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:fontFamily="serif"
		android:padding="10dp"
		android:textColor="@android:color/holo_purple"
		android:textSize="18sp" />

	<TextView
		android:id="@+id/email"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:fontFamily="serif"
		android:padding="10dp"
		android:textColor="@android:color/holo_purple"
		android:textSize="18sp" />

	<TextView
		android:id="@+id/salary"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:fontFamily="serif"
		android:padding="10dp"
		android:textColor="@android:color/holo_purple"
		android:textSize="18sp" />

</LinearLayout>

Create a file employee_background.xml inside the drawable folder. This will provide background for each element in the list view.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
	android:shape="rectangle" >

	<!-- View background color -->
	<solid
		android:color="#fff" >
	</solid>

	<!-- View border color and width -->
	<stroke
		android:width="1dp"
		android:color="#aaa" >
	</stroke>

	<!-- The radius makes the corners rounded -->
	<corners
		android:radius="2dp"   >
	</corners>

</shape>

Creating a ListView using Custom Adapter

In order to display the fetched JSON data from the server, we will be customizing the ArrayAdapter. Create a class EmployeeAdapter in adapter package.

package com.androiddeft.jsonparsing.adapter;

import android.content.Context;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import com.androiddeft.jsonparsing.R;
import com.androiddeft.jsonparsing.beans.EmployeeDetails;

import java.util.List;


/**
 * Created by Abhi on 03 Sep 2017 008.
 */

public class EmployeeAdapter extends ArrayAdapter<EmployeeDetails> {
    private static final String KEY_EMPLOYEE_ID = "Employee Id: ";
    private static final String KEY_NAME = "Name: ";
    private static final String KEY_DOB = "Date of Birth: ";
    private static final String KEY_DESIGNATION = "Designation: ";
    private static final String KEY_CONTACT_NUMBER = "Contact Number: ";
    private static final String KEY_EMAIL = "Email: ";
    private static final String KEY_SALARY = "Salary: ";
    private List<EmployeeDetails> dataSet;

    public EmployeeAdapter(List<EmployeeDetails> dataSet, Context mContext) {
        super(mContext, R.layout.employee_row, dataSet);
        this.dataSet = dataSet;
    }


    @NonNull
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        if (v == null) {
            LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(R.layout.employee_row, null);
        }
        EmployeeDetails employee = dataSet.get(position);
        if (employee != null) {
            //Text View references
            TextView employeeId = (TextView) v.findViewById(R.id.employeeId);
            TextView name = (TextView) v.findViewById(R.id.name);
            TextView dob = (TextView) v.findViewById(R.id.dob);
            TextView designation = (TextView) v.findViewById(R.id.designation);
            TextView contactNumber = (TextView) v.findViewById(R.id.contact_number);
            TextView email = (TextView) v.findViewById(R.id.email);
            TextView salary = (TextView) v.findViewById(R.id.salary);
            
            //Updating the text views
            employeeId.setText(KEY_EMPLOYEE_ID + employee.getEmployeeId());
            name.setText(KEY_NAME + employee.getName());
            dob.setText(KEY_DOB + employee.getDob());
            designation.setText(KEY_DESIGNATION + employee.getDesignation());
            contactNumber.setText(KEY_CONTACT_NUMBER + employee.getContactNumber());
            email.setText(KEY_EMAIL + employee.getEmail());
            salary.setText(KEY_SALARY + employee.getSalary().toString());
        }

        return v;
    }
}

Fetching Individual JSON Nodes

We use the following methods to fetch the JSON nodes:

getJSONArray(String name) : fetches JSON array from JSON object.

getJSONObject(int index) : fetches JSON object from a JSON array.

getString(String name) : fetches String value from JSON object.

getInt(String name) : fetches Integer value from JSON object.

Calling makeHttpRequest from AsyncTask

Any network related operations in Android needs to be performed as an asynchronous task, without disturbing the UI thread. If we perform the network operation on the main thread (UI thread) then we will get NetworkOnMainThreadException. We will be using following methods in AsyncTask:

onPreExecute() : Prerequisite  operations such as displaying progress bar.

doInBackground(String… params) : Performing the network operation (calling makeHttpRequest in this tutorial).

onPostExecute(String result): Parse the response and populate the UI. We will be calling runOnUiThread(Runnable) for the same.

Complete MainActivity class

Below is the complete implementation of MainActivity.

package com.androiddeft.jsonparsing;

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ListView;
import android.widget.Toast;

import com.androiddeft.jsonparsing.adapter.EmployeeAdapter;
import com.androiddeft.jsonparsing.beans.EmployeeDetails;
import com.androiddeft.jsonparsing.utils.HttpJsonParser;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private static final String KEY_SUCCESS = "success";
    private static final String KEY_DATA = "data";
    private static final String KEY_EMPLOYEE_ID = "employee_id";
    private static final String KEY_NAME = "name";
    private static final String KEY_DOB = "dob";
    private static final String KEY_DESIGNATION = "designation";
    private static final String KEY_CONTACT_NUMBER = "contact_number";
    private static final String KEY_EMAIL = "email";
    private static final String KEY_SALARY = "salary";
    private String url = "http://api.androiddeft.com/json/employee.php";
    private ProgressDialog pDialog;
    private int success;
    private EmployeeAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //Call the AsyncTask
        new FetchEmployeeDetails().execute();

    }

    private class FetchEmployeeDetails extends AsyncTask<String, String, String> {
        JSONObject response;
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            //Display progress bar
            pDialog = new ProgressDialog(MainActivity.this);
            pDialog.setMessage("Loading Data.. Please wait...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(false);
            pDialog.show();
        }

        @Override
        protected String doInBackground(String... params) {
            HttpJsonParser jsonParser = new HttpJsonParser();
            response = jsonParser.makeHttpRequest(url,"GET",null);
            try {
                success = response.getInt(KEY_SUCCESS);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return null;
        }

        protected void onPostExecute(String result) {
            pDialog.dismiss();
            runOnUiThread(new Runnable() {
                public void run() {

                    ListView listView =(ListView)findViewById(R.id.employeeList);
                    if (success == 1) {
                        try {
                            JSONArray employeeArray =  response.getJSONArray(KEY_DATA);
                            List<EmployeeDetails> employeeList = new ArrayList<>();
                            //Populate the EmployeeDetails list from response
                            for (int i = 0; i<employeeArray.length();i++){
                                EmployeeDetails employeeDetails = new EmployeeDetails();
                                JSONObject employeeObj = employeeArray.getJSONObject(i);
                                employeeDetails.setEmployeeId(employeeObj.getInt(KEY_EMPLOYEE_ID));
                                employeeDetails.setName(employeeObj.getString(KEY_NAME));
                                employeeDetails.setDob(employeeObj.getString(KEY_DOB));
                                employeeDetails.setDesignation(employeeObj.getString(KEY_DESIGNATION));
                                employeeDetails.setContactNumber(employeeObj.getString(KEY_CONTACT_NUMBER));
                                employeeDetails.setEmail(employeeObj.getString(KEY_EMAIL));
                                employeeDetails.setSalary(employeeObj.getString(KEY_SALARY));
                                employeeList.add(employeeDetails);
                            }
                            //Create an adapter with the EmployeeDetails List and set it to the LstView
                            adapter = new EmployeeAdapter(employeeList,getApplicationContext());
                            listView.setAdapter(adapter);

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                    } else {
                        Toast.makeText(MainActivity.this,
                                "Some error occurred while loading data",
                                Toast.LENGTH_LONG).show();

                    }
                }
            });
        }
    }

}

You can download the source code and APK from the below links. You can also watch the demonstration in the below animation. If you have any doubts you can ask them in the comments section.

Download Source CodeDownload APK

JSON Parsing in Android over HTTP

Stay Connected

No spam guarantee.

Abhishek

Abhishek

Abhishek loves coding. His favorite is Android Development. Apart from coding he loves traveling and reading.
Abhishek

Latest posts by Abhishek (see all)

Leave a Reply

Your email address will not be published. Required fields are marked *