Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 86 di 97
  • livello avanzato
Indice lezioni

Android e la rete

Come accedere ai servizi internet, come leggere i contenuti in rete, come trasmettere i contenuti in rete e l'uso del Download Manager.
Come accedere ai servizi internet, come leggere i contenuti in rete, come trasmettere i contenuti in rete e l'uso del Download Manager.
Link copiato negli appunti

La presente lezione su Android, utilizza la libreria HTTPClient per la connessione alla rete. Nonostante questa resti un'ottima soluzione per assolvere tali compiti e sia molto apprezzata tra gli sviluppatori Java, è stata deprecata a partire dalla versione 23 delle API Android. Pertanto, il suo utilizzo resta qui illustrato al solo fine di agevolare il mantenimento di progetti Android esistenti, in considerazione del largo impiego che ne è stato fatto nelle versioni precedenti del sistema.

In un corso Android, che si tratti di tutorial scritti, videocorsi o lezioni frontali, non si può negare che uno dei momenti più attesi dai discenti sia la lezione che riguarda l'accesso alla Rete.
Non è la prima volta che in questa guida si parla di accesso alla Rete. È già successo a proposito della WebView, il controllo che permette di
integrare web app in un'interfaccia utente. Quello che viene presentato in questo capitolo è un discorso più ampio, un insieme di strumenti che permettono
all'applicazione di consultare, scaricare ed inviare dati in Internet.

Prerequisiti

A proposito di connessioni remote, sono due i concetti da tenere a mente, entrambi già incontrati nel corso della guida e fondamentali per evitare errori
ed eccezioni di sicurezza:

  • nel file AndroidManifest.xml va indicata la permission Internet apponendo il seguente nodo: <uses-permission
    android:name="android.permission.INTERNET"/>
    ;
  • l'attività in Rete deve essere eseguita in modalità asincrona, su un thread separato. In questo caso,
    senza scomodare i Service, ci si potrà avvantaggiare della classe AsyncTask, utilizzando tutto il codice che verrà presentato nel metodo doInBackground.

Leggere contenuti in Rete

Per eseguire l'accesso alla Rete, esistono fondamentalmente due modi in Android: usare classi Java standard o librerie esterne incluse nel sistema.

Il tipo di interazione remota più comune è quello via HTTP, il protocollo comunemente usato per la distribuzione dei contenuti Internet. Questo protocollo
può essere trattato con la classe HttpUrlConnection, tipica del mondo Java, o con la libreria HttpClient gestita dalla
fondazione Apache.

Per programmatori Java entrambi i casi sono generalmente piuttosto noti. Ma quale usare? Uno dei due è migliore dell'altro? Entrambe, al giorno d'oggi,
possono considerarsi funzionali. Sicuramente la libreria di Apache è molto estesa e offre tantissime funzionalità ma la classe HttpUrlConnection è più che
sufficiente nella maggior parte dei casi come ad esempio nel normale scaricamento di un file. Quindi, di norma, si può usare la HttpUrlConnection tranne
nei casi in cui servano funzionalità differenti disponibili solo in HttpClient.

Mettiamo a confronto gli utilizzi.

Immaginiamo che all'indirizzo http://www.mioserver.it/storage/file.txt sia disponibile un file di cui si deve fare il download.

Con HttpUrlConnection
si farebbe:

URL url=new URL( "http://www.mioserver.it/storage/file.txt");

recuperando direttamente lo stream ai contenuti:

InputStream is= url.openStream();

oppure passando per la connessione con:

HttpURLConnection conn= (HttpURLConnection) url.openConnection();
InputStream is= conn.getInputStream();

Con HttpClient, in alternativa, si tratta di preparare una request HTTP ed eseguirla ottenendo in cambio una response:

HttpClient request=new DefaultHttpClient();
HttpGet get=new HttpGet("http://www.mioserver.it/storage/file.txt");
HttpResponse response=request.execute(get);
InputStream is=response.getEntity().getContent()

In tutti i casi, si
è
ottenuto un riferimento ad un InputStream.
Per suo tramite, si potrà fare accesso ai contenuti del file. Grazie all'astrazione offerta dagli Stream i contenuti potranno essere recuperati come se il
file fosse locale. La classe che svolgerà il lavoro dipende dalla tipologia del formato dei dati: binari o testuali.

Se fosse un file testuale da scaricare in uno StringBuffer potremmo mettere in pratica questo codice:

BufferedReader r=new BufferedReader(new InputStreamReader(is));
String s=null;
StringBuffer sb=new StringBuffer();
while((s=r.readLine())!=null)
{
sb.append(s);
}

Trasmettere dati in Rete

Se si desidera inviare dati ad un server mediante HTTP, è probabile che lo si voglia fare con il metodo POST. Parafrasando il codice visto con HttpClient,
un'operazione del genere si può portare a termine così:

HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
List<BasicNameValuePair> parametri = new ArrayList<BasicNameValuePair>(1);
parametri.add(new BasicNameValuePair("cognome", "Rossi"));
parametri.add(new BasicNameValuePair("nome", "Sergio"));
parametri.add(new BasicNameValuePair("eta", "21"));
post.setEntity(new UrlEncodedFormEntity(parametri));
HttpResponse resp = client.execute(post);

A differenza delle operazioni di lettura, si è usata la classe HttpPost in sostituzione di HttpGet. I dati da trasmettere vengono codificati in una lista
di BasicNameValuePair. Ognuno di questi oggetti è costituito da una coppia chiave/valore. I parametri nel complesso alla fine diventano l'Entity della
richiesta HTTP con l'invocazione di setEntity.

Appena sistemati i parametri, il funzionamento di HttpClient procede come abbiamo già visto. La richiesta viene eseguita e della risposta ottenuta si può
leggere il contenuto nell'Entity come Stream.

Un caso particolare: il DownloadManager

La lettura da remoto, come visto sinora, è ottimale per scambi di informazioni finalizzati a stabilire una comunicazione tra app e server. Generalmente, i
dati ricevuti non hanno una mole eccessiva e sono codificati in un formato comune come JSON, XML, testo o CSV per agevolarne il parsing e l'utilizzo nelle
app.

Per download di dimensioni piuttosto grandi, sarebbe opportuno predisporre un funzionamento più "robusto". Non è necessario reinventare la
ruota in quanto esiste un servizio di sistema che già svolge bene questo lavoro: il DownloadManager.

Come tutti i servizi di sistema, se ne deve recuperare un riferimento:

DownloadManager manager= (DownloadManager) getSystemService(DOWNLOAD_SERVICE);

A questo punto si crea una richiesta contenente l'indirizzo del file da scaricare e la si accoda nel manager:

Request request=new Request(Uri.parse("http://.... "));
manager.enqueue(request);

In funzione delle richieste pendenti, il servizio farà il download non appena possibile.

Questo servizio non solo offre "già pronta" una funzionalità molto utile ma è altamente configurabile. Infatti si può scegliere, tra
l'altro, se mostrare una barra di avanzamento nell'area delle notifiche, la posizione di salvataggio del file all'interno dello Storage e, cosa molto
importante, se svolgere il download con ogni tipo di connessione o solo in presenza di Wi-Fi.

Le potenzialità e la flessibilità del DownloadManager lo rendono un servizio utilissimo tanto da poter considerare assolutamente inutile, se non
addirittura dannoso, creare in proprio una soluzione alternativa per il medesimo scopo.

Ti consigliamo anche