Categories

Different ways to access HTTP resources from Android

In this article, I invite the reader to discover the different methods to access http resources from the Android platform.
These methods can be adapted to access web services (using REST) or simply to download files !

First Method : getting an input stream given a simple url from Android using HttpURLConnection

This method is the most basic one : it allows you, using the basic HttpUrlConnection, ( contained in java.net) to get an InputStream from an Url :

private InputStream downloadUrl(String url) {
		HttpURLConnection con = null;
		URL url;
		InputStream is=null;
		try {
			url = new URL(url);
			con = (HttpURLConnection) url.openConnection();
			con.setReadTimeout(10000 /* milliseconds */);
			con.setConnectTimeout(15000 /* milliseconds */);
			con.setRequestMethod("GET");
			con.setDoInput(true);
			con.addRequestProperty("Referer", "http://blog.dahanne.net");
			// Start the query
			con.connect();
			is = con.getInputStream();
		}catch (IOException e) {
                        //handle the exception !
			e.printStackTrace();
		}
		return is;
 
	}

You can also use the Post method, sending data in the HTTP POST payload :

private InputStream downloadUrl(String url) {
                InputStream myInputStream =null;
		StringBuilder sb = new StringBuilder();
                //adding some data to send along with the request to the server
		sb.append("name=Anthony");
		URL url;
		try {
			url = new URL(url);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setDoOutput(true);
			conn.setRequestMethod("POST");
			OutputStreamWriter wr = new OutputStreamWriter(conn
					.getOutputStream());
                        // this is were we're adding post data to the request
                        wr.write(sb.toString());
			wr.flush();
			myInputStream = conn.getInputStream();
			wr.close();
		} catch (Exception e) {
                        //handle the exception !
			Log.d(TAG,e.getMessage());
		}
                return myInputStream;
}

But there are better ways to achieve that, using Apache HttpClient, included in android.jar (no need to add another jar, it’s included in android core)

Second Method : getting an input stream given a simple url from Android using HttpClient

Why is it a better to do it ? because the simpler, the better ! See by yourself :

public static InputStream getInputStreamFromUrl(String url) {
		InputStream content = null;
		try {
			HttpGet httpGet = new HttpGet(url);
			HttpClient httpclient = new DefaultHttpClient();
			// Execute HTTP Get Request
			HttpResponse response = httpclient.execute(httpGet);
			content = response.getEntity().getContent();
                } catch (Exception e) {
			//handle the exception !
		}
		return content;
}

But you maybe wondering if it’s still easy with HTTP Post method ? You won’t be deceived !

public static InputStream getInputStreamFromUrl(String url) {
		InputStream content = null;
		try {
          		HttpClient httpclient = new DefaultHttpClient();
			HttpPost httpPost = new HttpPost(url);
			List nameValuePairs = new ArrayList(1);
                        //this is where you add your data to the post method
                        nameValuePairs.add(new BasicNameValuePair(
			"name", "anthony"));
			httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
			// Execute HTTP Post Request
			HttpResponse response = httpclient.execute(httpPost);
			content = response.getEntity().getContent();
		        return content;
	        }
}

But what if you want to read a cookie from the response ? And how can you send a cookie back to the server for the next request ?

Reading / Sending a cookie along with the requests

Using Apache HttpClient, it’s easy to retrieve cookies ! Everything is in the headers after all !

[...]
Cookie sessionCookie =null;
HttpResponse response = httpclient.execute(httpPost);
Header[] allHeaders = response.getAllHeaders();
CookieOrigin origin = new CookieOrigin(host, port,path, false);
for (Header header : allHeaders) {
			List parse = cookieSpecBase.parse(header, origin);
			for (Cookie cookie : parse) {
				// THE cookie
				if (cookie.getName().equals(COOKIE_I_WAS_LOOKING_FOR)
						&& cookie.getValue() != null && cookie.getValue() != "") {
					sessionCookie = cookie;
				}
			}
}

To send a cookie along with your request, keep it simple :

HttpPost httpPost = new HttpPost(url);
CookieSpecBase cookieSpecBase = new BrowserCompatSpec();
List cookies = new ArrayList();
cookies.add(sessionCookie);
List cookieHeader = cookieSpecBase.formatCookies(cookies);
// Setting the cookie
httpPost.setHeader(cookieHeader.get(0));

What about the resulting InputStream ? You definitely want to transform it into a String or an Drawable (to set it to an ImageView for example !) don’t you ?

Converting the InputStream into a Drawable in Android

The Drawable class already handles that for you :

Drawable d = Drawable.createFromStream(myInputStream, "nameOfMyResource");

Converting the InputStream into a String in Android

This is some classic java stuff (don’t tell about how easier it is in Ruby.. I know :-( … but hey ! Java SE7 at the rescue with NIO !!! maybe one day in 2010 ! )

BufferedReader rd = new BufferedReader(new InputStreamReader(myInputStreamToReadIntoAString), 4096);
String line;
StringBuilder sb =  new StringBuilder();
while ((line = rd.readLine()) != null) {
		sb.append(line);
}
rd.close();
String contentOfMyInputStream = sb.toString()
 
That's it folks ! If you have any other methods to achieve these goals, feel free to share them sending a comment !

26 comments to Different ways to access HTTP resources from Android

  • Great article! Thank you

  • It’s very good! Thank you

  • Rui Gonçalves

    Hi there!

    First of all, great post! I only have one question: it is possible to send a xml string in the HTTP POST payload?

    Thanks in advance,
    Best regards!

  • yeah sure, for a REST POST action for example !

  • Rui Gonçalves

    Hi again!

    I´m developing a client application that must send a xml string with the requests to a HTTP server, that is running on port 2323. My approach, is to establish a socket and send a HTTP POST with a xml string. In your examples, you only use the URL to establish the connections but, the server only listens the port 2323 and so I think I must establish a connection through a socket.

    Could you give any suggestion?

    Thanks in advance,
    Best regards!

  • Hello Rui !
    you only have to specify the port at the end of the URL, HttpClient will guess it !
    for example :
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost(« http://myurl:2323″);
    will do the trick !

  • Rui Gonçalves

    Hi Anthony!

    Thanks for your help so far. It is necessary any additional network configuration in the Android emulator to send the request to the server?

    Best regards!

  • No ! I suggest you to try, it is the best way to learn !

  • Rui Gonçalves

    Hi!

    I know trying it’s the best way to learn but the designated time for this project is very short! I’ll keep you informed! :)

    Best regards and thanks for the help,
    Rui

  • Rui Gonçalves

    Hi again!

    It is possible to change this code
    try {
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost(url);
    List nameValuePairs = new ArrayList(1);
    //this is where you add your data to the post method
    nameValuePairs.add(new BasicNameValuePair(
    « name », « anthony »));
    httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
    // Execute HTTP Post Request
    HttpResponse response = httpclient.execute(httpPost);
    content = response.getEntity().getContent();
    return content;
    }
    in order to send not pairs of values but a xml string?

    Thanks for the help,
    Best regards!

  • jit

    Hi All,

    I want a peice of code for https communication.
    Objective is sending a xml file to the web server with https.

    Thanks and Regards,
    jit

  • Shawn

    Has anyone figured out how to send xml as the payload in a POST? Nothing I do seems to work. I thin I need to encode the xml somehow but nothing has worked so far. Any ideas?

  • vidya

    hi ,

    how can iuse HttpDelete and also post an xml.

    Please help.
    Thanks

  • Priya

    Thanks for the article… It is very useful!

  • Philip A.

    Let say I have a tabview which every tab I have pre-loaded an URL with webview. On the page of webview, I have a link to download a file. How can I implement this to download that file to the phone?

    Appreciated it!

    Philip

  • Hello Philip !
    To download a file to hte phone (sdcrad) you just have to create a link to that file (http:∕∕host.com∕file.zip for example), in a webview, and when the user will click on the link, android will ask the user where he wants to download it.

  • Philip A.

    Thanks but that is not a solution ;(.

    I’ve tried that but it does nothing!(Like if that’s a large video file, .mp4). Link to an image just open an image, not to save. I want to save :) . I meant the webview in the app somehow does not handle the requests like in its real browser!

    I’m on Droid 2.0.1.

    Philip

  • //I want to save temparary media file to sdcard using following code

    File temp = File.createTempFile(« /sdcard/Sipdroid/mediaplayertmp », « dat »);

    String tempPath = temp.getAbsolutePath();
    FileOutputStream out = new FileOutputStream(temp);
    byte buf[] = new byte[128];
    do {
    int numread = fis.read(buf);
    if (numread <= 0)
    break;
    out.write(buf, 0, numread);
    } while (true);

    MediaPlayer mp = new MediaPlayer();
    mp.setDataSource(tempPath);
    mp.start();

  • Hey..
    Gr8 articles.. helped us a lot :)

    Thank you.

  • saravanan

    Its very useful for me. how to upload .doc file from android to servlet. like resume attachment from android

  • pedro teixeira

    Hello there, how can I read de  »content », how can I make it back to a String for example? My PHP echo’s a link which I’d like the android to use .. can somebody help me please?

  • pedro teixeira

    Hi there again, how can we POST an array, instead of the value pair?

  • pedro teixeira

    Can someone help me with this? To make the « Second Method : getting an input stream given a simple url from Android using HttpClient » able to send also an Array of strings to receive later in PHP instead of being limited to a BasicNamePair ?

    Thank you…

    Any help is REALLY WELCOME with this :/

  • Ritesh Sahoo

    Hi, I am having issues as to how i can pars and extract the XML contnet and attachment from an Httpurlconnection. Please help . Sample source code will be great help.

    Thanks in advance

  • Ricos

    This is a great article.
    But I have a question.
    If HTTP connection was disconnected while receiving the response via InputStream, could I detect this failour?
    I tested it on emulator, but no any exception is occurred in this case.

    Best Regards.
    Ricos.

  • Chethan

    Brilliant article……Made my life easy…thanks

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">