I just finished a huge project for school using the Google Android OS. The biggest hurdle I had to jump through we getting android to successfully talk to web services. I have put together a set of classes and procedures to do so that make it easy and reliable. I have taken some code from here and there and adapted my own. It was a while ago so I don’t recall where I found it all. For this example I am going to be using the web service  http://www.sumasoftware.com/alerts/GetAlerts.php to read the alerts.

The first thing you’ll need to download and add to your project is the google GSON library http://code.google.com/p/google-gson/downloads/list

Add the jar file to your android project as an external jar

Download the following WebService.java class in order to interact with the web service and add it to your project

package josecgomez.com.android.dev.webservice;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

import com.google.gson.Gson;

public class WebService{

    DefaultHttpClient httpClient;
    HttpContext localContext;
    private String ret;

    HttpResponse response = null;
    HttpPost httpPost = null;
    HttpGet httpGet = null;
    String webServiceUrl;

    //The serviceName should be the name of the Service you are going to be using. 
    public WebService(String serviceName){
        HttpParams myParams = new BasicHttpParams();

        HttpConnectionParams.setConnectionTimeout(myParams, 10000);
        HttpConnectionParams.setSoTimeout(myParams, 10000);
        httpClient = new DefaultHttpClient(myParams);       
        localContext = new BasicHttpContext();
        webServiceUrl = serviceName;
       
    }

    //Use this method to do a HttpPost\WebInvoke on a Web Service
    public String webInvoke(String methodName, Map<String, Object> params) {
    	
    	JSONObject jsonObject = new JSONObject();

    	for (Map.Entry<String, Object> param : params.entrySet()){
    		try {
    			jsonObject.put(param.getKey(), param.getValue());
			} 
    		catch (JSONException e) {
    			Log.e("Groshie", "JSONException : "+e);
			}
    	}
        return webInvoke(methodName,  jsonObject.toString(), "application/json");
    }

    private String webInvoke(String methodName, String data, String contentType) {
        ret = null;

        httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109);

        httpPost = new HttpPost(webServiceUrl + methodName);
        response = null;

        StringEntity tmp = null;        

        //httpPost.setHeader("User-Agent", "SET YOUR USER AGENT STRING HERE");
        httpPost.setHeader("Accept", 
"text/html,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");

        if (contentType != null) {
            httpPost.setHeader("Content-Type", contentType);
        } else {
            httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
        }

        try {
            tmp = new StringEntity(data,"UTF-8");
        } catch (UnsupportedEncodingException e) {
            Log.e("Groshie", "HttpUtils : UnsupportedEncodingException : "+e);
        }

        httpPost.setEntity(tmp);

        Log.d("Groshie", webServiceUrl + "?" + data);

        try {
            response = httpClient.execute(httpPost,localContext);

            if (response != null) {
                ret = EntityUtils.toString(response.getEntity());
            }
        } catch (Exception e) {
            Log.e("Groshie", "HttpUtils: " + e);
        }

        return ret;
    }

    //Use this method to do a HttpGet/WebGet on the web service
    public String webGet(String methodName, Map<String, String> params) {
    	String getUrl = webServiceUrl + methodName;
    	
    	int i = 0;
    	for (Map.Entry<String, String> param : params.entrySet())
    	{
    		if(i == 0){
    			getUrl += "?";
    		}
    		else{
    			getUrl += "&";
    		}
    		
    		try {
				getUrl += param.getKey() + "=" + URLEncoder.encode(param.getValue(),"UTF-8");
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    		
    		i++;
    	}
    	
        httpGet = new HttpGet(getUrl);  
        Log.e("WebGetURL: ",getUrl);
        
        try {
            response = httpClient.execute(httpGet);  
        } catch (Exception e) {
            Log.e("Groshie:", e.getMessage());
        }

        // we assume that the response body contains the error message  
        try {
            ret = EntityUtils.toString(response.getEntity());  
        } catch (IOException e) {
            Log.e("Groshie:", e.getMessage());
        }

        return ret;
    }
    
    public static JSONObject Object(Object o){
    	try {
			return new JSONObject(new Gson().toJson(o));
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return null;
    }

    public InputStream getHttpStream(String urlString) throws IOException {
        InputStream in = null;
        int response = -1;

        URL url = new URL(urlString); 
        URLConnection conn = url.openConnection();

        if (!(conn instanceof HttpURLConnection))                     
            throw new IOException("Not an HTTP connection");

        try{
            HttpURLConnection httpConn = (HttpURLConnection) conn;
            httpConn.setAllowUserInteraction(false);
            httpConn.setInstanceFollowRedirects(true);
            httpConn.setRequestMethod("GET");
            httpConn.connect(); 

            response = httpConn.getResponseCode();                 

            if (response == HttpURLConnection.HTTP_OK) {
                in = httpConn.getInputStream();                                 
            }                     
        } catch (Exception e) {
            throw new IOException("Error connecting");            
        } // end try-catch

        return in;     
    }
    
    public void clearCookies() {
        httpClient.getCookieStore().clear();
    }

    public void abort() {
        try {
            if (httpClient != null) {
                System.out.println("Abort.");
                httpPost.abort();
            }
        } catch (Exception e) {
            System.out.println("Your App Name Here" + e);
        }
    }
}

Based on the structure of your JSON file develop a class in your project to support the structure. For example for the above mentioned service I developed this class.

The JSON returned has this structure {“alertid”:”1″,”alerttext”:”This is test”,”alertdate”:”2010-02-11 09:03:40″}

package josecgomez.com.android.dev.webservice.objects;

public class alerts {
	
	public int alertid;
	public String alerttext;
	public String alertdate;
	
	@Override
	public String toString()
	{
		return "Alert ID: "+alertid+ " Alert Text: "+alerttext+ " Alert Date: "+alertdate;
		
	}
}

Once you’ve done this in your android activity you may execute the following code to access the web service

 // Instantiate the Web Service Class with he URL of the web service not that you must pass
        
        WebService webService = new WebService("http://www.sumasoftware.com/alerts/GetAlerts.php");

        //Pass the parameters if needed , if not then pass dummy one as follows
		Map<String, String> params = new HashMap<String, String>();
		params.put("var", "");
		
		//Get JSON response from server the "" are where the method name would normally go if needed example
		// webService.webGet("getMoreAllerts", params);
		String response = webService.webGet("", params);

		try
		{
			//Parse Response into our object
			Type collectionType = new TypeToken<List<alerts>>(){}.getType();
			List<alerts> alrt = new Gson().fromJson(response, collectionType);
		
		}
		catch(Exception e)
		{
			Log.d("Error: ", e.getMessage());
		}

Please note that the above code is for accessing collection of items, if you are attempting to access a single item there should be a slight modification to the code as follows

/* Replace
Type collectionType = new TypeToken<List<alerts>>(){}.getType();
List<alerts> alrt = new Gson().fromJson(response, collectionType);
with
*/
alerts alert = new Gson().fromJson(response, alerts.class);

The above method uses GET if you need to INVOKE POST there should be a slight modification to the above code as follows. I hope this helps.

/* Replace 
String response = webService.webGet("", params);
with
*/
webService.webInvoke("", params);

Be Sociable, Share!

Tags: , , , ,

62 Comments on Android accessing RESTFull Web Services using JSON

  1. Rahul says:

    I want to display the alert text and date in the list view…Can u plz tell me how to do it… The code for the xml is as follows…

  2. Jose C Gomez says:

    Visit the most recent post in my blog as a follow up to your question.

  3. Levi says:

    Hey Jose, this info is great. Exactly the solution I’m looking for.

    Would you happen to know why gson is generating an error in eclipse when the jars are added?

    Error generating final archive: duplicate entry: assembly-descriptor.xml

    I’ve scoured the web and cannot find a resolution.

    Thanks.

  4. Jose C Gomez says:

    Have you added the jar I created ?? Or just the GSON jar? If you added the jar I created on my newwest post then do not inmport the GSON since i’ve included them in there already. If you are using the GSON jar and the above class. Try removing the GSON jar form the project and download my jar

  5. Hasn says:

    Thank you very very much, ve been looking for this solution for quite some time.

    just one advise, when add the Gson jar file from Google, there will be three jar files, you need to add only the Gson, if you add the three of them, the app will issue an error, do not know why, but I needed to remove the other files to get it working…

    Thank you very much and keep the great work up ;)

    Cheers
    Hasn

  6. Sarun says:

    The error was occurred “The application has stopped unexpectedly. Please try agaian”. How can I fix this problem? Please help me.

  7. Sarun says:

    There is three Java class in my project which are WebService, Alerts, and GSONWebService. The GSONWebService class is the activity containing the following code like these.

    public class GSONWebService extends Activity {
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    WebService webService = new WebService(“http://www.sumasoftware.com/alerts/GetAlerts.php”);
    Map params = new HashMap();
    params.put(“var”, “”);
    String response = webService.webGet(“”, params);
    try{
    Type collectionType = new TypeToken<List>(){}.getType();
    List alrt = new Gson().fromJson(response, collectionType);
    }
    catch(Exception e){
    Log.d(“Error: “, e.getMessage());
    }
    }
    }

    Apart from that I just directly copy and paste the code that you posted.

  8. Jose C Gomez says:

    Look at the code above you need to return a List of alerts not just a list and specify string, string on your hash map. See the third code snippet

    // Instantiate the Web Service Class with he URL of the web service not that you must pass
    
           WebService webService = new WebService("http://www.sumasoftware.com/alerts/GetAlerts.php");
    
           //Pass the parameters if needed , if not then pass dummy one as follows
    	Map<String, String> params = new HashMap<String, String>();
    	params.put("var", "");
    
    	//Get JSON response from server the "" are where the method name would normally go if needed example
    	// webService.webGet("getMoreAllerts", params);
    	String response = webService.webGet("", params);
    
    	try
    	{
    		//Parse Response into our object
    		Type collectionType = new TypeToken<List<alerts>>(){}.getType();
    		List<alerts> alrt = new Gson().fromJson(response, collectionType);
    
    	}
    	catch(Exception e)
    	{
    		Log.d("Error: ", e.getMessage());
    	}
    
  9. Selena says:

    Hello,

    very good example, thank you for this.
    But could you maybe post your Activity class? I’m new into Android but would like to learn more about it.
    Thank you!

  10. Jose C Gomez says:

    I have the Activity code on the followup post
    http://www.josecgomez.com/2010.....-listview/

    Let me know if you need anything else.

  11. Matt says:

    This is really helpful… one problem I can’t seem to figure out. It seems when this list is built in combination with other elements on the screen, it repeats all of the items for each result it picks up. Is there any way to make it not do that? I assume you are not using a list view because of certain problems associated with this type of data…? I am basically trying to return this between a top and bottom footer of the screen and it duplicates all elements x times (x=# of recs).

  12. Jose C Gomez says:

    Did you look at the previous comment where I said to go look at a different blog entry that shows how to put it on a custom list view? Take a look at that and let me know if it helps!

    Thanks!

  13. Karl says:

    This seems so incredibly complicated to turn JSON encoded data from PHP into usable string data for Android…Is there not a simpler way to call the php request and drop it right into useable android string format?

  14. ganesh says:

    hi ,
    can i send a json object from android and access in rest service which i created in .net ?

    or

    is it possible to convert the json string/object to a class object and send it to .net rest service?

    for me the problem is im using stringbuidler for my asp.net client to insert data into database as json..but from android client i could not insert.. !!

  15. tom says:


    /* Replace
    String response = webService.webGet("", params);
    with
    */
    webService.webInvoke("", params);

    this doesn’t work

  16. Abdulaziz says:

    thanks a lot.

    your tutorial was very helpful.

  17. vani says:

    hi,
    i am getting nullPointerException,what to do?
    i am not getting anything.

  18. vani says:

    In those 3 jar files,i added one jar file

  19. Mustafa says:

    Nice! I am planning to use this in a project I am starting. Can you please throw some light on how I can authenticate users with username/password and keep the user logged in for the entire session?

  20. flash cards says:

    You rock. I have ben searching for info on restful json and android for awhile. This is the most complete demonstration ever. Super thanks!

  21. jubin says:

    Hello ,

    When i use your code in my project its gives below error ithink there is something wrong with type.I have included the header file but its gives this type of error.

    The method fromJson(String, Class) in the type Gson is not applicable for the arguments (String, Proxy.Type) weblist.java line 37.

    Thanks,
    Jubin

  22. Renuka says:

    working fine… nice tutorial
    thanks

  23. Mark says:

    If you get the “Force Close” issue (NullPointer exception) try adding the uses-permission android:name=”android.permission.INTERNET” tag into the manifest section of you AndroidManifest.xml. Your app doesn’t have access to the internet.

  24. pranav says:

    where to put JAR file to call web services in android……

    Please, Give the solution with steps….

    Thanks…

  25. Gaurav says:

    Could you please post the implementation of your restful webservice. do you have a java implementaion of the webservice that we speak about over here….?

  26. Tun says:

    Awesome job,works perfectly for me.
    One question though,why didn’t you use the AsynkTask ?
    I ran the project with a low connection in the emulator and it crashed.

  27. Sergio says:

    Hi,
    let me say you your code is really helpfull but I dont understand what should I do for calling to a service with a json String. I mean, I got a REST service method consuming application/json.

    thanks

  28. loveAnd says:

    too hard for me!!

  29. Your article rulez. Thanks for posting good stuff.

  30. [...] Part 1 – getting the json data Part 2 – parsing the objects created to a custom adapter Part 3 – Lazy loading of images [...]

  31. jatin patel says:

    Thanks, it worked for me.

  32. Hydro says:

    This is a very helpful tutorial.
    I would like to know how do I use this to get specific list of JSON strings? For example, I want to get the list of “Chairs” elements from a web service that contains all “Furniture”. How do I do this using your tutorial?
    My JSON string will be
    [{"type":"Chairs"
    ,{"company":"ABC"}]
    Thanks in advance.

  33. Hydro says:

    I have solved my previous problem by using your following codes, where WhatIWant is a string. Thanks for your posting here. It helps.
    //Pass the parameters if needed , if not then pass dummy one as follows
    HashMap params = new HashMap();
    params.put(“type”, WhatIWant.toLowerCase());

  34. rana says:

    Thanx a lot sir for ur valuable post. I appreciate ur knowledge. I was
    wondering if u could guide me about “To post the data from android apps To
    a WebServer or To send Password and Username to the Webserver”…..how I
    can convert my apps data into JSON format so that I will be able to send
    it to the server.

    Ur help would be appreciated :)

    please reply me either by mail or post it here :)

    my email id: ranakrishnapaul@gmail.com

  35. rana says:

    Thanx a lot sir for ur valuable post. I appreciate ur knowledge. I was
    wondering if u could guide me about “To post the data from android apps To
    a WebServer or To send Password and Username to the Webserver”…..how I
    can convert my apps data into JSON format so that I will be able to send
    it to the server.

    Ur help would be appreciated :)

    please reply me either by mail or post it here :)

    my email id: ranakrishnapaul@gmail.com

    Thank You,
    Rana

  36. Chris says:

    Don’t forget to add your permission to the network in the android.manifest file (replace “package=com.example.RestfulWebService” with your package name and the activity name:

  37. Electrokate says:

    Thank you so much! This is the only tutorial on Android Webservices I have actually gotten to work. Many thanks for posting your code!!!!

  38. Sudha rani says:

    hello ,i am doing live project.some one could u help me by give sample programs which are having remote database connectivity through web server.i am full of confusion

  39. Srikanth says:

    Thanku so much..really awesome code and exaplaintaion..please post these kind of tutorials…

  40. Wilmer says:

    Alguien que me facilite el ejemplo completo, que no corre.

  41. Wilmer says:

    Y para la version 3.0 ??? por que esta no funciona.. help please…

  42. Omar F. Rodriguez Morales says:

    I am trying to consume (from android) a webservice that i made using oracle jdeveloper running on Oracle Application Server 10.1.3, but i tried with ksoap and failed miserably, but i wanna know how to use your JSON class with a webservice published on OAS

    Thanks in advance

  43. Fredrick says:

    Thanks for the tutorial. Can you please show how to save this data to a local sqlite database? I am looking for a tutorial where you can sync your local database to MYSQL server. I am trying to use HTTP and PHP to make this happen but not allot of luck.

  44. Amila says:

    Hey thanx a looooooooooot for the code…highly appreciate it!! :)

  45. Fred Stluka says:

    Very useful! Thanks!

    –Fred Stluka

  46. [...] found this post which helped me accomplish my goal.  It presents a method based on the GSON library to parse JSON. [...]

  47. karan soni says:

    hello sir,
    i want to consume a webservice after login wed service but 2nd webservice is return , “user is not authuticated” , tell me the simple example

  48. David says:

    Do you have anything for an httpPut?

  49. sinchro says:

    amazing :) thank you. very helpful.

  50. Jose C Gomez says:

    I haven’t done Android Dev in a bit, sorry :(

  51. sinchro says:

    any chance u could upload the full source for the project? i’m a student in my 2nd year and i have trouble wrapping my head around your guide.

  52. Jose C Gomez says:

    This is an old post, I don’t have any of the source files. Sorry

  53. Lucas says:

    Thats not a RESTful service. This is WebService with method calls.

  54. Nick Penkov says:

    Very nice article. Unfortunately it will not work straight forward with the latest Android 4.X, as Network operations are not permitted from UI thread. I am planning to create similar article with the latest apis, and some demos for creating and consuming RESTfull web services in Java, if you don’t mind I will put reference to your post.

    Thanks,
    Nick

  55. Jose C Gomez says:

    Sure no problem, I haven’t had time to update anything regarding Android recently, I appreciate that you asked :)

    Thanks!

  56. [...] In other words – our UI class will implement this interface and pass self instance to AsyncThread. When AsyncThread webservice class finishes his work – he will call implementation method response(String) of our UI class to notify about the result. I have to admit here that some of the code for WebService Call – I have copied from Jose C Gomez’s Blog. [...]

  57. hans stam says:

    the thing most people will be missing is in the android manifest. if you add that, the app will run

  58. JOrge says:

    What import do I need for this obnect Type collectionType?

  59. JOrge says:

    I hve an error when a parser my class:
    public class Channel implements Serializable {

    /**
    *
    */
    private static final long serialVersionUID = 1L;
    public String code;
    public String name;
    public int order;
    public String description;
    public boolean enabled;
    public String equipmentCode;
    public double offset;
    public double slope;
    public String unit;
    public int decimals;
    public double minValue;
    public double maxValue;
    public int rawValue;
    public double calculatedValue;
    public String calculatedValueAndUnit;
    public boolean rawValueSupported;
    public double setPointValue;
    public long tsUpdated;
    public long tsProcessed;
    public int lifetime;
    public boolean upToDateNotified;
    public String channelTypeName;
    public int watchCount;
    public String channelTypeCode;
    public String direction;

    @Override
    public String toString() {
    return “Channel “;
    }

    }

    Type collectionType = new TypeToken<List>(){}.getType();
    channels = new Gson().fromJson(response, collectionType);
    Expected BEGIN_ARRAY but Was BEGIN_OBJECT

  60. Ashish says:

    Very nice and detailed post for android developers. Thanks a lot

Leave a Reply