Fare una richiesta HTTP con Android
-
29-09-2019 - |
Domanda
Ho cercato dappertutto, ma non riuscivo a trovare la mia risposta, c'è un modo per fare una semplice richiesta HTTP? Voglio chiedere una pagina / script PHP su uno dei miei sito web, ma io non voglio mostrare la pagina web.
Se possibile, ho anche voglia di farlo in background (in un BroadcastReceiver)
Soluzione
UPDATE
Questa è una risposta molto vecchio. Io sicuramente non consigliamo più client di Apache. Invece utilizzare:
risposta originale
Prima di tutto, richiedere un permesso di rete di accesso, aggiungere in seguito al manifestarsi:
<uses-permission android:name="android.permission.INTERNET" />
Quindi il modo più semplice è quello di utilizzare Apache client HTTP in bundle 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());
}
Se si desidera che venga eseguito sul thread separato mi consiglia estendere 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..
}
}
È quindi possibile fare una richiesta da:
new RequestTask().execute("http://stackoverflow.com");
Altri suggerimenti
se non si ha una ragione esplicita per scegliere l'Apache HttpClient, si dovrebbe preferire java.net.URLConnection. si possono trovare un sacco di esempi di come usarlo sul web.
Abbiamo anche migliorato la documentazione Android dal tuo post originale: http: / /developer.android.com/reference/java/net/HttpURLConnection.html
e abbiamo parlato dei compromessi sul blog ufficiale: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
Nota: Il client HTTP Apache in bundle con Android è ora sconsigliato a favore HttpURLConnection . Si prega di consultare la per ulteriori dettagli.
Aggiungi <uses-permission android:name="android.permission.INTERNET" />
al vostro manifesto.
Si potrebbe quindi recuperare una pagina web in questo modo:
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();
}
Ho anche suggerisco di esecuzione su un thread separato:
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..
}
}
Vedere la documentazione per ulteriori informazioni sulla gestione delle risposte e richieste POST .
Il modo più semplice sta usando il lib Android chiamato Volley
Volley offre i seguenti vantaggi:
Programmazione automatica delle richieste di rete. rete simultanee multiple collegamenti . lastra trasparente e la risposta di memoria cache con standard di coerenza della cache HTTP. Sostegno alla richiesta di priorità. richiesta di annullamento API. È possibile annullare una singola richiesta, o si può blocchi fissi o ambiti di richieste per annullare. Facilità di personalizzazione, per esempio, per tentativi e backoff. Forte ordinamento che lo rende facile correttamente popolano l'interfaccia utente con i dati recuperati in modo asincrono dal Rete. Debugging e strumenti di tracciamento.
È possibile inviare una richiesta HTTP / HTTPS semplice come questo:
// 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 questo caso, non è necessario prendere in considerazione "in esecuzione in background" o "usando cache", dato che tutti questi è già stato fatto da Volley.
private String getToServer(String service) throws IOException {
HttpGet httpget = new HttpGet(service);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
return new DefaultHttpClient().execute(httpget, responseHandler);
}
Saluti
Guardate questa nuova libreria impressionante che è disponibile tramite Gradle:)
build.gradle: compile 'com.apptakk.http_request:http-request:0.1.2'
Utilizzo:
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();
Con un filo:
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);
}
}
Ho fatto questo per un servizio web per richiesta su URL, utilizzando 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;
}
Questo è il nuovo codice per HTTP Get / richiesta POST in Android. HTTPClient
è depricated e non può essere disponibile come è stato nel mio caso.
In primo luogo aggiungere le due dipendenze in build.gradle:
compile 'org.apache.httpcomponents:httpcore:4.4.1'
compile 'org.apache.httpcomponents:httpclient:4.5'
Quindi scrivere questo codice in ASyncTask
nel metodo doBackground
.
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
}
Per quanto mi riguarda, il modo più semplice è utilizzare libreria chiamata Retrofit2
solo bisogno di creare un'interfaccia che contiene il nostro metodo di richiesta, i parametri, e anche noi può fare intestazione personalizzata per ogni richiesta:
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);
}
E il meglio è, siamo in grado di farlo in modo asincrono con facilità utilizzando il metodo Enqueue
Per quanto nessuna delle risposte ha descritto un modo per eseguire le richieste con OkHttp , che è molto popolare http cliente al giorno d'oggi per Android e Java in generale, ho intenzione di fornire un semplice esempio:
//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();
Il chiaro vantaggio di questa libreria è che ci astrae da alcuni dettagli di basso livello, fornendo modi più amichevole e sicuro per interagire con loro. La sintassi è anche semplificata e permette di scrivere codice bello.
Usa Volley come suggerito in precedenza. Aggiungere segue nella build.gradle (modulo: app)
implementation 'com.android.volley:volley:1.1.1'
Aggiungi segue nel AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
E aggiungere seguente a voi il codice di attività:
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);
}
Sostituisce http cliente ed è molto semplice.