2010-08-17 20 views
308

He buscado en todas partes pero no he podido encontrar mi respuesta, ¿hay alguna manera de hacer una simple solicitud HTTP? Deseo solicitar una página/script PHP en uno de mis sitios web, pero no quiero mostrar la página web.Hacer una solicitud HTTP con android

Si es posible incluso que quiero hacer en el fondo (en un BroadcastReceiver)

+0

Relacionados: [Descargar un recurso y mostrar un diálogo de progreso] (http://stackoverflow.com/questions/3028306/download-a-file-with-android-and-showing-the-progress-in-a -progressdialog/3028660 # 3028660) – rds

Respuesta

438

ACTUALIZACIÓN

Ésta es una respuesta muy antigua. Definitivamente ya no recomendaré el cliente de Apache. Considere usar HttpUrlConnection o OkHttp en su lugar.

ACTUALIZACIÓN

En primer lugar, solicitar una autorización de acceso a la red, añadir siguiente a su manifiesta:

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

A continuación, la forma más fácil es usar cliente HTTP Apache incluido con 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()); 
    } 

Si desea que se ejecute el hilo separado le recomiendo que se extiende 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.. 
    } 
} 

A continuación, puede hacer una solicitud por:

new RequestTask().execute("http://stackoverflow.com"); 
+0

¿Esto crea un hilo para hacer la solicitud o bloquea? – fredley

+0

Ver la actualización. AsyncTask es la mejor manera de lidiar con el trabajo de fondo en Android. Aquí hay un buen tutorial http://www.screaming-penguin.com/node/7746 –

+10

Aquí hay un artículo del blog oficial de desarrolladores de Android en AsyncTask: http://android-developers.blogspot.com/2010/07/ multithreading-for-performance.html –

2

Con un hilo:

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

a menos que tenga una razón explícita para elegir el HttpClient Apache, se debe preferir java.net.URLConnection. puedes encontrar muchos ejemplos de cómo usarlo en la web.

También hemos mejorado la documentación de Android desde su puesto original: http://developer.android.com/reference/java/net/HttpURLConnection.html

y ya hemos hablado de las ventajas y desventajas en el blog oficial: http://android-developers.blogspot.com/2011/09/androids-http-clients.html

+13

¿Por qué no se recomienda utilizar Apache HttpClient? – Ted

+4

Un co-conspirador mío entró en esto en gran detalle en el blog oficial: http://android-developers.blogspot.com/2011/09/androids-http-clients.html –

+0

@ElliottHughes: Estoy de acuerdo 100%. No se puede negar que Apache httpclient ofrece métodos sencillos y una vista del protocolo más abstracta, pero la conexión de url nativa de Java no es de ninguna manera menos útil. Con un poco de práctica, es tan fácil de usar como httpclient, y es mucho más portátil –

1

Hice esto para un servicio web a requerst en la URL, utilizando un lib Gson:

Cliente:

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; 
} 
4
private String getToServer(String service) throws IOException { 
    HttpGet httpget = new HttpGet(service); 
    ResponseHandler<String> responseHandler = new BasicResponseHandler(); 
    return new DefaultHttpClient().execute(httpget, responseHandler); 

} 

Saludos

37

Nota: Apache HTTP Client incluido con Android ahora está en desuso en favor de HttpURLConnection. Por favor, consulte los desarrolladores de Android Blog para más detalles.

Agregue <uses-permission android:name="android.permission.INTERNET" /> a su manifiesto.

A continuación, recuperar una página web de esta manera:

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

también sugieren ejecutarlo en un hilo separado:

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

Véase el documentation para más información sobre el manejo de respuestas y peticiones POST .

+1

@Semmix ¿Cómo? La pregunta solicitó una solicitud de "HTTP simple" y mi código hace exactamente eso. –

+0

Me sale que el primer bloque de código es una copia pegada de los documentos de Android, pero el hombre es esa basura de muestra/doc. 'readStream' ni siquiera está definido. –

+0

@EugeneK Lo son, pero esta es probablemente la forma más sencilla de responder a esta pregunta.Hacer una Solicitud HTTP correctamente en Android implicaría explicar Retrofit y OkHttp. Creo que eso podría confundir a los principiantes más que simplemente entregando un fragmento que técnicamente hará una solicitud HTTP simple, incluso si está mal construida. –

1

Este es el nuevo código para la solicitud HTTP Get/POST en android. HTTPClient está privado y puede no estar disponible como lo fue en mi caso.

añadir primer lugar las dos dependencias en build.gradle:

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

Luego escribe este código en ASyncTask en doBackground método.

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

Mira esta nueva biblioteca impresionante que está disponible a través de Gradle :)

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

Uso:

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

0

Para mí, la forma más fácil es usar la biblioteca llamada Retrofit2

Sólo tenemos que crear una interfaz que contiene nuestra forma de solicitud, parámetros, y también podemos hacer cabecera personalizada para cada solicitud:

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

    } 

Y lo mejor es que podemos hacerlo de forma asíncrona fácilmente usando método de puesta en cola

4

la forma más sencilla utiliza el lib Android llamada Volley

voleo ofrece los siguientes beneficios:

Programación automática de solicitudes de red. Red simultánea múltiple conexiones. Almacenamiento en caché de respuesta de memoria y disco transparente con coherencia de caché HTTP estándar. Soporte para la priorización de solicitudes. API de solicitud de cancelación. Puede cancelar una sola solicitud, o puede establecer bloques o ámbitos de solicitudes para cancelar. Facilidad de personalización, para el ejemplo , para el reintento y el apagado. Un orden fuerte que hace que sea fácil de llenar correctamente su UI con los datos obtenidos de forma asincrónica desde la red . Herramientas de depuración y rastreo.

Puede enviar una solicitud HTTP/HTTPS tan simple como esto:

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

En este caso, no es necesario considerar "que se ejecuta en segundo plano" o "el uso de caché" a sí mismo como todos esto ya lo ha hecho Volley.

Cuestiones relacionadas