Thursday, February 14, 2013

Android JSON Parsing example


JSON is built on two structures:
  • A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
  • An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
These are universal data structures. Virtually all modern programming languages support them in one form or another. It makes sense that a data format that is interchangeable with programming languages also be based on these structures.
In JSON, they take on these forms:
An object is an unordered set of name/value pairs. An 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).

An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).

A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.

A string is a sequence of zero or more Unicode characters, wrapped in double quotes, using backslash escapes. A character is represented as a single character string. A string is very much like a C or Java string.

A number is very much like a C or Java number, except that the octal and hexadecimal formats are not used.




Create a project with name AndroidJSONparser and have a mainactivity as given and with the given code

MainActivity .java


package com.jitesh.androidjsonparser;

import java.util.ArrayList;
import java.util.HashMap;

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



import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class MainActivity extends ListActivity {
private Context context;
private static String url = "http://docs.blackberry.com/sampledata.json";

private static final String TAG_VTYPE = "vehicleType";
private static final String TAG_VCOLOR = "vehicleColor";
private static final String TAG_FUEL = "fuel";
private static final String TAG_TREAD = "treadType";
private static final String TAG_OPERATOR = "approvedOperators";
private static final String TAG_NAME = "name";
private static final String TAG_POINTS = "experiencePoints";

ArrayList<HashMap<String, String>> jsonlist = new ArrayList<HashMap<String, String>>();

ListView lv ;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new ProgressTask(MainActivity.this).execute();
}

private class ProgressTask extends AsyncTask<String, Void, Boolean> {
private ProgressDialog dialog;

public ProgressTask(ListActivity activity) {

Log.i("1", "Called");
context = activity;
dialog = new ProgressDialog(context);
}

/** progress dialog to show user that the backup is processing. */

/** application context. */
private Context context;

protected void onPreExecute() {
this.dialog.setMessage("Progress start");
this.dialog.show();
}

@Override
protected void onPostExecute(final Boolean success) {
if (dialog.isShowing()) {
dialog.dismiss();
}
ListAdapter adapter = new SimpleAdapter(context, jsonlist,
R.layout.list_item, new String[] { TAG_VTYPE, TAG_VCOLOR,
TAG_FUEL, TAG_TREAD }, new int[] {
R.id.vehicleType, R.id.vehicleColor, R.id.fuel,
R.id.treadType });

setListAdapter(adapter);

// selecting single ListView item
lv = getListView();






}

protected Boolean doInBackground(final String... args) {

JSONParser jParser = new JSONParser();

// getting JSON string from URL
JSONArray json = jParser.getJSONFromUrl(url);

for (int i = 0; i < json.length(); i++) {

try {
JSONObject c = json.getJSONObject(i);
String vtype = c.getString(TAG_VTYPE);

String vcolor = c.getString(TAG_VCOLOR);
String vfuel = c.getString(TAG_FUEL);
String vtread = c.getString(TAG_TREAD);

HashMap<String, String> map = new HashMap<String, String>();

// adding each child node to HashMap key => value
map.put(TAG_VTYPE, vtype);
map.put(TAG_VCOLOR, vcolor);
map.put(TAG_FUEL, vfuel);
map.put(TAG_TREAD, vtread);
jsonlist.add(map);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

return null;

}

}

}


JSONParser.java code is given below

package com.jitesh.androidjsonparser;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class JSONParser {

static InputStream is = null;
static JSONArray jarray = null;
static String json = "";

// constructor
public JSONParser() {

}

public JSONArray getJSONFromUrl(String url) {

  StringBuilder builder = new StringBuilder();
   HttpClient client = new DefaultHttpClient();
   HttpGet httpGet = new HttpGet(url);
   try {
     HttpResponse response = client.execute(httpGet);
     StatusLine statusLine = response.getStatusLine();
     int statusCode = statusLine.getStatusCode();
     if (statusCode == 200) {
       HttpEntity entity = response.getEntity();
       InputStream content = entity.getContent();
       BufferedReader reader = new BufferedReader(new InputStreamReader(content));
       String line;
       while ((line = reader.readLine()) != null) {
         builder.append(line);
       }
     } else {
       Log.e("==>", "Failed to download file");
     }
   } catch (ClientProtocolException e) {
     e.printStackTrace();
   } catch (IOException e) {
     e.printStackTrace();
   }
 
// try parse the string to a JSON object
try {
jarray = new JSONArray( builder.toString());
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}

// return JSON String
return jarray;

}
}


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>

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="horizontal">  
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
<!-- Name Label -->
        <TextView
            android:id="@+id/vehicleType"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textColor="#43bd00"
            android:textSize="16sp"
            android:textStyle="bold"
            android:paddingTop="6dip"
            android:paddingBottom="2dip" />
<!-- Description label -->
        <TextView
            android:id="@+id/vehicleColor"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textColor="#acacac"
            android:paddingBottom="2dip">
        </TextView>
        
        <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <!-- Cost Label -->
        <TextView
              android:id="@+id/fuel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#5d5d5d"
            android:gravity="left"
            android:textStyle="bold"
            android:text="Mobile: " >
        </TextView>
        <!-- Price Label -->
        <TextView
            android:id="@+id/treadType"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#acacac" 
            android:textStyle="bold"
            android:gravity="left">
        </TextView>
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

do not forget to add the internet permissions.

 <uses-permission android:name="android.permission.INTERNET"/>

the output can be shown as follows


you can download the code from the given link JSONPARSER




29 comments:

  1. Thank you for the sensible critique. Me and my friend were just preparing to do some research about this. We got a book from our local library but I think I learned more from this post. I am very glad to see such great information being shared freely out there...
    Read More

    ReplyDelete
  2. I ma glad to know that this post is useful to you. please ask things regarding the JSON parsing without any hesitation and feel free. good day ahead :)

    ReplyDelete
    Replies
    1. how to retrieve data from webservice with using list view.. i want put retrieve data in edittext can u help me...

      Delete
  3. This comment has been removed by the author.

    ReplyDelete
  4. After new ProgressTask(MainActivity.this).execute();
    which will be called
    private class ProgressTask extends AsyncTask
    or public ProgressTask(ListActivity activity).

    if ProgressTask(Activity is called then when will be the ASYncTask will be called?

    ReplyDelete
  5. Hi Friend please follow the simple java rules and have a look .
    As we uses java, generally passes parameters in constructor and initialize them in constructor.

    But it is not compulsory, you can pass it in execute() also.

    But as i thinks better to pass in constructor because whenever class of async task is created a constructor will called first.

    execute() is the place where you pass the parameters.You can use the constructor to pass something more general and not specific to a certain task. For example, passing your context to hold a reference to your UI (eg. progressBar).
    as AsyncTask is designed to pass parameter in execute method, You can pass parameters to execute method, it will invoke onPreExecute method with same parameter, and there you can do your initialization tasks as well. it depends on you how you wants to approach.

    the document for the precise notes from Android docs
    http://developer.android.com/reference/android/os/AsyncTask.html

    Hope i helped you on this. if not please ask again that i can have something for you. Thanks :)

    ReplyDelete
  6. Thanks.....For the information
    Now i got the flow of program.

    ReplyDelete
  7. I get this error in my list_item.xml file: "Unexpected namespace prefix "xmlns" found for tag
    LinearLayout"

    ReplyDelete
    Replies
    1. Hi AFTER a long time i am back , can you tell me what is the error? and which line you are getting the error!!

      Delete
  8. This comment has been removed by the author.

    ReplyDelete
  9. Hi,
    Thanks for such a nice tutorial. I have a question - this is a snippet from your json:

    {
    "vehicleType": "excavator",
    "vehicleColor": "yellow",
    "fuel": "diesel",
    "approvedOperators":
    [
    {
    "name": "Greg Stark",
    "experiencePoints": 13
    },
    {
    "name": "Aarti Patel",
    "experiencePoints": 21
    },
    {
    "name": "Tarek Mizan",
    "experiencePoints": 9
    }
    ],
    "treadType": "plate chain"
    }

    I have downloaded the source code and I realized that it doesn't handle the approvedoperators node, can you modify the code to include it? Or may be just give a code snippet which can handle this. Hoping to get response soon

    ReplyDelete
  10. Hi, if you will see the json than at"approvedOperators" is an array which contains the other squence of objects. what you need to do is acquire the tag "approvedOperators" as an array and than parse it will help you. i you will face any problem please mail that i can work on this tag and will send you the code.

    ReplyDelete
  11. I tried a lot but couldn't figure out: here's a snippet from my JSON which I need to parse and try to put this snippet in place of "approvedOperators" because my JSON is pretty complex and this snippet comes in the middle. I couldn't figure out which is object and which is array out of phone_numbers/phone_group/phone and I was receiving JSONObject can't be converted to JSONArray. Can you please help me with this?
    "phone_numbers": {
    "phone_group": {
    "phone": [
    {
    "phone_number": 9999999999,
    "formattedPhNbr": "999-999-9999",
    "phone_type": "Local",
    "description": {

    },
    "phoneTags": "english,information,local",
    "label": "Operator/information",
    "vanity_number": {

    },
    "work_hours": ""
    },
    {
    "phone_number": 9999999999,
    "formattedPhNbr": "999-999-9999",
    "phone_type": "Local",
    "description": {

    },
    "phoneTags": "english,information,local",
    "label": "Appointment and Advice Call Center",
    "vanity_number": {

    },
    "work_hours": ""
    }
    ]
    }
    }

    ReplyDelete
    Replies
    1. Hi Achint i have sent you the full code on yours mail please have a look there : i think yours problem is solved now.

      Delete
  12. Hi ACHINT "phone_numbers" is representing itself an object that "phone_group" is an object and than "phone" is an array. one thing i am doing is i am going to writ the code for this and than will send to you on yours mail or will copy the code here only, please give me some time that i am going to solve this.

    ReplyDelete
  13. hi achint i validate the json you sent at http://jsonlint.com/ but it was not validating please give me the correct json that i can work on yours problem. you can sent that on my mail upadhyay.jitesh@gmail.com

    ReplyDelete
  14. Can it be that when i download te source, it wil showup emty in my eclipse?

    if you want to respond: adriaansendennis@gmail.com

    ReplyDelete
    Replies
    1. Hi Please check the mail, hope it will work finefor you.i have sent the source code to you.

      Delete
    2. Hi I have sent two mails to you on adriaansendennis@gmail.com please look them two examples for you for better understanding, hope it will work fine for you now.

      Delete
  15. Can I use JSON if I want to store data taken from internet in file API ? If yes, then how ?

    I am basically making an application where I need to store a lot of data. Is there any other alternative ?

    ReplyDelete
    Replies
    1. yes you can store it, but it will not be a good practice because ultimately you need to parse the json , so after getting streams , rather than streaming into file system you can parse json data directly, it will save the time as well as yours memory. there are lot of other ways to get structured data like 1) xml that you can parsedata 2) use of SOAP web services 3) json parsing

      Delete
  16. thanks a lot, it is really nice tutorial.

    ReplyDelete
  17. http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=

    parsing above url

    ReplyDelete
  18. please post example code snippet

    ReplyDelete
    Replies
    1. Hi As we can see, the above goven url giving the string {
      "responseData": {
      "results": [],
      "cursor": {
      "moreResultsUrl": "http://www.google.com/search?oe=utf8&ie=utf8&source=uds&start=0&hl=en&q",
      "searchResultTime": "0.00"
      }
      },
      "responseDetails": null,
      "responseStatus": 200
      } json string is started by a jsonpbjectwhich is having three json objects with the name responseData,responseDetails,responseStatus. now finally inside responseData there is an object having an array results and an object with tag cursor..so please have a try in this way but if still u need the full code than i wil send to you.

      if we will investigate the

      Delete
  19. I copied all the code but somehow it doesn't work... It gave me loads of error.. please help!

    ReplyDelete
  20. Error occured
    03-20 04:50:34.671: D/AndroidRuntime(1236):
    Shutting down VM
    03-20 04:50:34.671: W/dalvikvm(1236): threadid=1: thread exiting with uncaught exception (group=0xb3abcba8)

    03-20 04:50:34.691: E/AndroidRuntime(1236): FATAL EXCEPTION: main
    03-20 04:50:34.691: E/AndroidRuntime(1236): Process: com.example.popup, PID: 1236

    03-20 04:50:34.691: E/AndroidRuntime(1236): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.popup/com.example.popup.MainActivity}: java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'

    03-20 04:50:34.691: E/AndroidRuntime(1236): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
    03-20 04:50:34.691: E/AndroidRuntime(1236): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
    03-20 04:50:34.691: E/AndroidRuntime(1236): at android.app.ActivityThread.access$800(ActivityThread.java:135)
    03-20 04:50:34.691: E/AndroidRuntime(1236): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
    03-20 04:50:34.691: E/AndroidRuntime(1236): at android.os.Handler.dispatchMessage(Handler.java:102)

    03-20 04:50:34.691: E/AndroidRuntime(1236): at android.os.Looper.loop(Looper.java:136)

    03-20 04:50:34.691: E/AndroidRuntime(1236): at android.app.ActivityThread.main(ActivityThread.java:5017)
    03-20 04:50:34.691: E/AndroidRuntime(1236): at java.lang.reflect.Method.invokeNative(Native Method)

    03-20 04:50:34.691: E/AndroidRuntime(1236): at java.lang.reflect.Method.invoke(Method.java:515)
    03-20 04:50:34.691: E/AndroidRuntime(1236): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)

    03-20 04:50:34.691: E/AndroidRuntime(1236): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)

    03-20 04:50:34.691: E/AndroidRuntime(1236): at dalvik.system.NativeStart.main(Native Method)

    03-20 04:50:34.691: E/AndroidRuntime(1236): Caused by: java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'

    03-20 04:50:34.691: E/AndroidRuntime(1236): at android.app.ListActivity.onContentChanged(ListActivity.java:243)

    03-20 04:50:34.691: E/AndroidRuntime(1236): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:293)

    03-20 04:50:34.691: E/AndroidRuntime(1236): at android.app.Activity.setContentView(Activity.java:1929)

    03-20 04:50:34.691: E/AndroidRuntime(1236): at com.example.popup.MainActivity.onCreate(MainActivity.java:53)

    03-20 04:50:34.691: E/AndroidRuntime(1236): at android.app.Activity.performCreate(Activity.java:5231)

    03-20 04:50:34.691: E/AndroidRuntime(1236): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)

    03-20 04:50:34.691: E/AndroidRuntime(1236): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)

    03-20 04:50:34.691: E/AndroidRuntime(1236): ... 11 more


    The error will be display. please help me!

    ReplyDelete