JSON is very light weight, structured, easy to parse and much human readable. JSON is best alternative to XML when your android app needs to interchange data with your server. If your app consuming XML data, you can always refer to Android XML Parsing Tutorial.
In this tutorial we are going to learn how to parse JSON in android.
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.
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 asinfo.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.
<? 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.nishal.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.nishal.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.
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.
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.
<? 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 named list_item.xml with following content.
<? 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 > |
Complete Code
MainActivity.java
package info.nishal.jsonparsing;
import info.nishal.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);
}
}
}
No comments :
Post a Comment