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);

Tags: , , , ,

57 Comments on Android accessing RESTFull Web Services using JSON

  1. Jose C Gomez says:

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

  2. 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.

  3. Jose C Gomez says:

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

  4. Lucas says:

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

  5. 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

  6. Jose C Gomez says:

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

    Thanks!

  7. [...] 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. [...]

Leave a Reply

*