Upload
sinetempore
View
224
Download
0
Embed Size (px)
Citation preview
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
1/759
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
2/759
SVILUPPARE APPLICAZIONI ANDROID CON GOOGLE PLAY SERVICES
Massimo Carli
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
3/759
© Apogeo - IF - Idee editoriali Feltrinelli s.r.l.
Socio Unico Giangiacomo Feltrinelli Editore s.r.l.
ISBN: 9788850317332
Google, Google Play e Android sono marchi registrati da Google Inc. “Android
robot” è riprodotto o modificato dall’opera creata e rilasciata da Google e utilizzato
secondo i termini descritti nella licenza Creative Commons BY 3.0.
Il presente file può essere usato esclusivamente per finalità di carattere personale.
Tutti i contenuti sono protetti dalla Legge sul diritto d’autore.
Nomi e marchi citati nel testo sono generalmente depositati o registrati dalle
rispettive case produttrici.
L’edizione cartacea è in vendita nelle migliori librerie.
~
Sito web: www.apogeonline.com
Scopri le novità di Apogeo su Facebook
Seguici su Twitter @apogeonline
Rimani aggiornato iscrivendoti alla nostra newsletter
http://bit.ly/aol-newsletterhttp://bit.ly/tw-apogeohttp://bit.ly/fb-apogeohttp://bit.ly/apogeonlinehttp://www.apogeonline.com/libri/9788850333349/scheda
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
4/759
A mio padre
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
5/759
Prefazione
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
6/759
Sono passati ormai diversi anni dal 23 settembre del 2008, giorno in cui è statarilasciata la prima versione di Android. Da allora si sono susseguite diverse release
che si sono differenziate per funzionalità e prestazioni, aiutate anche dal fatto di
utilizzare hardware sempre più potenti. In questi anni uno dei punti di forza di
Android, ovvero la portabilità, si è rivelato spesso un problema. Spesso i costruttori
di dispositivi rilasciavano nuovi prodotti che si appoggiavano a versioni della
piattaforma poi superate, senza preoccuparsi di aggiornare i dispositivi ormai in
commercio. Molti utenti si ritrovavano con dispositivi relativamente nuovi, ma con
sistemi operativi ormai obsoleti. Il problema è stato in parte risolto attraverso quelli
che si chiamano Google Play services.
Si tratta di API che non dipendono pesantemente dall’hardware dei dispositivi e
che quindi possono essere aggiornate automaticamente come fossero una qualunque
applicazione. Molte delle funzionalità più importanti della piattaforma – come la
gestione della location, delle mappe e molte altre – sono state spostate in questa
libreria, permettendo di avere sempre l’ultimo aggiornamento senza la necessità di
attendere update del firmware da parte del costruttore. Tutto questo viene ora gestito
da Google, che, in questo modo, si è ripresa parte del controllo sulla piattaforma
perso in precedenza. I Google Play services stanno quindi assumendo sempre
maggiore importanza e sono divenuti fondamentali nella realizzazione di una
qualunque applicazione più o meno professionale.
L’idea di questo libro nasce da qui: creare un riferimento per lo sviluppo di
applicazioni Android fortemente orientate allo sfruttamento delle API messe a
disposizione da Google e dedicate a dispositivi smartphone, tablet ma anche
wearable e TV. Abbiamo infatti trattato gli aspetti fondamentali dell’utilizzo di
tecnologie anche diverse tra loro, ma accomunate dal fatto di essere raccolte
all’interno dei Google Play services. Per fare questo abbiamo utilizzato un approccio
pratico, attraverso la scrittura di moltissimo codice abbondantemente spiegato nel
testo. Il consiglio è quindi quello di leggere il libro con il relativo progetto aperto
all’interno di Android Studio.
NOTA
Tutto il codice di esempio può essere scaricato all’indirizzo http://bit.ly/apo-gps.
http://bit.ly/apo-gps
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
7/759
A chi è rivolto il testoQuesto testo è rivolto a chi, partendo da conoscenze di base della piattaforma
Android e buone conoscenze del linguaggio di programmazione Java, voglia
apprendere e approfondire l’utilizzo delle librerie dei Google Play services.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
8/759
Organizzazione del testoIl Capitolo 1 presenta le motivazioni che hanno portato alla creazione da parte di
Google di una libreria esterna. Faremo quindi una panoramica di tutte le API e
soprattutto descriveremo come eseguire il setup di tali librerie all’interno dei nostri
progetti.Il Capitolo 2 è invece dedicato alla gestione della Location. Vedremo come
ottenere la Location corrente, come eseguire le operazioni di georeferenziazione
attraverso un oggetto di nome Geocoder e come tracciare le posizioni dell’utente e
soprattutto renderle persistenti.
Il Capitolo 3 è dedicato alla gestione delle Google Maps. Descriveremo sia come
eseguire il setup, sia come personalizzare le mappe attraverso l’utilizzo dei Marker.
Vedremo poi come disegnare dei percorsi e soprattutto come gestire quelli che sichiamano Geofence, ovvero delle zone per le quali poter ricevere delle notifiche al
momento dell’ingresso o dell’uscita. In questo capitolo vedremo anche come
utilizzare le API per la gestione delle Street View.
Il Capitolo 4 è dedicato alla gestione delle API per Google Drive. Con il pretesto
di rendere persistenti le informazioni relative ai percorsi tracciati nei capitoli
precedenti, vedremo come salvare e ripristinare dei file nel cloud.
Il Capitolo 5 è dedicato agli aspetti social e quindi a come sfruttare le API per
l’interazione con Google+.
Il Capitolo 6 descrive nel dettaglio le API Google Cloud Messaging. Vedremo
come funzionano e soprattutto come creare e utilizzare un server per l’invio delle
informazioni in push alla nostra applicazione.
Il Capitolo 7 è dedicato alla programmazione dei dispositivi weareable, che
rappresentano la vera novità descritta durante il Google I/O del 2014. Vedremo inuovi pattern di interazione con questo tipo di dispositivi e come gestire e
personalizzare le varie Notification. La seconda parte del capitolo è dedicata invece
alla realizzazione delle applicazioni weareable vere e proprie, perfettamente integrate
con l’ecosistema Android.
Nel Capitolo 8 cambiamo completamente argomento e ci dedichiamo all’utilizzo
di uno strumento molto interessante che si chiama Chromecast e che permette di
proiettare contenuti multimediali in un dispositivo esterno, come può essere una TV.Nella prima parte di questo capitolo descriviamo anche il funzionamento del
MediaRouter su cui si basa l’interazione con Chromecast.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
9/759
Il Capitolo 9 è dedicato a un’altra novità presentata al Google I/O del 2014,
ovvero Google Fit. Si tratta di API che permettono di raccogliere in un unico
repository e quindi condividere con diverse applicazioni, le informazioni relative
all’attività fisica degli utenti.
Il Capitolo 10 descrive il funzionamento delle Game API di Google. Sarà
l’opportunità di scoprire diversi meccanismi mirati alla gestione dei giochi, degliobiettivi, delle leaderboard, ma anche quelli che permettono a più utenti di giocare in
modalità realtime oppure a turni.
Il Capitolo 11 è dedicato invece a una funzionalità molto delicata, ovvero quella
che permette all’utente di eseguire degli acquisti attraverso un’applicazione Android.
Vedremo sia la parte di amministrazione, attraverso la console di Google, sia quella
legata alla vera e propria scrittura del codice. In questo capitolo è molto importante
anche la descrizione delle modalità di test.
Il Capitolo 12 è dedicato a un aspetto fondamentale nella realizzazione di
un’applicazione Android, ovvero la gestione del tracking. Vedremo come utilizzare
gli strumenti di Google Analytics per poter capire il comportamento dell’utente e
fornirgli la migliore esperienza possibile.
Nel Capitolo 13 descriviamo, infine, le API che permettono la visualizzazione dei
banner all’interno dell’applicazione, in modo da poter in qualche modo monetizzare
il nostro lavoro. Si tratta di un argomento molto semplice, che può comunque dare
diverse soddisfazioni.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
10/759
Tool e versioniI progetti realizzati utilizzano come tool di riferimento Android Studio nella
versione 1.x mentre i Google Play services sono gli ultimi disponibili a inizio 2015,
ovvero la versione 6.5.
Negli ultimi mesi Google ha cambiato molte cose, sia per quello che riguarda iltool di sviluppo, sia per quello che riguarda le API. Per questo motivo abbiamo
cercato di descrivere non solo il codice in quelle che sono le istruzioni vere e proprie,
ma soprattutto nei meccanismi di utilizzo, che sono rimasti pressoché gli stessi nelle
diverse versioni. Potrebbe quindi capitare che alcune delle immagini relative alle
schermate di Android Studio o ai risultati nel dispositivo siano leggermente diverse
da quelle testate dal lettore.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
11/759
Capitolo 1
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
12/759
Introduzione ai Google Play services
Per iniziare, vedremo cosa sono i Google Play services ed esamineremo, ad altolivello, le funzionalità di questa libreria, che andremo a utilizzare e descrivere nel
dettaglio attraverso vari esempi pratici. Nella seconda parte ci dedicheremo invece
alle procedure da seguire per preparare una qualunque applicazione che utilizzi
queste librerie. La versione di riferimento è quella disponibile al momento, ovvero la
6.5, la quale ha portato, come vedremo, ad alcune novità per quello che riguarda la
procedura di configurazione nelle applicazioni. Prima fra tutte la possibilità di
importare solamente le API che interessano e non l’intera libreria, con conseguente
risparmio di spazio. Fatto questo, vedremo come preparare lo scheletro di
un’applicazione con Android Studio, descrivendone le parti fondamentali. Dove
possibile faremo in modo di restare il più possibile indipendenti dall’IDE, anche se
Android Studio si sta affermando come lo strumento al momento migliore per lo
sviluppo di applicazioni con la piattaforma di Google. La versione da noi utilizzata è
la 1.0, resa disponibile verso la fine del 2014 come evoluzione di quella annunciata
all’ultimo Google I/O del 2014.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
13/759
Che cosa sono i Google Play services?Prima di addentrarci nelle diverse librerie messe a disposizione dai Google Play
services è importante capire quali siano state le motivazioni che hanno spinto Google
a realizzarle.
NOTA
Spesso si fa riferimento ai Google Play services attraverso l’acronimo GPs, che, ovviamente, non
ha nulla a che fare con il Global Positioning System. Faremo attenzione nei casi di ambiguità.
Fin dalle prime versioni della piattaforma di Android, Google ha dovuto affrontare
il problema della frammentazione. Quello che doveva essere un punto a favore di
Android, ovvero la possibilità di essere installato e personalizzato su diversi tipi di
dispositivi, era infatti diventato un problema, causa di un certo malcontento tra gli
utenti. In corrispondenza di ogni nuova release del sistema operativo, era necessarioinformare i vari produttori di dispositivi, i quali fornivano la propria
implementazione. Questo processo non solo richiedeva moltissimo tempo, ma spesso
era accompagnato dalla scelta dei produttori di abbandonare alcuni modelli a favore
di altri. Molti utenti si ritrovavano quindi con un dispositivo relativamente nuovo, ma
non più compatibile con l’ultima versione di Android e questo per una pura scelta di
marketing o di costi dell’azienda produttrice. Si trattava di un evidente problema per
la diffusione di questo ormai non più nuovo sistema operativo per dispositivi mobili.
Per alcuni maliziosi lo stesso Google vedeva in un certo senso perdere il controllo
sulla propria creatura. Serviva quindi una soluzione che riducesse il più possibile la
dipendenza di Google e dei servizi da essa offerti dai produttori di dispositivi. Si è
fatto un ragionamento molto semplice: ci si è chiesti quali fossero gli strumenti legati
all’hardware e quali potessero invece essere gestiti a livello software. Per i primi la
dipendenza dai produttori è inevitabile, mentre per i secondi è possibile scegliere un
approccio diverso, ovvero creare un’applicazione in grado di aggiornarsi
automaticamente e di fornire una serie di servizi che, anche alla luce della filosofia diAndroid (all applications are created equals), possono essere utilizzati dalle altre
applicazioni. Ecco il motivo della nascita di un’applicazione chiamata, appunto,
Google Play services, che contiene tutte le API che descriveremo in questo testo
attraverso la realizzazione di alcune applicazioni reali. In questo modo tutti i
dispositivi potranno avere sempre l’ultima versione dei GPs ed essere aggiornati con
gli ultimi servizi messi a disposizione da Google.
NOTA
Questo è un grosso passo in avanti verso una maggiore semplificazione nella gestione degli
aggiornamenti, ma, ovviamente, non potrà mai sostituire completamente la fase di
aggiornamento legata agli aspetti puramente hardware.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
14/759
Prima di procedere con la descrizione dei servizi messi a disposizione dai GPs,
verifichiamo se il nostro dispositivo ne è provvisto. Utilizzando il Nexus 5 con
Android 5.0 a nostra disposizione andiamo nella parte dei Settings relativa alle
applicazioni e cerchiamo appunto i Google Play services, che notiamo essere presenti
come visualizzato nella Figura 1.1 insieme ad altre app, sempre fornite da Google.
Se selezioniamo la voce corrispondente, otteniamo quanto rappresentato nellaFigura 1.2, nella quale possiamo notare come la versione disponibile sia proprio la
6.5.
NOTA
A questo punto il lettore potrebbe chiedersi perché stiamo utilizzando un dispositivo che monta la
versione di Android 5.0 senza utilizzare le API di questa nuova versione, che sappiamo chiamarsi
Lollipop. La prima ragione riguarda la scarsa distribuzione (almeno attualmente) di questa
versione, mentre la versione 4.x è ormai compatibile con la quasi totalità dei dispositivi. Il
secondo motivo riguarda la volontà di concentrarsi sui Google Play services e non su aspetti cheriguardano Lollipop. Le API che descriveremo sono perfettamente funzionanti su tutti i dispositivi
Android, dalla versione 2.3 in avanti e quindi anche sulle versioni 4.x e ovviamente 5.0.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
15/759
Figura 1.1 Applicazione Google Play services tra quelle disponibili.
Questo aggiornamento viene fatto in automatico, per cui non dovremo in alcun
modo ricevere una notifica e procedere all’aggiornamento nel Play Market .
Osservando la Figura 1.2 viene la tentazione di selezionare il pulsante Disable come
faremo più avanti per descrivere che cosa succede nel caso in cui l’applicazione non
fosse disponibile. Al momento lasciamo al lettore la verifica, che porterebbe alla
visualizzazione di un avvertimento e alla cancellazione dell’applicazione, con
conseguente generazione di una serie di warning generati da tutte le applicazioni che
fanno uso di questi servizi.
NOTA
Nel caso, niente paura: come vedremo più avanti, sarà sufficiente andare sul Play Market o
semplicemente seguire le istruzioni successive alla selezione di una delle notifiche di warning per
reinstallare il tutto.
Figura 1.2 Le informazioni relative all’applicazione Google Play services nella versione 6.5.99.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
16/759
Se andiamo a vedere le applicazioni installate di default sul dispositivo, notiamo
anche quella con l’icona rappresentata nella Figura 1.3, relativa alle possibili
configurazioni che ogni utente può personalizzare. Come vedremo nei prossimi
capitoli, ogni utente potrà eventualmente disabilitare i servizi di localizzazione o
gestire il proprio account Google Plus.
Figura 1.3 Icona per la configurazione dei Google Play services.
Si tratta di un’applicazione che viene mantenuta allineata con i Google Play
services, permettendo la configurazione da parte degli utenti delle proprietà relative
ai servizi che la piattaforma mette a disposizione.Prima di iniziare a “sporcarci le mani” è comunque utile fare una panoramica di
tutte le funzionalità dei Google Play services che andremo a utilizzare per realizzare
un’applicazione che descriviamo brevemente e che amplieremo di capitolo in
capitolo.
Si tratta, in sostanza, di un’applicazione che ci permetterà inizialmente di
visualizzare su una mappa la posizione nostra e di un insieme di nostri amici che
decideranno, dando ovviamente il loro consenso, di aggiungersi. In questo capitolovedremo come creare lo scheletro dell’applicazione, mentre nei successivi vedremo
come aggiungere funzionalità legate ai servizi di Google Play services che andremo
di volta in volta a esplorare. Per completezza, ci aiuteremo anche con un insieme di
altri esempi che ci permetteranno di testare funzionalità dei Google Play services non
strettamente legate al nostro caso d’uso, ma che possono essere comunque
importanti.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
17/759
Figura 1.4 Elenco delle possibili configurazioni per i Google Play services.
Gestione della Location
Il primo passo consiste nell’individuare la posizione dei vari utenti. La
determinazione della Location è stata una delle prime funzionalità trasferite a livellodei Google Play services, in quanto le informazioni fisiche necessarie, in termini di
latitudine e longitudine, erano comunque già disponibili dalle prime versioni della
piattaforma. Si è trattato, quindi, di implementare nuovi algoritmi in grado di
elaborare queste informazioni e di dare maggiore accuratezza nella posizione nel caso
di luoghi aperti e, soprattutto, di luoghi chiusi. Per quanto riguarda la nostra
applicazione, svilupperemo l’opzione Where I Am, che permetterà di visualizzare le
coordinate in termini di latitudine e longitudine, cui cercheremo di dare una località equindi un nome. Sempre in corrispondenza di questa voce di menu non ci
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
18/759
accontenteremo di sapere la nostra posizione, ma anche il modo in cui ci stiamo
spostando, attraverso le funzionalità di ActivityRecognition.
NOTA
È curioso come il termine Activity, in questo caso, non faccia riferimento alla classe che
utilizziamo come base per tutte le schermate, ma al concetto di attività ovvero al movimento
dell’utente.
In questa fase vedremo tutto ciò che riguarda la posizione, rimandando la
visualizzazione delle informazioni raccolte in una mappa al capitolo successivo. Si
tratterà di un capitolo molto importante, in quanto ci permetterà di affrontare concetti
anche non strettamente legati a quello di Location. Per realizzare queste funzionalità
abbiamo scelto la strada migliore, ma anche meno convenzionale, non documentata
in modo ufficiale, se non attraverso il JavaDoc. Da un punto vista puramente tecnico
vedremo, in sintesi, come ottenere le informazioni di Location all’interno di un Serviceper poterle rendere persistenti in un ContentProvider. Ulteriore sfida è la possibilità di
affrontare concetti di programmazione concorrente, non sempre descritti in altri testi.
Utilizzo delle Google Maps
Un’altra importantissima funzionalità fornita dai Google Play services è
rappresentata dalla possibilità di visualizzare e gestire le Google Maps. Nel terzo
capitolo vedremo come sia semplice visualizzare una mappa e quali siano i principali
strumenti che ci permetteranno di evidenziare particolari Location. Vedremo che cosa
siano i Marker e come sia semplice personalizzarli attraverso icone o colori e come
gestire gli eventi associati attraverso la visualizzazione delle Info Window. Nel
secondo capitolo abbiamo imparato a tracciare delle posizioni, che ora vogliamo
visualizzare all’interno di una mappa sfruttando gli strumenti per il disegno di
percorsi o di figure geometriche. Le stesse API per il disegno verranno utilizzate
anche nella creazione e gestione dei Geofence, regioni nella mappa per le quali è
possibile ricevere notifiche associate a particolari eventi. Alcuni di questi sono
relativi alla semplice entrata o uscita da tali zone, ma possiamo creare una notifica
nel caso un utente rimanesse nella stessa zona per un tempo maggiore di un periodo
fissato. Questo caso d’uso ci permetterà anche di vedere come testare un servizio di
localizzazione attraverso Mock Location. Concluderemo il terzo capitolo spiegando
come utilizzare le Street View per visualizzare un percorso. Si tratta di un capitolo
molto impegnativo, che ci permetterà di porre le basi per realizzare applicazioni confunzionalità molto interessanti.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
19/759
Google Drive
Finora abbiamo visto come creare delle FenceSession ovvero una collezione di
informazioni di Location e di attività caratterizzate da un nome, una data di inizio e di
fine. Nel capitolo dedicato a Google Drive vogliamo utilizzare le Google Drive API
per rendere queste informazioni persistenti all’interno di un file, per ripristinarle,eventualmente, in un secondo tempo. Vedremo in particolare come creare un file in
Google Drive, gestendone il contenuto. Allo stesso modo vedremo come leggere
questi file per importare informazioni di una specifica FenceSession. Vedremo come
utilizzare questi strumenti per eseguire ricerche oltre che per gestire Folder privati
della nostra applicazione ( App Folder) o comunque accessibili anche in altro modo,
per esempio tramite il Web.
Google Plus
Nel capitolo dedicato a Google Plus ci occuperemo dell’aspetto social della nostra
applicazione, attraverso le API che i Google Play services ci mettono a disposizione
per l’integrazione con Google Plus. Inizialmente vedremo come eseguire la login con
Google+ in modo da ottenere le informazioni dell’utente senza doverle richiedere in
modo esplicito. Poi vedremo come accedere alle informazioni relative agli utenti
nelle proprie cerchie, per condividere informazioni di vario genere.
Google Cloud Messaging
Una delle tecnologie più affascinanti che sono state aggiunte ai Google Play
services è quella che permette l’invio di notifiche push e che va sotto il nome di
Google Cloud Messaging. Attraverso questa tecnologia è possibile inviare dei
messaggi in push a un insieme di dispositivi che si sono in precedenza registrati a unserver di terze parti che contiene la logica dell’applicazione. Nel nostro contesto il
server potrebbe, per esempio, memorizzare le informazioni relative ai Geofence creati e
quindi inviare notifiche ai nostri amici quando si è nella stessa zona. Le possibili
applicazioni sono moltissime. Nel capitolo dedicato al Google Cloud Messaging
descriveremo i punti fondamentali della tecnologia attraverso la realizzazione di una
semplicissima chat. Come detto si tratta di una tecnologia che prevede un’architettura
nel quale il server ha un’importanza fondamentale. Nel nostro caso abbiamorealizzato un semplicissimo server con Node.js, ma il lettore potrà realizzare il
proprio con la tecnologia che ritiene più opportuna, purché vengano rispettate le
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
20/759
convenzioni relative ai servizi Rest che il server espone. In particolare abbiamo
realizzato un servizio /register per la registrazione del client di quello che si chiama
Registration Id e che viene ottenuto dal server GCM di Google, e il servizio /send per
l’invio di una notifica di push ai dispositivi associati a un particolare utente. Si tratta
di una tecnologia che è possibile utilizzare in moltissimi modi diversi, secondo le
specifiche caratteristiche dell’applicazione che intendiamo realizzare.
Google Wear
Nel capitolo dedicato a Google Wear ci occupiamo dei nuovi strumenti di gestione
dei dispositivi wearable. Stiamo parlando di tutti quegli strumenti che possono essere
indossati e che permettono modalità di interazione diversa con le varie applicazioni.
In questo momento i dispositivi wearable sono principalmente orologi, caratterizzatida display molto piccoli e modalità di interazioni limitate alla selezione di piccoli
tasti o all’invio di comandi vocali. In questo capitolo vedremo tutto questo partendo
dalla gestione e personalizzazione delle notifiche, fino alla realizzazione di
applicazioni che girano interamente sul dispositivo wearable. Vedremo nel dettaglio
tutti i componenti principali di una libreria di supporto specifica per questo tipo di
dispositivi rilasciata da Google, concludendo con la descrizione delle diverse
modalità con cui i diversi tipi di device comunicano tra loro, ovvero attraverso
sincronizzazione di dati oppure messaggi. Si tratta di un capitolo abbastanza
impegnativo, che ci permetterà di aprire un nuovo mondo nello sviluppo delle
applicazioni Android.
Google Cast
Nel capitolo precedente abbiamo imparato a programmare un dispositivo esterno
allo smartphone o al tablet che sta al polso come un orologio, ma ovviamente ciaspettiamo che altri dispositivi di vario genere, sempre wearable, vengano lanciati
nel mercato e programmati allo stesso modo. In questo capitolo ci occupiamo invece
di un altro genere di dispositivi esterni che si possono considerare come
un’estensione dei device tradizionali per quello che riguarda la loro capacità di
riprodurre media. Stiamo pensando per esempio a schermi molto grandi, come TV,
oppure a dispositivi in grado di riprodurre suoni. In questo capitolo vedremo
inizialmente come funzionano le MediaRouter API, per poi applicarle a un caso
particolare ovvero l’utilizzo del Chromecast. Si tratta di un dispositivo dal prezzo
molto accessibile, di poche decide di euro, che permette di riprodurre suoni o video
su schermi diversi da quello dello smartphone e che solitamente sono molto più
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
21/759
grandi e di ottima risoluzione. Vedremo che cos’è un Sender e soprattutto che come si
programma un Receiver per questo tipo di dispositivi. È un argomento che si discosta
leggermente da quelli trattati durante lo sviluppo dell’applicazione FriendFence, ma che
permette comunque di realizzare un certo insieme di applicazioni molto interessanti.
Google Fit
Nel capitolo dedicato a Google Fit ci occuperemo invece di alcune API che sono
state annunciate all’ultimo Google I/O come parte di Lollipop, ma che sono state
integrate ai Google Play services nella release 6.5. Le Google Fit sono un ecosistema
di API che permette di raccogliere informazioni relative alla nostra attività fisica
attraverso dei sensori, per poi renderle persistenti all’interno di un database condiviso
che si chiama Google Fitness Store. Si tratta di una tecnologia appena all’inizio e inpiena evoluzione. Vedremo i concetti fondamentali e faremo alcuni esempi su come
utilizzare le API per la raccolta, memorizzazione e visualizzazione dei dati.
Google Game
Nel capitolo dedicato a questo argomento ci occuperemo della descrizione delle
Game API, ovvero degli strumenti che Google ci mette a disposizione per gestire
l’aspetto social e non solo di un gioco. Vedremo infatti come creare e gestire degliobiettivi che i giocatori dovranno raggiungere per poter sbloccare nuove funzionalità
o comunque progredire nel gioco. Il raggiungimento di un obiettivo permette la
raccolta di “punti esperienza”, che possono essere poi visualizzati attraverso
opportune classifiche (leaderboard) che impareremo a personalizzare e visualizzare.
La seconda parte del capitolo è dedicata agli strumenti che permettono il multiplayer
in modalità real-time e a turno. Vedremo gli strumenti per invitare altri giocatori
attraverso i nostri amici nelle cerchie Google+ o attraverso la modalità Quick Start ,che permette la selezione casuale di un giocatore in attesa di giocare. Vedremo come
mettere in contatto questi giocatori e gestire lo scambio di messaggi. Vedremo poi
come gestire i Gift e Wish e soprattutto come raccogliere informazioni sui giocatori
del nostro gioco, in modo da tararlo di conseguenza. Il capitolo permette di capire, e
soprattutto mettere in pratica, i concetti principali nello sviluppo di un gioco.
Google In-app BillingQuindi ci occuperemo delle API che permettono la vendita di prodotti multimediali
dalla nostra applicazione. Vedremo quali passi seguire per configurare l’applicazione
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
22/759
e per creare il nostro catalogo. Poi ci occuperemo dell’integrazione di queste API
all’interno della nostra applicazione. Vedremo come sia possibile ottenere
informazioni sui prodotti del nostro catalogo, ma soprattutto come poterli acquistare.
Faremo molta attenzione a quelli che sono gli aspetti di test, attraverso la creazione di
una semplice applicazione.
Google Analytics
Segue un capitolo dedicato all’utilizzo di alcuni strumenti molto importanti per
comprendere i nostri utenti e creare applicazioni che li soddisfino il più possibile.
Vedremo come, attraverso le Google Analytics API sia possibile comprendere quali
siano le schermate utilizzate dagli utenti e le modalità di navigazione. Vedremo come
è possibile registrare tutte le azioni dell’utente, raggruppate per categorie, per poi
visualizzarle attraverso la console di Google Analytics. Esamineremo inoltre gli
strumenti disponibili per misurare le performance della nostra applicazione e per
tenere traccia degli eventuali errori ed eccezioni.
Google Ads
L’ultimo capitolo è dedicato alle API per la visualizzazione dei banner all’interno
della nostra applicazione. Vedremo inizialmente come creare normali banner, per poipassare ai cosiddetti Interstitial. Un capitolo molto breve che permette di farsi
un’idea dei meccanismi di advertisement nelle applicazioni Android.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
23/759
Installazione e setup di un’applicazioneDopo aver descritto i servizi offerti dai GPs, iniziamo a creare il nostro progetto
utilizzando Android Studio nella versione disponibile al momento, ovvero la 1.0. Per
creare lo scheletro della nostra applicazione utilizzeremo un semplice wizard, messo
a disposizione dall’IDE.NOTA
Anche se l’ambiente dovesse cambiare, il lettore potrà comunque creare la stessa struttura da
zero seguendo la descrizione di seguito. Preferiamo non legarci troppo all’IDE e specialmente ad
Android Studio, in continua evoluzione.
Iniziamo selezionando l’opzione di creazione di un nuovo progetto, ottenendo la
schermata rappresentata nella Figura 1.5, che ci mette a disposizione diverse opzioni.
NOTACon le ultime versioni di Android Studio è possibile che venga visualizzata una finestra diversa,
che permette di selezionare una configurazione standard o personalizzata dell’IDE. In questo
caso, basta selezionare il pulsante Cancel per arrivare alla schermata per la creazione di un
nuovo progetto.
In questa prima schermata inseriamo semplicemente il nome dell’applicazione, il
corrispondente package e il percorso in cui salvare il progetto nel nostro file system.
Figura 1.5 Finestra di creazione del progetto FriendFence.
Ovviamente il lettore potrà avere un percorso diverso.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
24/759
NOTA
Supponiamo che il lettore sia già a conoscenza dei concetti base della programmazione Android.
Descriveremo solamente gli aspetti in qualche modo collegati ai GPs.
Fino a qui nessun problema, se non quello di sottolineare come il package sia di
fondamentale importanza, in quanto definisce in modo univoco la nostra applicazione
e non potrà più essere modificato una volta che questa sia stata pubblicata.NOTA
Forse per questo motivo viene chiesto il dominio dell’azienda o persona che crea l’applicazione e
quindi viene creato in automatico il package. L’errore in questa fase è abbastanza frequente.
Selezionando il pulsante Next otteniamo la schermata rappresentata nella Figura 1.6
che, alla luce delle novità annunciate al Google I/O del 2014, assume un’importanza
fondamentale.
Figura 1.6 Definizione degli ambienti in cui l’applicazione potrà essere eseguita e relative versioni.
In questa fase andiamo infatti a definire gli ambienti in cui la nostra applicazione
potrà essere eseguita, con relative versioni minime. Come possiamo notare ci sarà la
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
25/759
possibilità di eseguire l’applicazione su un ambiente TV, su un dispositivo Wear che al
momento è rappresentato da un orologio oppure attraverso i Google Glasses. Al
momento selezioniamo solamente la prima delle opzioni, scegliendo come minima
versione di riferimento quella relativa a Gingerbread ovvero un API Level 10 o SDK
di versione 2.3.3. Come possiamo vedere nella figura, questo ci permette di
raggiungere il 99,2% degli utenti che possiamo considerare più che accettabile.NOTA
In realtà i Google Play services esistono anche per Froyo (API Level 8), ma sono contenuti in una
libreria distinta. L’aggiunta di questa versione avrebbe comportato l’introduzione di una
complessità non giustificata da un aumento minimo della percentuale di dispositivi (0,8%) peraltro
in continua diminuzione.
A questo punto facciamo clic sul pulsante Next e otteniamo un’altra schermata che
ci permette di scegliere tra un insieme di Activity (Figura 1.7). Il lettore potrà notare
come esista la possibilità di creare una Google Play services Activity e generare in
modo automatico tutto il codice di inizializzazione. Nel nostro caso abbiamo deciso
di essere il più possibile indipendenti dall’IDE, per cui scegliamo l’opzione
evidenziata in figura: Blank Activity.
NOTA
Come sappiamo, l’utilizzo dei Fragment è da preferire in quanto ci permette di essere più elastici
nel caso di un Tablet . Nel nostro caso la prima attività da creare sarà quella di Splash che non
necessita di questo accorgimento. È comunque disponibile anche una Blank Activity withFragment .
Selezioniamo ancora il pulsante Next, arrivando alla schermata rappresentata nella
Figura 1.8, la quale ci permette di inserire le informazioni relative alla nostra
SplashActivity.
A questo punto il pulsante Finish è abilitato e possiamo procedere con la creazione
del progetto e la conseguente generazione della struttura, che possiamo vedere in
Figura 1.9. Coloro che hanno già utilizzato una versione precedente di AndroidStudio troveranno una modalità di visualizzazione diversa. In questa nuova vista
possiamo vedere come la definizione del modulo app è separata dai file di
configurazione di Gradle, che possiamo vedere nella parte inferiore.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
26/759
Figura 1.7 Wizard per la creazione di una Activity.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
27/759
Figura 1.8 Creazione della nostra SplashActivity.
Nel modulo app notiamo come il file di configurazione AndroidManifest.xml venga
visualizzato in una parte separata rispetto al codice. Infine notiamo come le risorse
con qualificatore diverso vengano comunque visualizzate come se appartenessero a
una stessa cartella; è il caso delle risorse nei file dimens.xml.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
28/759
Figura 1.9 Struttura del progetto generata in automatico da Android Studio.
Prima di descrivere tutto ciò che è stato generato, dobbiamo però assicurarci un
paio di cose. La prima riguarda la disponibilità di tutte le librerie di cui andremo a
definire le dipendenze nel file di configurazione di Gradle ovvero il file build.gradle
associato al modulo app. Per fare questo andiamo a selezionare l’icona per l’avvio
dell’SDK Manager (Figura 1.10) per verificare la presenza delle librerie relative ai
Google Play services, della libreria di supporto e dei vari Repository cui Gradle accede
in fase di build.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
29/759
Figura 1.10 Verifichiamo la presenza delle librerie necessarie per la nostra applicazione.
NOTA
Notiamo come la versione dei Google Play services 6.5 disponibile al momento corrisponda alla
revisione 22. Qualora Google rilasciasse nuove versioni, tale valore sarà ovviamente diverso.
La seconda riguarda l’utilizzo delle librerie in Gradle oltre alla configurazione deiGoogle Play services, come evidenziato nel seguente listato:
apply plugin: 'com.android.application'android {
compileSdkVersion 21
buildToolsVersion “21.1.2”
defaultConfig {
applicationId “uk.co.massimocarli.friendfence”
minSdkVersion 10
targetSdkVersion 21
versionCode 1
versionName “1.0”}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile(‘proguard-android.txt’),
‘proguard-rules.pro’
}
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
30/759
}
}dependencies {
compile fileTree(dir: ‘libs’, include: [‘*.jar’])
compile 'com.android.support:appcompat-v7:21.0.3' compile 'com.android.support:support-v4:21.+' compile 'com.google.android.gms:play-services:6.5.+'}
Ovviamente la versione cui fare riferimento sarà quella disponibile al momento di
creazione del progetto. Come possiamo vedere abbiamo aggiunto la dipendenza dalle
librerie di supporto e ovviamente dai Google Play services, che rappresenta il primo
passo di configurazione per il loro utilizzo. Nel precedente codice abbiamo
evidenziato la definizione della seguente dipendenza, che permette di importare nel
nostro progetto tutte le API contenute all’interno dei Google Play services:
compile 'com.google.android.gms:play-services:6.5.+'
In realtà questo non è sempre necessario. Se realizziamo un’applicazione che
utilizza le Location API, forse non abbiamo bisogno anche delle API per la gestione
del gaming o dei dispositivi wearable. In realtà per la maggior parte delleapplicazioni questo non è un problema. Per applicazioni di una certa dimensione può
invece accadere che si verifichi un errore in fase di build dovuto al fatto che esiste
comunque un limite nel numero dei metodi (framework compreso) del codice
contenuto all’interno di un APK. Non possiamo, infatti, avere un numero di metodi
superiore a 65.536. Per questo motivo, dalla versione 6.5, è possibile importare anche
solo le API che servono. Nel caso della nostra applicazione vedremo di volta in volta
quali API utilizzare e quali dipendenze impostare. Facciamo quindi subito una prima
modifica, sostituendo la definizione precedente con :
compile 'com.google.android.gms:play-services-base:6.5.87'
Questo ci permette di importare le sole API base. Un’altra modifica riguarda
l’eliminazione del + con un valore esplicito di versione. La parte delle dipendenze
diventa quindi la seguente. Ricordiamo che le versioni potrebbero essere diverse peril lettore, che rimandiamo alla documentazione ufficiale, dove troverà il valore
corretto.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
31/759
dependencies {
compile fileTree(dir: ‘libs’, include: [‘*.jar’])
compile ‘com.android.support:appcompat-v7:21.0.3’
compile ‘com.android.support:support-v4:21.0.3’compile ‘com.google.android.gms:play-services:6.5.87’
compile ‘com.google.android.gms:play-services-maps:6.5.87’
}
L’applicazione generata in modo automatico permette la semplice visualizzazione
di un messaggio HelloWorld, mentre nel nostro caso vogliamo realizzare una Splash, masoprattutto introdurre la logica che ci permetterà di fare in modo che gli stessi Google
Play services siano disponibili nella versione corretta.
Partiamo da quanto generato in modo automatico e iniziamo con la dichiarazione
dei Google Play services nel file di configurazione della nostra applicazione, ovvero
all’interno dell’AndroidManifest.xml. Avendo utilizzato il template relativo a una Blank
Activity, questa definizione non è avvenuta in automatico, per cui dovremo apportare
manualmente la modifica evidenziata nel seguente documento:
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
32/759
android:label=”@string/app_name”>
In realtà l’operazione è molto semplice, in quanto il riferimento della versione dei
Google Play services è verso una risorsa di tipo intero, definita nella stessa libreriaimportata in precedenza. Si tratta quindi di un valore che viene modificato
automaticamente nel momento in cui viene aggiornata la versione della libreria dei
Google Play services utilizzata.
NOTA
Questo significa che il valore non dovrà più essere modificato in caso di aggiornamenti dei
Google Play services.
Nel codice abbiamo evidenziato anche l’utilizzo di un tema che ci permette divisualizzare l’Activity di Splash a tutto schermo, definita nel seguente modo nel file
styles.xml. D’ora in poi non ci occuperemo più di questi dettagli, che il lettore potrà
comunque cogliere nel codice relativo agli esempi.
L’ultimo passo di configurazione riguarda Proguard, il tool di offuscamento e
ottimizzazione del codice, che viene richiamato nel caso di creazione dell’ APK
firmato con il certificato di produzione. È infatti necessario fare in modo che le nuove
classi non vengano offuscate e quindi rese inutilizzabili dall’applicazione. Anche in
questo caso si tratta di aggiungere il seguente testo al file proguard-rules.pro nella
cartella associata al modulo del progetto. Per i dettagli relativi a questa
configurazione rimandiamo alla documentazione ufficiale di Proguard
(http://proguard.sourceforge.net/).
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
33/759
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents();
}-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
public static final *** NULL;
}
-keepnames @com.google.android.gms.common.annotation.KeepName class *-keepclassmembernames class * {
@com.google.android.gms.common.annotation.KeepName *;
}-keepnames class * implements android.os.Parcelable {
public static final ** CREATOR;
}
Per creare questo file è possibile passare alla visualizzazione del progetto,
selezionando la corrispondente opzione (Figura 1.11).
Figura 1.11 Vista di progetto per la visualizzazione del file di Proguard.
Terminata la fase di configurazione iniziamo quella relativa al codice Java da
aggiungere alla nostra SplashActivity. Vogliamo infatti che venga visualizzato il nome
dell’applicazione e che dopo un certo tempo si proceda verso la Activity principale,
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
34/759
che al momento non abbiamo ancora preparato. Per inserire la logica relativa alla
gestione dei Google Play services facciamo pulizia partendo dal seguente codice:
public class SplashActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
}
}
Ecco il documento di layout nel file activity_splash.xml:
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
35/759
Per eliminare la ActionBar abbiamo anche dovuto modificare le risorse relative allo
stile per i dispositivi di API Level maggiore o uguale a 11 nel file /res/values-
v11/styles.xml:
E anche nel file/res/values/styles.xml
:
L’utilizzo di queste risorse di tipo style sarebbe causa di un errore nel caso in cui la
nostra Activity estendesse la classe ActionBarActivity della relativa libreria come nel
codice generato automaticamente da Android Studio. La nostra Splash non necessita
di ActionBar, per cui abbiamo semplicemente esteso la classe Activity come evidenziato
nel precedente codice. Il tema dovrà quindi essere associato alla SplashActivity, come
evidenziato nell’AndroidManifest.xml. Se eseguissimo l’applicazione in questo momento
otterremmo quanto rappresentato nella Figura 1.12, che non è nulla di speciale, ma
che ci permette di consolidare un punto di partenza.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
36/759
Figura 1.12 La visualizzazione della SplashActivity come punto di partenza.
Non ci resta che fare in modo che un utente non possa avviare la nostra
applicazione se non con la versione corretta dei Google Play services. Si tratta di un
procedimento ormai standard, per cui le stesse API ci mettono a disposizione dei
metodi di utilità per raggiungere il nostro scopo in modo semplice.
NOTA
Nel nostro caso eseguiamo questo controllo all’avvio dell’applicazione, in quanto i Google Play
services sono necessari da subito. Nel caso si trattasse di funzionalità secondarie è possibile
implementare la logica di controllo in un altro punto dell’applicazione.
Il codice della nostra SplashActivity prevede sostanzialmente la gestione del
controllo sulla compatibilità (presenza o versione) dei Google Play services e, in caso
di successo, il passaggio automatico alla Activity principale, che abbiamo chiamato
MainActivity e che vedremo come creare utilizzando un Wizard di Android Studio.
public class SplashActivity extends Activity {
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
37/759
/**
* The Tag for the Log
*/
private static final String TAG_LOG = SplashActivity.class.getName();
/**
* The delay to wait before going to the MainActivity
*/
private static final long SPLASH_DELAY = 2000;
/**
* The Request code to use for the Dialog management*/
private static final int GPS_REQUEST_CODE = 1;
/**
* The Handler to manage the delay message
*/
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (!isFinishing()) {
final Intent mainIntent =new Intent(SplashActivity.this, MainActivity.class);
startActivity(mainIntent);
finish();
}
}
};
@Override
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
38/759
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
}
@Override
protected void onResume() {
super.onResume();
// We check if the GooglePlayServices are available
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); if (ConnectionResult.SUCCESS != resultCode) { // In this case the Google Play services are not installed or
// in the wrong version so we have to launch the Play Store // for the installation GooglePlayServicesUtil.showErrorDialogFragment(resultCode, this, GPS_REQUEST_CODE, new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { // In this case we close the app Toast.makeText(SplashActivity.this, R.string.gps_mandatory, Toast.LENGTH_LONG).show(); finish(); } }); } else { // Here we implement the logic for the MainActivity mHandler.sendEmptyMessageDelayed(0, SPLASH_DELAY); }
}
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (GPS_REQUEST_CODE == requestCode &&
Activity.RESULT_CANCELED == resultCode) {
Log.d(TAG_LOG, “Dialog closed from the Play Market”);
Toast.makeText(SplashActivity.this, R.string.gps_mandatory,
Toast.LENGTH_LONG).show();
}
}
}
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
39/759
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
40/759
DialogInterface.OnCancelListener, che permette di gestire il caso in cui l’utente prema Back
dopo la visualizzazione della Dialog.
NOTA
Il metodo showErrorDialogFragment() prevede anche un overload senza la necessità di impostare
un valore per il parametro cancelListener.
È importante comprendere come la cancellazione della Dialog comporti la chiamata
del particolare cancelListener, ma non la chiamata del metodo onActivityResult(), il quale
viene invece richiamato nel caso in cui l’operazione venisse annullata direttamente
dalla schermata del Play Market in fase di installazione dei Google Play services.
Il secondo aspetto della nostra SplashActivity riguarda il passaggio alla MainActivity
nel caso in cui il test sui Google Play services sia andato bene e siano passati 2
secondi. Come possiamo notare, questo viene realizzato attraverso un Handler che ha,come unica accortezza, quella di controllare attraverso il metodo isFinishing(), se
l’Activity è stata chiusa.
NOTA
Vista la semplicità della nostra Splash abbiamo deciso di non implementare l’Handler con il
consueto accorgimento della classe interna statica, al fine di eliminare possibili memory leak .
Prima di passare a un semplice test sul funzionamento di quanto creato ci
ricordiamo di creare una MainActivity temporanea.
Figura 1.13 Creazione di una Activity di tipo Navigation Drawer.
Abbiamo deciso di utilizzare un Navigation Drawer per la selezione delle diverseopzioni, per cui utilizziamo il Wizard che Android Studio ci mette a disposizione. Per
mettere un minimo di ordine abbiamo creato un package activity e quindi selezionato
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
41/759
l’opzione indicata nella Figura 1.13, che ci porta alla finestra rappresentata nella
Figura 1.14.
La presenza della classe MainActivity permetterà la compilazione della nostra
SplashActivity. Eseguendo l’applicazione otterremmo la visualizzazione della Splash
della Figura 1.12 e quanto rappresentato nella Figura 1.15 che andremo a
personalizzare nei prossimi capitoli. Quanto visualizzato nella Figura 1.15 potrà
essere diverso da quanto visualizzato dal lettore, a seconda della particolare versione
di Android utilizzata o del particolare dispositivo.
Quello descritto è il funzionamento nel caso in cui tutto vada bene ovvero che nel
device sia disponibile l’ultima versione di Google Play services. Il prossimo
paragrafo ci permetterà di verificare cosa succede nel caso in cui i Google Play
services non fossero invece disponibili o siano di versione diversa da quella richiesta.
Figura 1.14 Configurazione della MainActivity.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
42/759
Figura 1.15 La MainActivity in esecuzione.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
43/759
Aggiornamento dei Google Play servicesIn questo capitolo non abbiamo scritto moltissimo codice, ma abbiamo
implementato qualcosa di necessario in tutte le applicazioni che si basano sui Google
Play services. Per completezza è interessante osservare che cosa succederebbe
qualora eseguissimo la nostra applicazione in un dispositivo non ancora dotato diGoogle Play services.
NOTA
Il lettore non interessato a questo tipo di test può saltare al prossimo capitolo, impiegando quanto
realizzato in precedenza.
La maggior parte dei dispositivi (approvati da Google) dovrebbe disporre della
ultima versione dei Google Play services. In caso contrario, la nostra applicazione
dovrebbe chiedere all’utente di procedere alla loro installazione, o aggiornamento,dal Play Market .
NOTA
Nella descrizione che segue abbiamo utilizzato un Nexus 5. In altri dispositivi questo meccanismo
potrebbe essere leggermente diverso e potrebbe comportare la perdita di alcune informazioni.
Lasciamo quindi al lettore la piena responsabilità su quanto segue.
Cerchiamo di simulare questo processo andando nella schermata rappresentata
nella Figura 1.2 e quindi selezionando il pulsante Disable. A questo punto si ha la
visualizzazione del messaggio rappresentato nella Figura 1.16: i dati memorizzati
fino a quel momento verranno cancellati.
Figura 1.16 La disabilitazione dei GPs comporta la perdita dei dati corrispondenti.
Selezioniamo il pulsante OK e otteniamo una finestra di dialogo (Figura 1.17) nella
quale ci viene chiesto di ripristinare l’applicazione nella sua versione originale,
ovvero quella installata inizialmente nel dispositivo.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
44/759
Anche in questo caso selezioniamo il pulsante OK: un messaggio ci segnala che
l’operazione che stiamo per effettuare necessita dei diritti di Administrator del device
(Figura 1.18).
Se siamo sicuri della nostra scelta selezioniamo il pulsante Manage device
administrators il quale ci conduce alla schermata rappresentata nella Figura 1.19 che
contiene una checkbox che deselezioniamo arrivando alla schermata rappresentatanella Figura 1.20.
Figura 1.17 Ripristiniamo la versione iniziale.
Figura 1.18 La rimozione necessita dei diritti di Administrator.
Figura 1.19 Otteniamo il diritto di cancellare la nostra applicazione.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
45/759
Figura 1.20 In questa schermata possiamo disattivare il ruolo di Administrator.
Selezionando il pulsante Deactivate in basso a destra torniamo alla schermata
rappresentata nella Figura 1.2, ma questa volta il pulsante Uninstall updates è abilitato,
come possiamo vedere nella Figura 1.21.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
46/759
Figura 1.21 Ora il pulsante Uninstall updates è abilitato.
Non ci resta che selezionare il pulsante Uninstall updates e dare conferma nella
successiva finestra di dialogo, per procedere alla disinstallazione, seguita da una serie
di notifiche di “lamentela” da parte delle altre applicazioni, tra cui, nel nostro caso,
Hangout e Google+ (Figura 1.22).
Figura 1.22 Notifiche delle applicazioni che reclamano la presenza dell’ultima versione di GPs.
Selezionando una di queste notifiche sarà possibile andare al Play Store e ottenere
quello che invece noi vogliamo testare attraverso la nostra applicazione, che avviamo
ottenendo il messaggio rappresentato nella Figura 1.23.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
47/759
Figura 1.23 La nostra applicazione, giustamente, richiede l’ultima versione di GPs.
A questo punto l’utente potrebbe premere il pulsante Back, in quanto non intendere
procedere all’aggiornamento. Questa è la parte del caso d’uso gestito dalla nostra
implementazione dell’interfaccia DialogInterface.OnCancelListener la quale termina
l’applicazione visualizzazione un messaggio attraverso un Toast (Figura 1.24). Inquesto caso il metodo di callback onActivityResult() non viene richiamato.
Figura 1.24 Se l’utente rifiuta l’aggiornamento dobbiamo uscire dall’applicazione.
Se invece selezioniamo il pulsante Update veniamo condotti al Play Market , dove
potremo procedere all’aggiornamento. Qualora, una volta giunti al Play Market ,
decidessimo di rifiutare l’aggiornamento scegliendo ancora il pulsante Back,
cadremmo nel caso corrispondente alla cancellazione della operazione. Verràrichiamato il metodo onActivityResult() con un valore di resultCode di cancellazione,
ovvero Activity.RESULT_CANCELED. Nel nostro caso il risultato è lo stesso del caso
precedente e quindi la visualizzazione di un Toast con il messaggio rappresentato
nella Figura 1.24. Questo metodo permetterebbe anche la gestione di altri tipi di
problemi che si potrebbero verificare di ritorno dalla particolare Activity di
destinazione della Dialog, che non è detto sia necessariamente quella del Play Store.
Procedendo invece all’aggiornamento dei Google Play services e tornando alla
nostra applicazione noteremo come il funzionamento sia quello sperato, ovvero la
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
48/759
visualizzazione della MainActivity dopo il tempo di attesa impostato nella SplashActivity.
Al termine consigliamo il lettore di riattivare i vincoli legati al ruolo di
Administrator del dispositivo, attraverso la corrispondente opzione che nel Nexus 5 è
nei Settings alla voce Security e quindi Device Administrators.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
49/759
ConclusioniNella prima parte di questo capitolo abbiamo voluto giustificare la realizzazione
dei Google Play services come un modo per diminuire la forte dipendenza della
piattaforma dai diversi produttori di dispositivi. Attraverso un’accorta separazione tra
quello che è fortemente legato all’hardware e quello che è invece gestibile a livellosoftware è stato possibile creare un meccanismo di aggiornamento della piattaforma
più affidabile e quindi in grado di soddisfare maggiormente i diversi utenti oltre che
Google stessa.
Dopo aver dato una panoramica su quelli che saranno i servizi offerti dai Google
Play services abbiamo iniziato lo sviluppo dell’applicazione FriendFence, occupandoci
di quello che ogni applicazione di questo tipo dovrà fare ovvero verificare la presenza
dei Google Play services nella corretta versione, gestendone eventualmentel’aggiornamento attraverso l’accesso al Play Market . Abbiamo quindi concluso
attraverso la simulazione di quello che accadrebbe nel caso in cui l’utente non
disponesse dei Google Play services necessari alla nostra applicazione. Quello
ottenuto alla fine di questo capitolo è lo scheletro di un’applicazione, con alcune voci
di menu che andremo a modificare e riempire di volta in volta nei prossimi capitoli.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
50/759
Capitolo 2
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
51/759
La gestione della Location
Come abbiamo accennato nel capitolo introduttivo, quella della gestione dellalocation, in termini di latitudine e longitudine, è stata una delle prime funzionalità
che Google ha deciso di spostare da quello che possiamo chiamare ambiente base ai
Google Play services. Oltre alle motivazioni già descritte per tutti i servizi in genere,
la gestione della location ne ha anche un’altra legata alle prestazioni e, in particolare,
alla durata della batteria. Come vedremo, specialmente nel caso di un’elevata
accuratezza, la gestione della location è un’operazione piuttosto impegnativa.
Qualora più applicazioni avessero la necessità di gestire una stessa informazione, è
sicuramente vantaggioso fare in modo che essa venga gestita in un punto solo.
Questo, per esempio, permette a un’applicazione di utilizzare la stessa location
appena richiesta da un’altra, senza ulteriore overhead. Allo stesso modo, i Google
Play services possono decidere il livello di accuratezza più efficiente per poter gestire
le richieste da parte di più applicazioni. Un’applicazione che si accontenti di
un’accuratezza bassa potrebbe anche godere di un’informazione più precisa
disponibile a seguito della richiesta da parte di un’altra applicazione. L’aspetto
fondamentale è che questa decisione è ora centralizzata e può essere gestita emigliorata nelle versioni successive della piattaforma. In Android ogni componente
in grado di fornire informazioni di Location si chiama Provider; ne esistono diverse
implementazioni che differiscono per la modalità di acquisizione dei dati,
conseguente accuratezza e quindi costo per poterla ottenere. L’unificazione di cui
abbiamo parlato prima si è quindi tradotta nella creazione di quello che viene
chiamato Fused Location Provider, ovvero di un’implementazione che permette di gestire
in modo ottimizzato le informazioni di localizzazione in relazione allo stato deldispositivo e alle necessità delle diverse applicazioni. Questa unificazione offre
vantaggi da diversi punti di vista. Per il programmatore rappresenta un’evidente
semplificazione nello sviluppo. Come vedremo non dovremo più preoccuparci della
gestione dei singoli Provider, ma ci accontenteremo di specificare il grado di
accuratezza dell’informazione che ci serve, la sua durata oltre ad altri criteri che
vedremo in dettaglio. Proprio per il fatto che si tratta di un Provider condiviso, è molto
probabile che la nostra applicazione disponga subito di un’informazione di Locationperché richiesta poco prima da un’altra applicazione, con conseguente estensione
dell’utilizzabilità.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
52/759
In questo capitolo vogliamo sfruttare questi servizi per implementare le
funzionalità dell’applicazione FriendFence, che utilizza in modo diretto le informazioni
di location. Implementeremo, come prima funzionalità , quella che chiamiamo Where
I Am, che ci permetterà di conoscere la nostra posizione sia in termini di latitudine e
longitudine, sia in termini di indirizzo. Da un’informazione statica realizzeremo poi
la funzione Where I Go, che ci permetterà di sapere “dove” stiamo andando e,soprattutto, “come”, attraverso la nuova funzionalità di ActivityRecognition che ci dirà
se stiamo camminando, se siamo fermi, se andiamo in bicicletta e così via.
Memorizzeremo le informazioni in un nostro ContentProvider, che ci sarà utile anche
nel prossimo capitolo per visualizzare le informazioni in una mappa. Infine vedremo
come definire delle regioni, chiamate GeoFence, alle quali associare una serie di eventi,
che andremo poi a utilizzare nei capitoli successivi.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
53/759
Design for ChangeCome accennato, la funzionalità Where I Am ci permetterà di visualizzare le
informazioni relative alla nostra posizione in termini di latitudine e longitudine, cui
assoceremo un indirizzo attraverso un servizio di Geocoder. Prima di fare tutto
questo, dobbiamo però riprendere l’applicazione che abbiamo creato nel capitoloprecedente e creare una struttura che ci permetta di aggiungere funzionalità in modo
dinamico. Per farlo abbiamo deciso di creare un package per ciascun argomento,
all’interno del quale distingueremo i diversi Fragment dalle classi di utilità ed eventuali
Activity. Nel caso di questa prima funzionalità vogliamo fare in modo che tutta la
logica sia in qualche modo incapsulata in un Fragment che chiamiamo
StaticLocationFragment. Come abbiamo detto nella parte introduttiva del primo capitolo,
i Google Play services vanno in un certo senso inizializzati e la documentazioneufficiale lega questo meccanismo al ciclo di vita di una Activity. Nel nostro caso, al
fine di semplificarne la descrizione, vogliamo rendere le funzionalità il più possibile
indipendenti e quindi rendere i vari Fragment autoconsistenti.
NOTA
Nella struttura della nostra applicazione, i Fragment vengono aggiunti a una stessa Activity
attraverso il meccanismo del Navigation Drawer , per cui l’inizializzazione potrebbe avvenire in
modo centralizzato. Vedremo inoltre che sarà necessario apportare una modifica alla MainActivity
in relazione al metodo onActivityResult() richiamato.
Prima di creare il nostro Fragment facciamo un po’ di refactoring per quanto riguarda
l’elenco delle funzionalità che andremo a realizzare. Nel codice creato da Android
Studio notiamo la presenza della classe NavigationDrawerFragment, che contiene al proprio
interno la definizione di un array delle opzioni nel seguente modo (nel metodo
onCreateView()):
mDrawerListView.setAdapter(new ArrayAdapter(
getActionBar().getThemedContext(),
android.R.layout.simple_list_item_1,
android.R.id.text1,
new String[]{ getString(R.string.title_section1), getString(R.string.title_section2),
getString(R.string.title_section3), }));
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
54/759
La nostra prima modifica consiste quindi nel creare una risorsa di tipo string-array
che abbiamo inserito nel file /res/array.xml e che al momento è molto semplice:
@string/menu_item_where_i_am
@string/menu_item_where_i_go
Da notare solo come non siano state inserite direttamente le voci di menu, ma i
riferimenti ad altrettante risorse di tipo String, che potranno quindi essere
internazionalizzate. Questo ci porta a modificare il precedente codice con il seguente,
nel quale abbiamo evidenziato i cambiamenti
final String[] menuOptions = getActivity() .getResources().getStringArray(R.array.menu_options);mDrawerListView.setAdapter(new ArrayAdapter(
getActionBar().getThemedContext(),
android.R.layout.simple_list_item_1,
android.R.id.text1,
menuOptions));
Con questa semplice modifica non dovremmo più tornare su questa classe, inquanto andremo a modificare le opzioni direttamente nella risorsa. Quello che
dobbiamo fare è invece modificare la nostra MainActivity, dove viene gestita la
selezione della voce di menu. Dovremo quindi cambiare l’implementazione dei
seguenti due metodi:
@Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
55/759
fragmentManager.beginTransaction()
.replace(R.id.container,
PlaceholderFragment.newInstance(position + 1))
.commit();
}public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
}
}
Il primo metodo viene infatti richiamato in corrispondenza della selezione di una
voce di menu, mentre il secondo permette di definire il titolo da visualizzare nella
ActionBar per la selezione stessa. Per non dover modificare più neppure questa classe
abbiamo definito una semplice FragmentFactory, la cui responsabilità sarà quella difornire il Fragment corrispondente alla selezione fatta. Il precedente codice diventa
quindi:
@Overridepublic void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager(); final Fragment optionFragment = FragmentFactory.get() .getFragment(this, position); mCurrentFragment = optionFragment;
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
56/759
fragmentManager.beginTransaction()
.replace(R.id.container, optionFragment)
.commit();
}public void onSectionAttached(int number) {
// We return the label for the given option mTitle = getResources().getStringArray(R.array.menu_options)[number];}
In questo modo tutta la logica di creazione dei Fragment da visualizzare in
corrispondenza di ciascuna opzione è nella FragmentFactory, che al momento sarà molto
semplice.
NOTA
Nella classe MainActivity ci siamo anche preoccupati di cancellare completamente la classe
PlaceholderFragment, che era stata creata come esempio di Fragment e che ora non serve più.
Come possiamo osservare nel precedente codice, la nostra classe FragmentFactory è
molto semplice, in quanto implementa il pattern Singleton
(http://en.wikipedia.org/wiki/Singleton_pattern) e definisce un metodo di Factory che
abbiamo evidenziato e che conterrà appunto la logica descritta in precedenza di
associazione fra voce di menu e corrispondente Fragment.
public final class FragmentFactory {
/**
* The Singleton Instance
*/
private static FragmentFactory sFragmentFactory;
/**
* Private constructor
*/
private FragmentFactory() {
}
/**
http://en.wikipedia.org/wiki/Singleton_pattern
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
57/759
* @return The FragmentFactory Singleton
*/
public synchronized static FragmentFactory get() {
if (null == sFragmentFactory) {
sFragmentFactory = new FragmentFactory();
}
return sFragmentFactory;
}
public final Fragment getFragment(final Context context, final int selection) { return new Fragment(); }
}
Al momento non facciamo altro che restituire un’istanza di Fragment, che non
porterà alla visualizzazione di alcuna informazione.
Prima di procedere all’implementazione della prima funzionalità è importante
descrivere un aspetto cui avevamo accennato in una precedente nota, relativo alla
gestione del ciclo di vita di inizializzazione di Google Play services legato a quellodella Activity. In alcuni casi abbiamo infatti visto come la comunicazione avvenga
attraverso la chiamata del metodo onActivityResult(). Il problema riguarda il fatto che
tale metodo non viene richiamato nel Fragment che gestisce, nel nostro caso, il processo
di inizializzazione, ma nella Activity contenitore. Questo è il motivo per cui in
precedenza abbiamo memorizzato in una variabile d’istanza il riferimento al Fragment
corrente:
mCurrentFragment = optionFragment;
e, soprattutto, questo è il motivo della seguente implementazione del metodo
onActivityResult() nella classe MainActivity.
@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
58/759
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
59/759
Inizializzazione dei servizi di LocationCome accennato in precedenza, l’utilizzo dei Google Play services prevede sempre
una fase di inizializzazione che può differire di poco da servizio a servizio e che
abbiamo deciso quindi di incapsulare all’interno di ciascuna funzionalità. Nel nostro
caso vogliamo creare la classe MyLocationFragment con lo scopo di implementare lafunzione Where I Am. Creiamo quindi un Fragment all’interno del package location
utilizzando il Wizard di Android Studio, ottenendo la schermata rappresentata nella
Figura 2.1.
Figura 2.1 Creazione di un Fragment con Android Studio.
Come possiamo vedere, abbiamo selezionato la possibilità di creare il documento
XML di layout, ma non il classico metodo di factory o l’eventuale interfaccia di
callback. Questo perché non si tratta di un Fragment che necessita di parametri di input,
né conterrà un’interfaccia che permetta di notificare eventi all’Activity che lo
contiene. Selezionando il pulsante Finish otteniamo quindi il classico codice di un
Fragment, cui abbiamo associato un documento XML di layout.
public class MyLocationFragment extends Fragment {
public MyLocationFragment() {
// Required empty public constructor
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
60/759
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_my_location,
container, false);
}
}
Prima di procedere, ricordiamoci di associare questo Fragment alla prima voce di
menu nella nostra classe FragmentFactory, nel seguente modo.
public final Fragment getFragment(final Context context, final int selection) {
switch (selection) {
case 0:
return new MyLocationFragment();
}
return new Fragment();
}
Torniamo finalmente al nostro MyLocationFragment e procediamo all’inizializzazione
del servizio di localizzazione, che è cambiato nelle ultime versioni dei Google Play
services e prevede, come per gli altri servizi che vedremo, l’inizializzazione di un
oggetto di tipo GoogleApiClient, al quale poi chiederemo il riferimenti ad altri
componenti relativi alle specifiche funzionalità.
NOTA
Nelle precedenti versioni dei Google Play services esisteva un grosso problema di design che
costringeva lo sviluppatore a inizializzare oggetti diversi, ciascuno dei quali possedeva un ciclo di
vita collegato a quello di una Activity o Fragment. Fortunatamente ora l’unico oggetto di cui è
necessario gestire il ciclo di vita è quello di tipo GoogleApiClient.
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
61/759
Il primo passo consiste quindi nell’inizializzazione di un oggetto di tipo
GoogleApiClient attraverso le seguenti righe di codice, che possiamo vedere nel nostro
metodo onCreate()
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) .addApi(LocationServices.API) .addConnectionCallbacks(mConnectionCallbacks) .addOnConnectionFailedListener(mOnConnectionFailedListener) .build();}
Come possiamo notare viene utilizzata un’implementazione del Builder Pattern
che ci permette di specificare quelle che sono le API di cui abbiamo bisogno (in
questo caso quelle di localizzazione) e quindi fornire le implementazioni di due
interfacce che ci permetteranno di gestire il caso di inizializzazione con successo e
quello di eventuale errore.
NOTA
Quelle che descriveremo sono operazioni che, come altre analoghe e ripetitive, nondescriveremo più per le successive funzionalità, se non strettamente necessario.
Come vedremo anche successivamente la nuova architettura dei Google Play
services prevede la definizione di una costante per ogni possibile funzionalità. Nel
nostro caso la costante LocationServices.API permette appunto di specificare la necessità
dei servizi relativi alla location, che ci verranno poi messi a disposizione da un
oggetto di tipo FusedLocationProviderApi.
NOTA
Alla luce di quanto fatto nel Capitolo 1, siamo sicuri che comunque i Google Play services siano
disponibili, per cui non dobbiamo implementare quella logica di controllo sulla loro presenza e
sulla loro versione.
L’inizializzazione di un oggetto di tipo GoogleApiClient non è immediata e si rende
necessario gestire sia il caso di avvenuta inizializzazione, sia quello di errore. A tale
proposito è necessario implementare due interfacce.
Nella variabile mConnectionCallbacks abbiamo memorizzato una nostraimplementazione dell’interfaccia GoogleApiClient.ConnectionCallbacks, responsabile della
gestione degli eventi di connessione e disconnessione. Nel nostro caso
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
62/759
l’implementazione è molto semplice, ma molto importante, in quanto ci mostra come
accedere al primo dei servizi di localizzazione di cui abbiamo bisogno, ovvero quello
che restituisce l’ultima posizione ottenuta dalla nostra o da un’altra applicazione.
private final GoogleApiClient.ConnectionCallbacks mConnectionCallbacks
= new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle bundle) {
Log.d(TAG_LOG, “Connected”);
// We update the data into the View with the first location
final Location firstLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
displayLocation(firstLocation);
}
@Override
public void onConnectionSuspended(int i) {
Log.d(TAG_LOG, “Disconnected. Please re-connect.”);
}
};
Come possiamo notare, l’interfaccia prevede la definizione di due operazioni
relative all’avvenuta connessione o disconnessione con i Google Play services. In
caso di successo abbiamo evidenziato come la classe LocationServices disponga del
membro statico FusedLocationApi che ci mette a disposizione il metodo:
public Location getLastLocation()
Questo metodo ha l’enorme vantaggio di non richiedere alcuna risorsa particolare.
Se in precedenza la stessa o un’altra applicazione aveva fatto richiesta di una
posizione, questa viene restituita attraverso un oggetto di tipo Location. Nel raro caso
in cui questa informazione non fosse disponibile, si otterrebbe semplicemente un
valore null, che dovremo gestire in fase di visualizzazione. Nel nostro caso abbiamo
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
63/759
richiamato semplicemente un nostro metodo di utilità, displayLocation(), per la
visualizzazione del dato sul display.
Non può andare sempre tutto bene, per cui è necessario gestire gli eventuali casi di
errore. Questa è la ragione della presenza dell’interfaccia
GooglePlayServicesClient.OnConnectionFailedListener , che abbiamo implementato nel
seguente modo:
private final GoogleApiClient.OnConnectionFailedListener
mOnConnectionFailedListener =
new GoogleApiClient.OnConnectionFailedListener() {
Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try {
connectionResult
.startResolutionForResult(getActivity(),
CONNECTION_FAILURE_RESOLUTION_REQUEST);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else {
DialogFragment dialogFragment = new DialogFragment();
dialogFragment.show(getFragmentManager(),
“Error:” + connectionResult.getErrorCode());
}
}
};
Possiamo notare come la gestione degli errori non differisca di molto da quella
relativa alla verifica della presenza dei Google Play services fatta nel capitolo
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
64/759
precedente. Il metodo onConnectionFailed() contiene infatti un parametro di tipo
ConnectionResult che ci fornisce alcune informazioni sull’errore. Attraverso la chiamata
del suo metodo hasResolution() siamo inoltre in grado di ottenere un Intent, lanciando il
quale si va automaticamente a una schermata per la risoluzione del problema. In caso
contrario, eventualità molto rara, visualizzeremo semplicemente una Dialog con un
messaggio di errore.
Come già detto, quella della Location è da un lato un’informazione sensibile e
dall’altro un dato che richiede diverse risorse da parte del dispositivo. Per questo
motivo, l’accesso a questa informazione richiede la definizione di una Permission
attraverso il corrispondente elemento nel file di configurazione AndroidManifest.xml. Da
molto tempo esistono due tipi di Permission e precisamente
android.permission.ACCESS_COARSE_LOCATION
e
android.permission.ACCESS_FINE_LOCATION
che differiscono per il livello di accuratezza. La prima richiede al dispositivo
l’accesso ai meccanismi meno costosi in termini di risorse (Wi-Fi e celle), in grado
però di dare informazioni solo indicative sulla posizione. La seconda permette invece
di richiedere l’utilizzo di meccanismi in grado di fornire posizioni accurate come il
GPS (Global Positioning System).
NOTA
Come vedremo più avanti, questa impostazione ha un importante impatto sull’esito dell’invio diuna LocationRequest in relazione specialmente a quella che chiameremo Priority.
L’inizializzazione di un’istanza di GoogleApiClient come fatto nel metodo onCreate()
non porta comunque alla creazione di una connessione con il corrispondente servizio.
Per farlo è necessario richiamare in modo esplicito il suo metodo:
public void connect()
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
65/759
Una volta utilizzato è importante eseguire la disconnessione attraverso la chiamata
del suo metodo:
public void disconnect()
Non ci resta che legare la chiamata di questi metodi al ciclo di vita del Fragment e
quindi provvediamo all’implementazione dei seguenti due metodi:
@Overridepublic void onStart() {
super.onStart();
// Here we have to connection the clientmGoogleApiClient.connect();
}@Overridepublic void onStop() {
// Here we have to disconnect the client
mGoogleApiClient.disconnect();
// And then call super.onStop()super.onStop();
}
Nel metodo onStart() provvediamo alla chiamata del metodo connect(), mentre il
metodo disconnect() verrà richiamato in corrispondenza del metodo onStop().
NOTA
Da notare la simmetria nelle chiamate dei metodi sul GoogleApiClient e i metodi di callback del
Fragment attraverso il riferimento super.
A questo punto la nostra prima funzionalità è quasi completa, anche se non
abbiamo in alcun modo gestito l’aggiornamento della Location corrente e nemmeno la
visualizzazione del corrispondente indirizzo. Le informazioni visualizzate sono infatti
quelle ottenute dal metodo getLastLocation(), che quindi dipendono da quello che il
sistema e le altre applicazioni ci possono regalare; non abbiamo ancora fatto alcunarichiesta esplicita. Quello di richiesta è il termine giusto, in quanto l’interazione con i
LocationServices avviene proprio attraverso la creazione di una particolare istanza della
8/18/2019 Sviluppare Applicazioni Android Con Google Play Services
66/759
classe LocationRequest, che ci permetterà di impostare una serie di opzioni che verranno
valutate dai Google Play services per fornirci un’informazione di Location più utile
possibile. Si tratta di un oggetto attraverso il quale imposteremo non solo le
informazioni relative all’accuratezza di cui abbiamo bisogno, ma anche informazioni
legate alla frequenza con cui vorremo essere notificati con nuovi dati.
Prima di proseguire diamo qualche indicazione sul codice del metodo di
visualizzazione della posizione, che non riportiamo per brevità, ma che il lettore può
consultare direttamente nel progetto