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 !


[...] and I still can’t get a valid response. In this blogpost http://blog.dahanne.net/2009/08/16/h…-from-android/ the guy shows a few ways of doing an Http request I tried the 1st one and the final string I get [...]
Hi Anthony,
I tryed both methods to get http resources described above, very similar to other examples I found on the web, but I can’t manage them to work.
I always get the following exception:
INFO/System.out(278): Excpetion = java.net.UnknownHostException: oxavi.com
It seems it’s the same problem described by Bipin Vayalu but I can’t see any reply on this.
I added to my AndroidManifest file the user permission:
android:name= »android.permission.INTERNET »
but it didn’t solve the problem.
I tryed both on my HW(HTC WildFire android 2.2.1) and on the AVDs with no results.
Do I miss some important configuration for the internet access ?
Do you think it is possible to handle the http connection directly into the event handler or I need to create a separate thread ?
=============== This is the code =====================
final Button buttonSearch = (Button) findViewById(R.id.search);
buttonSearch.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event)
{
if(event.getAction() == android.view.MotionEvent.ACTION_DOWN){
try {
System.out.println(« \n\n BUTTON PUSHED\n\n »);
InputStream content = null;
HttpGet httpGet = new HttpGet(« http://oxavi.com/price.php »);
HttpClient httpclient = new DefaultHttpClient();
// Execute HTTP Get Request
HttpResponse response = httpclient.execute(httpGet);
content = response.getEntity().getContent();
BufferedReader rd = new BufferedReader(new InputStreamReader(content), 4096);
String line;
StringBuilder sb = new StringBuilder();
while ((line = rd.readLine()) != null)
{ sb.append(line);}
rd.close();
String contentOfMyInputStream = sb.toString();
System.out.println(contentOfMyInputStream);
} catch (Exception e){
System.out.println(« Excpetion = » + e);}
}
return true;
}
});
===================================================
Many thanks in advance.
Andrea
Reading / Sending a cookie along with the requests.can you provide entire code for this i was struggle with this lot. please.
Hi Anthony,
You may find this somehow unrelated to your efforts towards accessing http resources from Android but I will appreciate it if you can provide me with your thoughts regarding to my challenge.
I’m trying to capture some statistics like number of 302′s and 200 Oks or the time it takes for the client to receive the content from the streamer (time it takes from the actual request (URL) to the http client till http client sends the content back to the media player). The cleanest way to do this is to extend HttpClient code. The challenge for me is to know that if the media player (any kind) on Android will use my extended version of HttpClient or not. I will appreciate it if you can help me at least based on your experience what you think about this.
Cheers, STZ
Maybe you could use convertStreamToString to convert the InputStream into a string:
JSONObject jsonResponse = new JSONObject(convertStreamToString(instream));
ByteArrayOutputStream stream_bytes=new ByteArrayOutputStream();
int cnt=0;
byte[] buffer=new byte[512];
while ((cnt=stream_content.read(buffer))!=-1)
{stream_bytes.write(buffer, 0, cnt);
}
String response_text=new String(stream_bytes.toByteArray());
or
BufferedReader br=new BufferedReader(new InputStreamReader(stream_content), 4096);
String line;
StringBuilder sb=new StringBuilder();
while ((line=br.readLine())!=null)
{sb.append(line);
}
String contentOfMyInputStream=sb.toString();
hi Andrea
i have faced such problem of unknown host .
check your internet connection ..
or if you are testing with emulator so set dns server for emulator like
start cmd
change directory to android-sdk/tools
and
fire this command
emulator.exe -avd [your avd name] -dns-server 192.168.1.1
thats it.
run your app…
hope this will help you
I think the best way how to get String content from InputStrem is:
Note: Don’t forget on right charset, see second parameter in InputStreamReader constructor.