Android e la rete

30 luglio 2014

La presente lezione 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.

Tutte le lezioni

1 ... 79 80 81 ... 85

Se vuoi aggiornamenti su Android e la rete inserisci la tua e-mail nel box qui sotto:
Tags:
 
X
Se vuoi aggiornamenti su Android e la rete

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy