Home > Programming / tutorials > Parsing JSON Results in Android

Parsing JSON Results in Android

January 26th, 2011 Leave a comment Go to comments

One of the common requirements for an android programmer is how to parse incoming JSON results from another web service or application into android. JSON is a data interchange format, and serves the same purpose as that of XML. XML is slowly being replaced by JSON because it’s easy to parse, light weight, and efficient too. We had talked about SOAP vs JSON earlier and not going to go into details again.

Let us focus on how to parse JSON results in Android.

We can parse JSON by 2 methods

i)  Using JSONObject and JSONTokener classes provided by Android SDK.
ii) Using external libraries. E.g GSON, Jackson etc.
(for more details refer http://json.org)

Let’s consider JSON data of the form:

{
“name”: “myName”,
“message”: [“myMessage1″,”myMessage2″],
“place”: “myPlace”,
“date”:  “thisDate”
}

Parsing JSON data using JSONTokener


public
class main extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

try {

/* Inflate TextView from the layout */

TextView tv = (TextView)findViewById(R.id.TextView01);

/* JSON data considered as an example. Generally this data is obtained

from a web service.*/

String json = “{”

+ ”  \”name\”: \”myName\”, ”

+ ”  \”message\”: [\”myMessage1\”,\”myMessage2\”],”

+ ”  \”place\”: \”myPlace\”, ”

+ ”  \”date\”: \”thisDate\” ”

+ “}”;

/* Create a JSON object and parse the required values */

JSONObject object = (JSONObject) new JSONTokener(json).nextValue();

String name = object.getString(“name”);

String place = object.getString(“place”);

String date = object.getString(“date”);

JSONArray message = object.getJSONArray(“message”);

tv.setText(“Name: “+ name +”\n\n”);

tv.append(“Place: “+ place +”\n\n”);

tv.append(“Date: “+ date +”\n\n”);

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

{

tv.append(“Message: “+ message.getString(i) +”\n\n”);

}

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

catch(Exception ex){ex.printStackTrace();}

}

}

Parsing JSON data using GSON (External Libraries)

External Libraries like GSON are commonly used because they are quicker than the android classes mentioned above. There are many libraries available to parse JSON, be careful while choosing one.

1)    Download GSON library

http://code.google.com/p/google-gson/

2)    Add GSON library to your project

i)     Right click on your project and select properties


ii)   Select Java Build Path



iii)   Click on “ Libraries “ tab and select “Add External JARs” at the right corner and add the downloaded jar.

3)    Create a class structure in accordance with the JSON response/data.

public class JSON_structure {
public String name;
public String place;
public String date;
public String[] message;
}
4)    Deserialize the JSON string

Gson gson = new Gson();
JSON_structure obj=

gson.fromJson(json, JSON_structure.class);

Here is the complete code.

public class main extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

try {

/* Inflate TextView from the layout */

TextView tv = (TextView)findViewById(R.id.TextView01);

/* JSON data considered as an example. Generally this data is obtained

from a web service.*/

String json = “{”

+ ”  \”name\”: \”myName\”, ”

+ ”  \”message\”: [\”myMessage1\”,\”myMessage2\”],”

+ ”  \”place\”: \”myPlace\”, ”

+ ”  \”date\”: \”thisDate\” ”

+ “}”;

Gson gson = new Gson();

JSON_structure obj= gson.fromJson(json, JSON_structure.class);

tv.setText(“Name: “+ obj.name +”\n\n”);

tv.append(“Place: “+ obj.place +”\n\n”);

tv.append(“Date: “+ obj.date +”\n\n”);

for(int i=0;i<obj.message.length;i++)

{

tv.append(“Message: “+ obj.message[i] +”\n\n”);

}

}

catch(Exception ex){ex.printStackTrace();}

}

}

In the above example I have considered simple JSON data. But if JSON data contains multiple events you need to create a container class along with the structure class as shown.

a. JSON data with multiple events


{ “List”:

[  { “post”:

{

“name”: “myName”,
“message”: [“myMessage1″,”myMessage2″],
“place”: “myPlace”,
“date”:  “thisDate”
},

{"post":

{

b. Now apart from structure class create a container class as shown

public class Container {

private List<JSON_structure> OBJ;

public List<JSON_structure> getObj() {
return OBJ;
}
public void setObj(List<JSON_structure> OBJ) {
this.OBJ = OBJ;

}

c. Now Deserialize

Gson gson = new Gson();
Container obj=

gson.fromJson(json, Container.class);

d.Display results

List <JSON_structure> struct_list = obj.getObj();

JSON_structure js;

for (int i = 0; i < struct_list.size(); i++) {

js = struct_list.get(i);

// Here tv is the TextView inflated from the layout

tv.append(js.name);

tv.append(js.place);

tv.append(js.date);

}

“name”: “myName”,
“message”: [“myMessage1″,”myMessage2″],
“place”: “myPlace”,
“date”:  “thisDate”
}
}]}

Categories: Programming / tutorials Tags: ,
  1. Sagar Zala
    January 27th, 2014 at 00:15 | #1

    Hi,

    I want to read data from .net web service using json in android.

    Thank you

  2. Robert Liguori
    May 9th, 2013 at 06:12 | #2

    Sushma, did you ever figure out your question….

    I too am seeing this:
    java.lang.RuntimeException: Failed to invoke public javax.xml.datatype.XMLGregorianCalendar() with no args

  3. Santhosh K
    April 25th, 2013 at 07:18 | #3

    {
    “data”: [
    {
    “userID”: “1046030”,
    “userName”: “BuddyTester”,
    “userGender”: “male”,
    “age”: “55”,
    “createdDate”: “2012-03-24T12:01:03.0000000-07:00″,
    “lastLoginDate”: “2012-03-26T10:19:46.0000000-07:00″,
    “statusID”: “2”,
    “profilePictureUrl”: “http://buddy.com/defaultprofilepic/buddymale.png”,
    “userLatitude”: “47.36”,
    “userLongitude”: “122.19”,
    “locationFuzzing”: “False”,
    “celebMode”: “False”,
    “userEmail”: “”,
    “userApplicationTag”: “”
    }
    ]
    }

    please help me for parsing this JSON response..

  4. pankaj
    January 10th, 2012 at 00:57 | #4

    Good For us

  5. Sushma
    July 6th, 2011 at 15:12 | #5

    I am new to JSON and using GSON too. I am getting this error when trying to convert JSON to Java object. Is there any way to solve this error, if so Please let me know.
    Unable to invoke no-args constructor for class javax.xml.datatype.XMLGregorianCalendar. Register an InstanceCreator with Gson for this type may fix this problem.
    JSON:
    “{\”historical\”:\”true\”,\”id\”:”
    +”{\”codeSystem\”:\”\”,\”codeSystemName\”:\”\”,\”value\”:\”f7cac88d-e5d1-48f3-a464-8d1204ae92c3\”,\”floatValue\”:\”0.0\”,\”displayable\”:\”true\”}”
    +”,\”sourceSystem\”:\”2.16.840.1.113883.3.200\”,”
    +”\”patientId\”:{\”codeSystem\”:\”2.16.840.1.113883.3.200\”,\”codeSystemName\”:\”\”,\”value\”:\”99990070\”,\”floatValue\”:\”9.9990072E7\”,\”displayable\”:\”true\”}”
    +”,\”adverseEventType\”:{\”codeSystem\”:\”2.16.840.1.113883.6.96\”,\”codeSystemName\”:\”SNOMED CT\”,\”code\”:\”416098002\”,\”label\”:\”drug allergy\”}”
    +”,\”codedProduct\”:{\”codeSystem\”:\”\”,\”codeSystemName\”:\”\”,\”code\”:\”UNK\”,\”label\”:\”Sulfa-Drugs\”}”
    +”,\”freeTextProduct\”:\”Sulfa-Drugs\”,\”adverseEventDate\”:\”1997-03-03T00:00:00-08:00\”,\”reaction\”:”
    +”{\”codedReaction\”:”
    +”{\”codeSystem\”:\”2.16.840.1.113883.6.96\”,\”codeSystemName\”:\”SNOMED CT\”,\”code\”:\”UNK\”,\”label\”:\”Anaphylaxis\”}”
    +”,\”freeTextReaction\”:\”Anaphylaxis\”,\”severity\”:”
    +”{\”codedSeverity\”:”
    +”{\”codeSystem\”:\”2.16.840.1.113883.6.96\”,\”codeSystemName\”:\”SNOMED CT\”,\”code\”:\”2448400\”,\”label\”:\”Severe\”}”
    +”,\”freeTextSeverity\”:\”Severe\”}}}”

    Java Object:

    package gov.hhs.fha.nhinc.adapter.fact;

    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import javax.xml.bind.annotation.XmlAccessType;
    import javax.xml.bind.annotation.XmlAccessorType;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlSchemaType;
    import javax.xml.bind.annotation.XmlType;

    /**
    * Java class for AllergyFactType complex type.
    *
    * The following schema fragment specifies the expected content contained within this class.
    *
    *

     * <complexType name="AllergyFactType">
     *   <complexContent>
     *     <extension base="{urn:gov:hhs:fha:nhinc:adapter:fact}FactType">
     *       <sequence>
     *         <element name="patientId" type="{urn:gov:hhs:fha:nhinc:adapter:fact}ValueType"/>
     *         <element name="adverseEventType" type="{urn:gov:hhs:fha:nhinc:adapter:fact}CodeLabelPair"/>
     *         <element name="codedProduct" type="{urn:gov:hhs:fha:nhinc:adapter:fact}CodeLabelPair"/>
     *         <element name="freeTextProduct" type="{http://www.w3.org/2001/XMLSchema}string"/>
     *         <element name="adverseEventDate" type="{http://www.w3.org/2001/XMLSchema}dateTime"/>
     *         <element name="reaction" type="{urn:gov:hhs:fha:nhinc:adapter:fact}ReactionFactType" maxOccurs="unbounded" minOccurs="0"/>
     *       </sequence>
     *     </extension>
     *   </complexContent>
     * </complexType>
     * 

    *
    *
    */
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = “AllergyFactType”, propOrder = {
    “patientId”,
    “adverseEventType”,
    “codedProduct”,
    “freeTextProduct”,
    “adverseEventDate”,
    “reaction”
    })
    public class AllergyFactType
    extends FactType
    implements Serializable {

    @XmlElement(name = “patientId”, required = true, namespace = “urn:gov:hhs:fha:nhinc:adapter:fact”)
    protected ValueType patientId;
    @XmlElement(name = “adverseEventType”, required = true, namespace = “urn:gov:hhs:fha:nhinc:adapter:fact”)
    protected CodeLabelPair adverseEventType;
    @XmlElement(name = “codedProduct”, required = true, namespace = “urn:gov:hhs:fha:nhinc:adapter:fact”)
    protected CodeLabelPair codedProduct;
    @XmlElement(name = “freeTextProduct”, required = true)
    protected String freeTextProduct;
    @XmlElement(name = “adverseEventDate”, type = Date.class, required = true)
    @XmlSchemaType(name = “dateTime”)
    protected Date adverseEventDate;
    @XmlElement(name = “reaction”, namespace = “urn:gov:hhs:fha:nhinc:adapter:fact”)
    protected List reaction;

    //—————————————————————————
    // JAXB generated codes
    //—————————————————————————

    /**
    * Sets the value of the patientId property.
    *
    * @param value
    * allowed object is
    * {@link ValueType }
    *
    */
    public void setPatientId(ValueType value) {
    this.patientId = value;
    }

    /**
    * Gets the value of the freeTextProduct property.
    *
    * @return
    * possible object is
    * {@link ValueType }
    *
    */
    public ValueType getPatientId() {
    return patientId;
    }

    /**
    * Gets the value of the adverseEventType property.
    *
    * @return
    * possible object is
    * {@link CodeLabelPair }
    *
    */
    public CodeLabelPair getAdverseEventType() {
    return adverseEventType;
    }

    /**
    * Sets the value of the adverseEventType property.
    *
    * @param value
    * allowed object is
    * {@link CodeLabelPair }
    *
    */
    public void setAdverseEventType(CodeLabelPair value) {
    this.adverseEventType = value;
    }

    /**
    * Gets the value of the codedProduct property.
    *
    * @return
    * possible object is
    * {@link CodeLabelPair }
    *
    */
    public CodeLabelPair getCodedProduct() {
    return codedProduct;
    }

    /**
    * Sets the value of the codedProduct property.
    *
    * @param value
    * allowed object is
    * {@link CodeLabelPair }
    *
    */
    public void setCodedProduct(CodeLabelPair value) {
    this.codedProduct = value;
    }

    /**
    * Gets the value of the freeTextProduct property.
    *
    * @return
    * possible object is
    * {@link String }
    *
    */
    public String getFreeTextProduct() {
    return freeTextProduct;
    }

    /**
    * Sets the value of the freeTextProduct property.
    *
    * @param value
    * allowed object is
    * {@link String }
    *
    */
    public void setFreeTextProduct(String value) {
    this.freeTextProduct = value;
    }

    /**
    * Gets the value of the adverseEventDate property.
    *
    * @return
    * possible object is
    * {@link Date }
    *
    */
    public Date getAdverseEventDate() {
    return adverseEventDate;
    }

    /**
    * Sets the value of the adverseEventDate property.
    *
    * @param value
    * allowed object is
    * {@link Date }
    *
    */
    public void setAdverseEventDate(Date value) {
    this.adverseEventDate = value;
    }

    /**
    * Gets the value of the reaction property.
    *
    *
    * This accessor method returns a reference to the live list,
    * not a snapshot. Therefore any modification you make to the
    * returned list will be present inside the JAXB object.
    * This is why there is not a set method for the reaction property.
    *
    *
    * For example, to add a new item, do as follows:
    *

       *    getReaction().add(newItem);
       * 

    *
    *
    *
    * Objects of the following type(s) are allowed in the list
    * {@link ReactionFactType }
    *
    *
    */
    public List getReaction() {
    if (reaction == null) {
    reaction = new ArrayList();
    }
    return this.reaction;
    }

    //—————————————————————————
    // Add any custom codes here
    //—————————————————————————
    public void setReaction(ArrayList reaction) {
    this.reaction = reaction;
    }

    @Override
    public String toString() {
    StringBuffer str = new StringBuffer();

    str.append(“AllergyFactType[” + super.toString() + System.getProperty(“line.separator”));
    str.append(” patientId=” + patientId + System.getProperty(“line.separator”));
    str.append(” adverseEventType=” + (adverseEventType != null ? adverseEventType : “”) + System.getProperty(“line.separator”));
    str.append(” adverseEventDate=” + adverseEventDate + System.getProperty(“line.separator”));
    str.append(” codedProduct=” + (codedProduct != null ? codedProduct : “”) + System.getProperty(“line.separator”));
    str.append(” freeTextProduct=” + this.freeTextProduct + System.getProperty(“line.separator”));
    str.append(” #reactions=” + getReaction().size() + System.getProperty(“line.separator”));
    for (int i = 0; i #” + i + reaction.get(i) + System.getProperty(“line.separator”));
    }

    str.append(“]”);

    return str.toString();
    }
    }

  6. April 12th, 2011 at 15:21 | #6

    Naynesh , where do you see this exception ? Can you post a more detailed log ?

  7. Nayanesh Gupte
    April 12th, 2011 at 00:19 | #7

    EXCEPTION :java.lang.RuntimeException: Unable to invoke no-args constructor for class com.xyz. Register an InstanceCreator with Gson for this type may fix this problem.

    how to solve this issue?

  8. Sunag
    February 17th, 2011 at 04:00 | #8

    Superb! Thanks :-)

  1. January 26th, 2011 at 12:36 | #1