Make an HTTP request with android
Asked Answered
B

12

402

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)

Baseboard answered 17/8, 2010 at 19:0 Comment(2)
Related: Download a resource, and show a progress dialogBeluga
This is also related: https://mcmap.net/q/87689/-http-request-in-android-with-kotlin/8583692Carrillo
B
507

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");
Bin answered 17/8, 2010 at 19:11 Comment(14)
Does this create a thread to make the request or does it block?Matisse
See the update. AsyncTask is the best way to deal with background work on Android. Here is a good tutorial screaming-penguin.com/node/7746Bin
Here is an article from the official android developer blog on AsyncTask: android-developers.blogspot.com/2010/07/…Bili
for gingerbread or greater its actually advised to use HttpURLConnection over the apache library, see android-developers.blogspot.com/2011/09/… . Its less taxing on the battery and has better performanceTravail
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!Lissome
It is easier to just use a BasicResponseHandler than to read the OutputStream manually.Ladyinwaiting
As of Honeycomb (SDK 11) the asynchronous approach is the way to go. A NetworkOnMainThreadException gets thrown when you try to run an HTTP request from the main thread.Shuman
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 : github.com/octo-online/robospiceEndure
What's the license of this stuff ?Matriarchy
OnPreExecute method of AsycTask is also very useful to show the progress bar: developer.android.com/reference/android/os/…Lentic
HTTPClient is depricated. So not used anymore.Earthshine
If you wanna make a simple HTTP request HttpUrlConnection is OK. But I strongly recommend using OkHttp for more complicated stuff.Humphries
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') #32153818Mcrae
i like answers like this, imagine this was posted almost 12 years agoSalomie
A
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

Automaton answered 18/8, 2010 at 5:55 Comment(4)
Why is using Apache HttpClient not recommended?Argive
A co-conspirator of mine went into this in great detail on the official blog: android-developers.blogspot.com/2011/09/…Automaton
@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 portableTrivial
Actually if u take a look at the video Google I/O 2010 - Android REST client applications(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."Ferrer
I
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.

Ivyiwis answered 30/6, 2015 at 20:54 Comment(4)
@Semmix How so? The question asked for "a simple HTTP" request, and my code does exactly that.Ivyiwis
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.Unbridled
@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.Ivyiwis
The URL constructor throws a malformed exception and should be wrapped in the try catch block.Creel
N
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.

Nilla answered 27/5, 2017 at 5:8 Comment(0)
M
12

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.

Mcglynn answered 28/9, 2019 at 9:22 Comment(3)
But this request is synchronous, yes? How to execute it asynchronous?Vitality
Imho it is asynchronous. Your code continues after queue.add(...Ose
It is async. And I have the opposite question: how to make a blocking HTTP(S) request? Short of organizing a busy loop after queue.add(), that is.Cosmetic
F
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

Felafel answered 30/7, 2014 at 18:7 Comment(0)
M
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.

Mameluke answered 11/6, 2018 at 18:59 Comment(0)
M
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);
    }
}
Matisse answered 17/8, 2010 at 19:3 Comment(0)
B
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;
}
Bombardier answered 5/6, 2014 at 13:51 Comment(0)
I
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

Icebox answered 4/5, 2016 at 0:0 Comment(0)
E
2

This is the new code for HTTP Get/POST request in android. HTTPClient is deprecated 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
 }
Earthshine answered 29/3, 2016 at 19:34 Comment(1)
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.Earthshine
F
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

Fleeting answered 2/4, 2017 at 20:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.