Buat permintaan HTTP dengan android

352

Saya telah mencari di mana-mana tetapi saya tidak dapat menemukan jawaban saya, apakah ada cara untuk membuat permintaan HTTP sederhana? Saya ingin meminta halaman / skrip PHP di salah satu situs web saya, tetapi saya tidak ingin menampilkan halaman web.

Jika mungkin saya bahkan ingin melakukannya di latar belakang (dalam BroadcastReceiver)

Mats Hofman
sumber

Jawaban:

477

MEMPERBARUI

Ini jawaban yang sangat lama. Saya pasti tidak akan merekomendasikan klien Apache lagi. Alih-alih gunakan:

Jawaban Asli

Pertama-tama, minta izin untuk mengakses jaringan, tambahkan berikut ini ke manifes Anda:

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

Maka cara termudah adalah dengan menggunakan klien Apache http yang dibundel dengan 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());
    }

Jika Anda ingin menjalankannya di utas terpisah, saya sarankan memperluas 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..
    }
}

Anda kemudian dapat mengajukan permintaan dengan:

   new RequestTask().execute("http://stackoverflow.com");
Konstantin Burov
sumber
11
Berikut adalah artikel dari blog resmi pengembang android di AsyncTask: android-developers.blogspot.com/2010/07/...
Austyn Mahoney
77
untuk roti jahe atau lebih besar ini sebenarnya disarankan untuk menggunakan HttpURLConnection melalui perpustakaan apache, lihat android-developers.blogspot.com/2011/09/… . Yang kurang melelahkan pada baterai dan memiliki kinerja yang lebih baik
Marty
8
responseString = out.toString () harus sebelum panggilan out.close (). Sebenarnya, Anda mungkin harus memiliki out.close () di blok akhirnya. Namun secara keseluruhan, jawaban yang sangat membantu (+1), terima kasih!
dcp
9
Pada Honeycomb (SDK 11) pendekatan asinkron adalah cara untuk pergi. Sebuah NetworkOnMainThreadException akan dilemparkan ketika Anda mencoba untuk menjalankan permintaan HTTP dari thread utama.
msrxthr
2
Jawaban ini sangat bagus. Tapi saya akan menyarankan untuk tidak menggunakan AsyncTasks untuk Networking. Mereka dapat membuat kebocoran memori dengan sangat mudah (dan sebenarnya contoh yang diberikan tidak bocor), dan tidak menyediakan semua fitur yang dapat diharapkan untuk permintaan jaringan. Pertimbangkan untuk menggunakan RoboSpice untuk tugas-tugas latar belakang seperti ini: github.com/octo-online/robospice
Snicolas
67

kecuali Anda memiliki alasan eksplisit untuk memilih Apache HttpClient, Anda sebaiknya memilih java.net.URLConnection. Anda dapat menemukan banyak contoh cara menggunakannya di web.

kami juga telah menyempurnakan dokumentasi Android sejak posting asli Anda: http://developer.android.com/reference/java/net/HttpURLConnection.html

dan kami telah berbicara tentang pertukaran di blog resmi: http://android-developers.blogspot.com/2011/09/androids-http-clients.html

Elliott Hughes
sumber
13
Mengapa menggunakan Apache HttpClient tidak disarankan?
Ted
4
Seorang rekan konspirator saya membahas hal ini dengan sangat terperinci di blog resmi: android-developers.blogspot.com/2011/09/…
Elliott Hughes
@ElliottHughes: Saya setuju 100%. Tidak dapat disangkal bahwa Apache httpclient menawarkan metode yang mudah dan pandangan protokol yang lebih abstrak, tetapi koneksi asli java sama sekali tidak berguna. Dengan sedikit hands-on, mudah digunakan sebagai httpclient, dan jauh lebih portabel
Nitin Bansal
1
Sebenarnya jika Anda melihat video Google I / O 2010 - aplikasi klien Android REST ( youtube.com/watch?v=xHXn3Kg2IQE 57min21sec) Anda akan melihat bahwa Apache HttpClient itu adalah yang paling direkomendasikan. Saya mengutip Virgil Dobjanschi (seorang insinyur perangkat lunak di google yang bekerja di Android Application Group) "Saya hanya akan menyarankan agar Anda menggunakan klien HTTP Apache, karena ia memiliki implementasi yang lebih kuat. Jenis koneksi URL dari transaksi HTTP bukan yang paling efisien implementasi. Dan cara itu mengakhiri koneksi kadang-kadang dapat memiliki efek buruk pada jaringan. "
Alan
46

Catatan: Klien HTTP Apache yang dibundel dengan Android sekarang tidak digunakan lagi karena mendukung HttpURLConnection . Silakan lihat Blog Pengembang Android untuk lebih jelasnya.

Tambahkan <uses-permission android:name="android.permission.INTERNET" />ke manifes Anda.

Anda kemudian akan mengambil halaman web seperti itu:

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

Saya juga menyarankan menjalankannya di utas terpisah:

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

Lihat dokumentasi untuk informasi lebih lanjut tentang penanganan respons dan permintaan POST.

kevinc
sumber
1
@Emmix Bagaimana bisa begitu? Pertanyaannya menanyakan permintaan "HTTP sederhana", dan kode saya melakukan hal itu.
kevinc
1
Saya mendapatkan bahwa blok kode pertama Anda disalin dari Android docs, tetapi man adalah sampel / dokumen sampah. readStreambahkan tidak didefinisikan.
Eugene K
@EugeneK Ya, tapi ini mungkin cara paling sederhana untuk menjawab pertanyaan ini. Melakukan Permintaan HTTP dengan benar di Android akan melibatkan menjelaskan Retrofit, dan OkHttp. Saya pikir itu akan membingungkan pemula lebih dari sekedar membagikan cuplikan yang secara teknis akan membuat permintaan HTTP sederhana, bahkan jika itu dibangun dengan buruk.
kevinc
12

Cara paling sederhana adalah menggunakan lib Android yang disebut Volley

Volley menawarkan manfaat berikut:

Penjadwalan otomatis permintaan jaringan. Beberapa koneksi jaringan bersamaan . Disk transparan dan caching respons memori dengan koherensi cache HTTP standar. Dukungan untuk prioritas permintaan. API permintaan pembatalan. Anda dapat membatalkan satu permintaan, atau Anda dapat mengatur blok atau cakupan permintaan untuk membatalkan. Kemudahan kustomisasi, misalnya, untuk mencoba ulang dan mundur. Pemesanan kuat yang memudahkan untuk mengisi UI Anda dengan benar dengan data diambil secara tidak sinkron dari jaringan. Alat debugging dan penelusuran.

Anda dapat mengirim permintaan http / https sesederhana ini:

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

Dalam hal ini, Anda tidak perlu mempertimbangkan "menjalankan di latar belakang" atau "menggunakan cache" sendiri karena semua ini sudah dilakukan oleh Volley.

Shao Wenbin
sumber
6
private String getToServer(String service) throws IOException {
    HttpGet httpget = new HttpGet(service);
    ResponseHandler<String> responseHandler = new BasicResponseHandler();
    return new DefaultHttpClient().execute(httpget, responseHandler);

}

Salam

Gabriel Gómez
sumber
4

Dengan utas:

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);
    }
}
fredley
sumber
4

Saya membuat ini untuk layanan web untuk meminta kembali pada URL, menggunakan lib Gson:

Klien:

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
sumber
4

Lihatlah perpustakaan baru yang mengagumkan ini yang tersedia melalui gradle :)

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

Pemakaian:

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
sumber
1
Sepertinya setiap perpustakaan lainnya ...
Nick Gallimore
3

Gunakan Volley seperti yang disarankan di atas. Tambahkan yang berikut ke build.gradle (Modul: aplikasi)

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

Tambahkan yang berikut ke AndroidManifest.xml:

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

Dan tambahkan kode aktivitas berikut kepada Anda:

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

Ini menggantikan klien http dan sangat sederhana.

Jarda Pavlíček
sumber
2

Ini adalah kode baru untuk permintaan HTTP Get / POST di android. HTTPClientdihapus dan mungkin tidak tersedia seperti dalam kasus saya.

Pertama tambahkan dua dependensi di build.gradle:

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

Kemudian tulis kode ini ASyncTaskdalam doBackgroundmetode.

 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
sumber
Kode mungkin menjadi usang dan apache tidak lagi didukung di Android Platform API 28. Dalam hal ini, Anda dapat mengaktifkan properti warisan apache di file Gradle tingkat Manifes atau modul. Namun, disarankan untuk menggunakan perpustakaan jaringan OKHttp, Volley atau Retrofit.
Rahul Raina
1

Bagi saya, cara termudah adalah menggunakan perpustakaan yang disebut Retrofit2

Kami hanya perlu membuat Antarmuka yang berisi metode permintaan kami, parameter, dan kami juga dapat membuat header khusus untuk setiap permintaan:

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

    }

Dan yang terbaik adalah, kita dapat melakukannya dengan mudah secara serempak menggunakan metode enqueue

faruk
sumber
1

Karena tidak ada jawaban yang menjelaskan cara melakukan permintaan dengan OkHttp , yang merupakan klien http yang sangat populer saat ini untuk Android dan Java secara umum, saya akan memberikan contoh sederhana:

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

Keuntungan yang jelas dari perpustakaan ini adalah bahwa perpustakaan ini mengabstraksi kita dari beberapa detail tingkat rendah, menyediakan cara yang lebih ramah dan aman untuk berinteraksi dengan mereka. Sintaksnya juga disederhanakan dan memungkinkan untuk menulis kode yang bagus.

NiVeR
sumber