396

I have searched everywhere but I couldn't find my answer, is there a way to make a simple HTTP request? I want to request a PHP page / script on one of my websites but I don't want to show the webpage.

If possible I even want to do it in the background (in a BroadcastReceiver)

aminography
  • 21,986
  • 13
  • 70
  • 74
Mats Hofman
  • 7,060
  • 6
  • 33
  • 48
  • Related: [Download a resource, and show a progress dialog](http://stackoverflow.com/questions/3028306/download-a-file-with-android-and-showing-the-progress-in-a-progressdialog/3028660#3028660) – rds Jun 11 '14 at 08:35
  • This is also related: https://stackoverflow.com/q/46177133/8583692 – Mahozad Dec 31 '21 at 19:15

12 Answers12

505

UPDATE

This is a very old answer. I definitely won't recommend Apache's client anymore. Instead use either:

Original Answer

First of all, request a permission to access network, add following to your manifest:

<uses-permission android:name="android.permission.INTERNET" />

Then the easiest way is to use Apache http client bundled with Android:

    HttpClient httpclient = new DefaultHttpClient();
    HttpResponse response = httpclient.execute(new HttpGet(URL));
    StatusLine statusLine = response.getStatusLine();
    if(statusLine.getStatusCode() == HttpStatus.SC_OK){
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        response.getEntity().writeTo(out);
        String responseString = out.toString();
        out.close();
        //..more logic
    } else{
        //Closes the connection.
        response.getEntity().getContent().close();
        throw new IOException(statusLine.getReasonPhrase());
    }

If you want it to run on separate thread I'd recommend extending AsyncTask:

class RequestTask extends AsyncTask<String, String, String>{

    @Override
    protected String doInBackground(String... uri) {
        HttpClient httpclient = new DefaultHttpClient();
        HttpResponse response;
        String responseString = null;
        try {
            response = httpclient.execute(new HttpGet(uri[0]));
            StatusLine statusLine = response.getStatusLine();
            if(statusLine.getStatusCode() == HttpStatus.SC_OK){
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                response.getEntity().writeTo(out);
                responseString = out.toString();
                out.close();
            } else{
                //Closes the connection.
                response.getEntity().getContent().close();
                throw new IOException(statusLine.getReasonPhrase());
            }
        } catch (ClientProtocolException e) {
            //TODO Handle problems..
        } catch (IOException e) {
            //TODO Handle problems..
        }
        return responseString;
    }
    
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        //Do anything with response..
    }
}

You then can make a request by:

   new RequestTask().execute("http://stackoverflow.com");
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Konstantin Burov
  • 68,980
  • 16
  • 115
  • 93
  • Does this create a thread to make the request or does it block? – fredley Aug 17 '10 at 19:12
  • See the update. AsyncTask is the best way to deal with background work on Android. Here is a good tutorial http://www.screaming-penguin.com/node/7746 – Konstantin Burov Aug 17 '10 at 19:24
  • 11
    Here is an article from the official android developer blog on AsyncTask: http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html – Austyn Mahoney Aug 17 '10 at 21:44
  • 78
    for gingerbread or greater its actually advised to use HttpURLConnection over the apache library, see http://android-developers.blogspot.com/2011/09/androids-http-clients.html . Its less taxing on the battery and has better performance – Marty Dec 05 '11 at 21:54
  • 8
    responseString = out.toString() needs to be before the out.close() call. Actually, you should probably have the out.close() in a finally block. But overall, very helpful answer (+1), thanks! – dcp May 01 '12 at 15:34
  • 1
    It is easier to just use a BasicResponseHandler than to read the OutputStream manually. – Thomas Dignan Jun 30 '12 at 19:42
  • 9
    As of Honeycomb (SDK 11) the asynchronous approach is the way to go. A [NetworkOnMainThreadException](http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html) gets thrown when you try to run an HTTP request from the main thread. – geaw35 Aug 26 '12 at 21:15
  • 2
    This answer is quite excellent. But I would advise not to use AsyncTasks for Networking. They can create memory leaks very easily (and actually the provided example does leak), and don't provide all features one can expect for network requests. Consider using RoboSpice for this kind of background tasks : https://github.com/octo-online/robospice – Snicolas Nov 09 '12 at 12:59
  • What's the license of this stuff ? – Paweł Brewczynski Jan 10 '14 at 00:03
  • OnPreExecute method of AsycTask is also very useful to show the progress bar: http://developer.android.com/reference/android/os/AsyncTask.html#onPreExecute() – Adil Malik Aug 20 '14 at 13:17
  • I'm facing a weird issue making http request from. When internet connection is slow for example 2g/3g in my MySql table an empty row gets inserted. Also i'm using a free server. but on wifi this problem doesn't occured! Do you have any idea? – Muhammad Babar Nov 22 '14 at 13:08
  • I also have username and password to authenticate. How to do it using http call? – Kaveesh Kanwal Apr 26 '15 at 17:35
  • Can i do it with https url? – Iman Marashi May 02 '15 at 23:53
  • 1
    HTTPClient is depricated. So not used anymore. – Rahul Raina Mar 29 '16 at 19:23
  • If you wanna make a simple HTTP request HttpUrlConnection is OK. But I strongly recommend using OkHttp for more complicated stuff. – Javid Aug 15 '16 at 10:08
  • HttpClient is not supported any more in sdk 23. You have to use URLConnection or downgrade to sdk 22 (compile 'com.android.support:appcompat-v7:22.2.0') https://stackoverflow.com/questions/32153318/httpclient-wont-import-in-android-studio – M at Nov 21 '17 at 19:23
  • i like answers like this, imagine this was posted almost 12 years ago – Vlad May 05 '22 at 17:00
68

unless you have an explicit reason to choose the Apache HttpClient, you should prefer java.net.URLConnection. you can find plenty of examples of how to use it on the web.

we've also improved the Android documentation since your original post: http://developer.android.com/reference/java/net/HttpURLConnection.html

and we've talked about the trade-offs on the official blog: http://android-developers.blogspot.com/2011/09/androids-http-clients.html

Elliott Hughes
  • 4,595
  • 2
  • 23
  • 21
  • 14
    Why is using Apache HttpClient not recommended? – Ted Oct 26 '11 at 20:09
  • 4
    A co-conspirator of mine went into this in great detail on the official blog: http://android-developers.blogspot.com/2011/09/androids-http-clients.html – Elliott Hughes Jan 22 '12 at 23:00
  • @ElliottHughes : I agree 100%. There's no denying that Apache httpclient offers easy methods and a more abstracted view of protocol, but java's native urlconnection is in no way less useful. With a bit of hands-on, its as easy to use as httpclient, and is way more portable – Nitin Bansal Aug 08 '12 at 20:19
  • 1
    Actually if u take a look at the video Google I/O 2010 - Android REST client applications(https://www.youtube.com/watch?v=xHXn3Kg2IQE 57min21sec) you would see that Apache HttpClient it is the most recommended one. I quote Virgil Dobjanschi(a software engineer on google that works on Android Application Group) "I would simply advise that you use the HTTP Apache client, because it has a more robust implementation.The URL connection type of HTTP transaction is not the most efficient implementation.And the way it terminates connections sometimes can have an adverse effect on the network." – Alan May 14 '14 at 17:51
50

Note: The Apache HTTP Client bundled with Android is now deprecated in favor of HttpURLConnection. Please see the Android Developers Blog for more details.

Add <uses-permission android:name="android.permission.INTERNET" /> to your manifest.

You would then retrieve a web page like so:

URL url = new URL("http://www.android.com/");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
     readStream(in);
}
finally {
     urlConnection.disconnect();
}

I also suggest running it on a separate thread:

class RequestTask extends AsyncTask<String, String, String>{

@Override
protected String doInBackground(String... uri) {
    String responseString = null;
    try {
        URL url = new URL(myurl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        if(conn.getResponseCode() == HttpsURLConnection.HTTP_OK){
            // Do normal input or output stream reading
        }
        else {
            response = "FAILED"; // See documentation for more info on response handling
        }
    } catch (ClientProtocolException e) {
        //TODO Handle problems..
    } catch (IOException e) {
        //TODO Handle problems..
    }
    return responseString;
}

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);
    //Do anything with response..
}
}

See the documentation for more information on response handling and POST requests.

Eugene K
  • 3,381
  • 2
  • 23
  • 36
Kevin Cronly
  • 1,388
  • 1
  • 13
  • 18
  • 1
    @Semmix How so? The question asked for "a simple HTTP" request, and my code does exactly that. – Kevin Cronly Jan 05 '16 at 19:12
  • 3
    I get that your first code block is copy pasted from Android docs, but man is that sample/doc garbage. `readStream` isn't even defined. – Eugene K Mar 01 '18 at 17:19
  • @EugeneK They are, but this is probably the simplest way to answer this question. Doing an HTTP Request properly in Android would involve explaining Retrofit, and OkHttp. I think that would confuse beginners more than just handing out a snippet that will technically make a simple HTTP request, even if it's constructed poorly. – Kevin Cronly Mar 02 '18 at 17:37
  • The URL constructor throws a malformed exception and should be wrapped in the try catch block. – stebak May 16 '22 at 18:44
15

The most simple way is using the Android lib called Volley

Volley offers the following benefits:

Automatic scheduling of network requests. Multiple concurrent network connections. Transparent disk and memory response caching with standard HTTP cache coherence. Support for request prioritization. Cancellation request API. You can cancel a single request, or you can set blocks or scopes of requests to cancel. Ease of customization, for example, for retry and backoff. Strong ordering that makes it easy to correctly populate your UI with data fetched asynchronously from the network. Debugging and tracing tools.

You can send a http/https request as simple as this:

        // Instantiate the RequestQueue.
        RequestQueue queue = Volley.newRequestQueue(this);
        String url ="http://www.yourapi.com";
        JsonObjectRequest request = new JsonObjectRequest(url, null,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    if (null != response) {
                         try {
                             //handle your response
                         } catch (JSONException e) {
                             e.printStackTrace();
                         }
                    }
                }
            }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });
        queue.add(request);

In this case, you needn't consider "running in the background" or "using cache" yourself as all of these has already been done by Volley.

Shao Wenbin
  • 531
  • 5
  • 3
11

Use Volley as suggested above. Add following into build.gradle (Module: app)

implementation 'com.android.volley:volley:1.1.1'

Add following into AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET" />

And add following to you Activity code:

public void httpCall(String url) {

    RequestQueue queue = Volley.newRequestQueue(this);

    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    // enjoy your response
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    // enjoy your error status
                }
    });

    queue.add(stringRequest);
}

It replaces http client and it is very simple.

Jarda Pavlíček
  • 1,636
  • 17
  • 16
6
private String getToServer(String service) throws IOException {
    HttpGet httpget = new HttpGet(service);
    ResponseHandler<String> responseHandler = new BasicResponseHandler();
    return new DefaultHttpClient().execute(httpget, responseHandler);

}

Regards

Gabriel Gómez
  • 311
  • 2
  • 10
6

As none of the answers described a way to perform requests with OkHttp, which is very popular http client nowadays for Android and Java in general, I am going to provide a simple example:

//get an instance of the client
OkHttpClient client = new OkHttpClient();

//add parameters
HttpUrl.Builder urlBuilder = HttpUrl.parse("https://www.example.com").newBuilder();
urlBuilder.addQueryParameter("query", "stack-overflow");


String url = urlBuilder.build().toString();

//build the request
Request request = new Request.Builder().url(url).build();

//execute
Response response = client.newCall(request).execute();

The clear advantage of this library is that it abstracts us from some low level details, providing more friendly and secure ways to interact with them. The syntax is also simplified and permits to write nice code.

NiVeR
  • 9,644
  • 4
  • 30
  • 35
5

With a thread:

private class LoadingThread extends Thread {
    Handler handler;

    LoadingThread(Handler h) {
        handler = h;
    }
    @Override
    public void run() {
        Message m = handler.obtainMessage();
        try {
            BufferedReader in = 
                new BufferedReader(new InputStreamReader(url.openStream()));
            String page = "";
            String inLine;

            while ((inLine = in.readLine()) != null) {
                page += inLine;
            }

            in.close();
            Bundle b = new Bundle();
            b.putString("result", page);
            m.setData(b);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        handler.sendMessage(m);
    }
}
Troy Alford
  • 26,660
  • 10
  • 64
  • 82
fredley
  • 32,953
  • 42
  • 145
  • 236
4

I made this for a webservice to requerst on URL, using a Gson lib:

Client:

public EstabelecimentoList getListaEstabelecimentoPorPromocao(){

        EstabelecimentoList estabelecimentoList  = new EstabelecimentoList();
        try{
            URL url = new URL("http://" +  Conexao.getSERVIDOR()+ "/cardapio.online/rest/recursos/busca_estabelecimento_promocao_android");
            HttpURLConnection con = (HttpURLConnection) url.openConnection();

            if (con.getResponseCode() != 200) {
                    throw new RuntimeException("HTTP error code : "+ con.getResponseCode());
            }

            BufferedReader br = new BufferedReader(new InputStreamReader((con.getInputStream())));
            estabelecimentoList = new Gson().fromJson(br, EstabelecimentoList.class);
            con.disconnect();

        } catch (IOException e) {
            e.printStackTrace();
        }
        return estabelecimentoList;
}
Deividson Calixto
  • 350
  • 1
  • 4
  • 11
4

Look at this awesome new library which is available via gradle :)

build.gradle: compile 'com.apptakk.http_request:http-request:0.1.2'

Usage:

new HttpRequestTask(
    new HttpRequest("http://httpbin.org/post", HttpRequest.POST, "{ \"some\": \"data\" }"),
    new HttpRequest.Handler() {
      @Override
      public void response(HttpResponse response) {
        if (response.code == 200) {
          Log.d(this.getClass().toString(), "Request successful!");
        } else {
          Log.e(this.getClass().toString(), "Request unsuccessful: " + response);
        }
      }
    }).execute();

https://github.com/erf/http-request

electronix384128
  • 6,625
  • 11
  • 45
  • 67
2

This is the new code for HTTP Get/POST request in android. HTTPClient is depricated and may not be available as it was in my case.

Firstly add the two dependencies in build.gradle:

compile 'org.apache.httpcomponents:httpcore:4.4.1'
compile 'org.apache.httpcomponents:httpclient:4.5'

Then write this code in ASyncTask in doBackground method.

 URL url = new URL("http://localhost:8080/web/get?key=value");
 HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
 urlConnection.setRequestMethod("GET");
 int statusCode = urlConnection.getResponseCode();
 if (statusCode ==  200) {
      InputStream it = new BufferedInputStream(urlConnection.getInputStream());
      InputStreamReader read = new InputStreamReader(it);
      BufferedReader buff = new BufferedReader(read);
      StringBuilder dta = new StringBuilder();
      String chunks ;
      while((chunks = buff.readLine()) != null)
      {
         dta.append(chunks);
      }
 }
 else
 {
     //Handle else
 }
Rahul Raina
  • 3,322
  • 25
  • 30
  • The code might get deprecated and apache is no more supported in Android Platform API 28. In that case, you can enable apache legacy property in Manifest or module level Gradle file. However, it is recommended to use OKHttp, Volley or Retrofit networking library. – Rahul Raina Jun 02 '19 at 12:46
1

For me, the easiest way is using library called Retrofit2

We just need to create an Interface that contain our request method, parameters, and also we can make custom header for each request :

    public interface MyService {

      @GET("users/{user}/repos")
      Call<List<Repo>> listRepos(@Path("user") String user);

      @GET("user")
      Call<UserDetails> getUserDetails(@Header("Authorization") String   credentials);

      @POST("users/new")
      Call<User> createUser(@Body User user);

      @FormUrlEncoded
      @POST("user/edit")
      Call<User> updateUser(@Field("first_name") String first, 
                            @Field("last_name") String last);

      @Multipart
      @PUT("user/photo")
      Call<User> updateUser(@Part("photo") RequestBody photo, 
                            @Part("description") RequestBody description);

      @Headers({
        "Accept: application/vnd.github.v3.full+json",
        "User-Agent: Retrofit-Sample-App"
      })
      @GET("users/{username}")
      Call<User> getUser(@Path("username") String username);    

    }

And the best is, we can do it asynchronously easily using enqueue method

Faruk
  • 5,438
  • 3
  • 30
  • 46