Creare un’applicazione per Android

Attualmente sono disponibili diverse piattaforme mobile, come ad esempio Windows Phone 7, iOS, Symbian, Linux Mobile (LiMo), allora perché dovremmo scegliere questa piattaforma? Android è la prima piattaforma completa e gratuita per lo sviluppo di applicazioni mobile.

Perchè Android

Ecco alcuni vantaggi che si hanno con Android:

  • Completamente open source.
  • Altissima diffusione (è il sistema operativo mobile più diffuso).
  • Costi ridotti di accesso e di sviluppo.
  • Gestione automatica del ciclo di vita dell’applicazione.
  • Estremamente portabile: può essere implementata per una grande varietà di hardware differente (non solo smartphone, ma anche internet tablet, ebook reader, netbook).
  • Gestione della grafica e del suono di altissima qualità.

Concetti Base

Il cuore dei controlli studiati e progettati appositamente per i device mobili è rappresentato dalle classi android.view.View eandroid.view.ViewGroup. Possiamo considerare una View come un widget (bottoni, etichette, caselle di testo, tabelle) che possiamo utilizzare per comporre le interfacce grafiche delle nostre applicazioni. Un oggetto ViewGroup è anch’esso una View, ma che contiene altre View. Un concetto fondamentale da imparare è quello dei layout utile per gestire l’impaginazione dei controlli all’interno delleView e per facilitare la progettazione delle interfacce. Si puo` definire l’interfaccia interamente da codice, costruirla attraverso le configurazione XML, oppure si puo` scegliere un approccio “ibrido”, definire le interfacce in XML e poi modificarle e gestirle da codice.

Un concetto legato allo sviluppo delle interfacce grafiche e anche uno degli elementi centrali di ogni applicazione Android è la classe Activity. Generalmente una Activity rappresenta una singola schermata della nostra applicazione e corrisponde ad un’azione specifica che l’utente può fare. Ci può essere solo una Activity attiva per volta e se in un determinato momento non si trova nello stato attivo e quindi non si trova in foreground (in questo caso si dice che l’Activity si trova in backgroud) potrebbe essere terminata dal sistema operativo. Ogni applicazione può cambiare lo stato in ogni momento e deve essere pronta ad essere interrotta e chiusa in ogni istante, per cui è responsabile del salvataggio del proprio stato in modo da poterlo ristabilire.

L’Intent è uno dei meccanismi fondamentali di Android: descrive un’azione specifica che possiamo far invocare ad Android e puo` essere utilizzata anche per riusare o sostituire diversi componenti software. Un Intent può essere molto specifico ed essere richiamabile da una specifica Activity oppure può essere generico e disponibile per qualsiasi Activity che rispetta determinati criteri.

Un Intent può essere utilizzato per:

  • trasmettere l’informazione per cui un particolare evento (o azione) si è verificato;
  • esplicitare un’intenzione che una Activity o un Service possono sfruttare per eseguire un determinato compito o azione, solitamente con o su un particolare insieme di dati;
  • lanciare una particolare Activity o Service;
  • supportare l’interazione tra qualsiasi applicazione installata sul dispositivo Android, senza doversi preoccupare di che tipo di applicazione sia o di quale componente software gli Intent facciano parte.

Teniamo presente, pero`, alcuni dettagli e principi che sono alla base dello sviluppo di un’applicazione Android. L’application context è un elemento centrale e importante per tutte le funzionalità disponibili al più alto livello applicativo: possiamo utilizzare l’application context per accedere ad un ampio insieme di caratteristiche e servizi condivise tra istanze di diverse Activity. Questo e` possibile recuperarlo con il seguente codice:

Context context = getApplicationContext();

L’application context lo utilizziamo per:

  1. Lanciare istanze di Activity.
  2. Gestire le directory, i database e i file protetti dell’applicazione.
  3. Richiamare i gestori di servizi di sistema (e.g. servizio di localizzazione).
  4. Applicare e controllare i permessi a livello applicativo.
  5. Richiamare gli asset dell’applicazione.

Visto che la classe Activity deriva dalla classe Context possiamo richiamare il metodo getResources() per recuperare le risorse dell’applicazione:

String hello = context.getResources().getString(R.string.hello);

Un altro elemento molto importante e` il layout. I layout sono estensioni della classe ViewGroup usati per posizionare i controlli e possono essere nidificati. Android mette a disposizione alcuni semplici modelli da cui partire. Vediamo alcune delle principali classi layout che la piattaforma ci mette a disposizione:

  • TableLayout: questo tipo di layout ci permette di disporre gli oggetti View usando una griglia composta da righe e colonne, proprio come una tabella;
  • LinearLayout: il LinearLayout allinea ogni View figlia sia in senso verticale sia in senso orizzontale (un layout orizzontale ha una riga di oggetti View, mentre un layout verticale è composto da una colonna di oggetti View);
  • RelativeLayout: questo è il layout più flessibile tra quelli nativi perché permette di definire le posizioni di ogni oggetto View in relazione agli altri oggetti View presenti;
  • FrameLayout: questa è la tipologia più semplice di layout, perché non fa altro che posizionare in ordine di inserimento tutti gli oggetti View partendo dall’angolo in alto a sinistra dello schermo. È molto comodo quando implementiamo degli swticher di immagini o delle interfacce a tab.

La manipolazione dei dati

Dato che Android è un sistema Linux-based, nel modello di sicurezza implementato i file scritti da una applicazione non possono essere letti o scritti da un’altra, per cui ogni applicazione per comunicare necessita di uncontenitore di dati o Content Provider.

Android è provvisto di un insieme di Content Provider nativi ma i processi possono segnalare se stessi al sistema come Content Provider di un insieme particolare di dati: quando queste informazioni sono richieste vengono richiamate da Android. Alcuni Content Provider forniscono l’accesso ai proprio dati solo in lettura, mentre altri permettono alle applicazioni di creare, aggiornare, modificare o cancellare record, come nel caso di quella che gestisce i contatti disponibile nei device come database nativo accessibile anche ad applicativi di terze parti. Un database SQLite è un esempio di sorgente di dati che possiamo incapsulare all’interno di un Content Provider. Per accedere alle risorse fornite da un Content Provider utilizziamo un insieme di URL caratterizzati dallo schema “content://”.

Un Service è un processo che gira in background utilizzato per creare componenti software che possono svolgere attività in modo “invisibile”, senza interfaccia utente. Utilizzando i Service possiamo far girare le nostre applicazioni e farle reagire ad eventi anche quando non sono in primo piano: un Service può essere avviato, fermato e controllato da altri componenti dell’applicazione, inclusi altri Service e Activity. Un Service avviato ha una priorità più alta rispetto ad Activity in stato di inattività e l’unica ragione per cui Android potrebbe fermare un Service prematuramente è per fornire risorse addizionali al componente software in primo piano per poi essere riavviato automaticamente non appena le risorse diventano nuovamente disponibili.

Nel caso in cui il Service debba interagire direttamente con l’utente potrebbe essere necessario incrementare la sua priorità, per fare in modo che non vengano terminati se non in circostanze estreme, a scapito della gestione delle risorse a tempo di esecuzione e dell’esperienza utente.

Il cuore di un’applicazione Android è AndroidManifest.xml, il file che definisce i contenuti e il comportamento dell’applicazione e in cui sono elencati i Content Provider, le Activity e i Service dell’applicazione, con i permessi che necessita per funzionare correttamente. La radice di ogni AndroidManifest.xml è il tag <manifest>: questo tag include i nodi che definiscono i componenti dell’applicazione, l’ambiente di sicurezza, e tutto ciò che fa parte dell’applicazione. Ogni applicazione gira all’interno di un processo Linux, ogni processo non può accedere alla memoria di un altro processo e i file di un applicativo non possono essere letti o scritti da altri applicativi, anche l’accesso a diverse operazioni critiche sono protette. Quando un’applicazione viene installata il gestore dei pacchetti concede o no i privilegi a seconda di come sono configurati nell’AndroidManifest.xml.

I principali permessi sono i seguenti:

  • READ_CONTACTS: leggere (ma non scrivere) i dati dei contatti dell’utente.
  • WRITE_CONTACTS: scrivere (ma non leggere) i dati dei contatti dell’utente
  • RECEIVE_SMS: monitorare l’arrivo di messaggi SMS
  • INTERNET: accedere ed utilizzare la connessione Internet
  • ACCESS_FINE_LOCATION: utilizzare un accurato sistema di localizzazione come il GPS

La gestione delle risorse

Una risorsa può essere un’immagine bitmap, una etichetta o un bottone, o può essere qualsiasi altra informazione che non sia codice e che è necessaria per il corretto funzionamento dell’applicazione. Tutte le Resource vengono compilate all’interno dell’applicazione e sono memorizzate all’interno della directory res del progetto: il compilatore delle risorse processa le risorse in base alle sotto-directory in cui sono memorizzate e in base al formato dei file. Cosi` i file immagine JPG o PNG andrebbero memorizzati nella directory all’interno di res/drawable mentre i file XML che descrivono i layout delle schermate in res/layout. Inoltre si possono aggiungere alle directory suffissi specifici per indicare una particolare lingua, un determinato orientamento dello schermo, la densità dei pixel ecc.

Il compilatore impacchetta le risorse e genera una classe chiamata “R” che contiene tutti gli identificatori per riferirci alle risorse del programma. Cio` assicura che tutte le referenze delle Resource siano valide e permette di risparmiare spazio non dovendo memorizzare anche le stringhe di referenza come avviene in ambiente Java standard.

La struttura dell’applicazione

L’applicazione ha tre componenti: il file AndroidManifest.xml, la cartella “src” che contiene il codice sorgente, la cartella “resource” che contiene le risorse come ad esempio “drawable”, “raw”, “layout”, “anim” ecc. Android supporta una organizzazione lineare per la cartella “res” per cui non sono supportate sottocartelle oltre il secondo livello. Le due directory “raw” e “assets”possono contenere la stessa tipologia di file, ma quelli contenuti nella cartella “raw” sono considerati delle risorse e saranno localizzati e accessibili attraverso gli ID autogenerati, mentre gli altri sono considerati come contenuto generico per cui possiamo organizzare arbitrariamente la gerarchia di cartelle e sottocartelle.

La cartella “layout” contiene alcune View dell’applicazione ed è in questa cartella che mettiamo i file XML che definiscono le interfacce della app. Nelle cartelle “drawable-ldpi”, “drawable-hdpi”, “drawable-mdpi” vanno immagini ed altre risorse grafiche per differenti risoluzioni e densità degli schermi e nella cartella “anim” ci sono le animazioni. In “menu” ci saranno i descrittori XML che definiscono la struttura dei vari menu e in “values” possiamo mettere altre risorse come stili, stringhe e definizioni di colori  sottoforma di descrittori XML.

Possiamo immaginare la struttura di una applicazione composta di cinque elementi:

  • Splash: rappresenta l’immagine visualizzata durante la fase di caricamento, in cui vengono rappresentati il logo e il numero di versione. Puo` anche esserci una musica di sottofondo;
  • Menu: il menu permette all’utente di scegliere tra diverse opzioni, come ad esempio configurare l’applicativo, accedere ai credits, visualizzare l’help ecc;
  • Avvio: questa schermata compare dopo aver avviato l’applicazione;
  • Help: ha il compito di visualizzare le istruzioni di utilizzo, per esempio descrivendo i controlli disponibili;
  • Credits: in questa schermata vi saranno le informazioni sull’azienda o su chi si è occupato dello sviluppo o della distribuzione dell’applicativo;

Questo modello permette di avere una buona usabilità, una facilità d’uso ma anche flessibilità e chiarezza.

Le interfacce utente in Android possono essere create completamente in codice Java (metodo procedurale) oppure possiamo creare l’interfaccia utente attraverso un descrittore XML (metodo dichiarativo). Android inoltre permette anche un approccio ibrido, in cui si crea un’interfaccia in modo dichiarativo e la si controlla e specifica in modo procedurale. Entrambi i metodi sono soluzioni valide, si suggerisce nella maggior parte dei casi di usare la metodologia dichiarativa perché spesso il codice XML è più corto e semplice da leggere e capire rispetto al corrispondente codice Java. L’applicazione necessiterà almeno di cinque Activity, una per ogni caratteristica: SplashActivity, MenuActivity, PlayActivity, HelpActivity, CreditsActivity. Ogni Activity avrà la propria classe e il proprio layout memorizzato nella directory resources.

Configurare l’ambiente di sviluppo

Per configurare un completo ambiente di sviluppo è necessario installare il Java Development Kit (JDK 5 o 6), l’Android SDK e un ambiente di sviluppo Java: il consiglio è quello di utilizzare Eclipse, perché è un IDE (Integrated Development Environment) open source, potente, fornito di tanti strumenti utili e disponibile per tutti i principali sistemi operativi. Inoltre Google ha rilasciato anche un plug-in per Eclipse chiamato Android Development Tool (ADT), un strumento che permette di integrare in Eclipse i tool per la compilazione, il testing, il debugging del codice rilasciati con l’Android SDK.

La prima cosa da fare e` installare alcuni componenti aggiuntivi nell’SDK di Android. Per fare questo, apriamo il manager dell’Android SDK seguendo questo percorso dal menu di Eclipse: Window / Android SDK Manager

Selezioniamo il packages e  i componenti che vogliamo installare e infine facciamo clic su Install packages.

Primi passi

Siamo pronti per implementare la nostra prima applicazione Android: iniziamo con il classico esempio “Hello Word”. Dal menu File di Eclipse selezioniamo New / Project. Nella finestra che compare selezioniamo Android/Android Project e poi clicchiamo su Next. A questo punto appare la finestra di dialog New Android Application, con questo wizard configureremo il nuovo progetto.

Inseriamo la stringa “HelloWord” come nome del progetto. La stringa che inseriamo come nome dell’applicazione è quella che comparirà nella barra del titolo dell’applicazione, dunque in una implementazione reale bisogna avere qualche accortezza per la scelta di questo nome. Selezioniamo il Min SDK, ovvero la versione minima di Android richiesta per la nostra applicazione e il target per l’applicazione cioe` la versione più alta di Android con la quale verra` usata l’applicazione. Infine dobbiamo selezionare la versione della piattaforma con la quale compilare l’applicazione e il tema della UI Android.

Nella schermata successiva possiamo scegliere il workspace del progetto e decidere se creare un’icona o un’activity automaticamente si consiglia di lasciare le selezioni predefinite e fare clic su Avanti. La schermata successiva può aiutare a creare un’icona di avvio per tutte le densità dello schermo. E` possibile selezionare un modello di attività da cui iniziare a costruire l’applicazione.

A questo punto Lasciare tutti i dettagli per l’attività nel loro stato predefinito e clicchiamo su Finish, e l’ADT genererà la struttura dell’APP, che rimane molto simile anche per applicazioni più complesse e di maggiori dimensioni rispetto all’esempio “HelloWord”.

L’emulatore, i test e il debug

L’Android Virtual Device (AVD) permette agli sviluppatori di testare le loro applicazioni senza dover per forza possedere un device. L’SDK di Android non include alcun AVD pre-installato, per cui è necessario creare almeno un device virtuale prima di poter testare le applicazioni in un emulatore. Il plugin ADT di Eclipse permette di gestire con facilità gli AVD, infatti permette di lanciare automaticamente l’emulatore all’interno dell’AVD selezionato. Per chi, invece, non volesse utilizzare Eclipse può controllare l’emulatore attraverso il terminale. La configurazione dell’AVD comprende la scelta della dimensione dello schermo, la possibilità di utilizzare una SD card e la sua dimensione. Per creare un AVD è necessario seguire questa procedura:

  1. Lanciare l’Android Virtual Device Manager da Eclipse seguendo il percorso di menu Window / Android Virtual Device Manager. Comparirà l’elenco degli AVD finora creati, se è il primo AVD che creiamo la lista sarà vuota;
  2. Cliccare sul pulsante “New” per creare un nuovo AVD;
  3. Compilare i campi richiesti. Scegliamo un nome per l’AVD, un Device, il Target e altre opzioni semplici.
  4. Scegliamo la capacità della SDcard che prenderà spazio nel nostro disco fisso, quindi un valore ragionevole potrebbe essere ad esempio 1024 Mib (il valore minimo è di 9 MiB);
  5. Clicchiamo sul pulsante “OK” e attendiamo la fine del processo di creazione.

Finito il processo di creazione potremo vedere l’AVD che abbiamo creato. Se volete testare il vostro emulatore è sufficiente selezionarlo e cliccare sul pulsante “Start” sulla destra della finestra dialog.

Per eseguire l’applicazione da Eclipse:

  1. Aprire uno dei file del progetto e sulla barra degli strumenti fare clic sul tasto Esegui
  2. Nella finestra che appare, selezionare Applicazione Android e fare clic su OK.

Eclipse installa l’app sul tuo AVD e l’avvia. Al primo lancio è necessario aspettare un po’ di tempo prima di poter interagire con il device virtuale.

Quando l’emulatore è pronto per l’interazione possiamo premere e trascinare il pulsante di sblocco e se abbiamo fatto tutto correttamente vedremo una schermata molto simile a quella seguente:

L’applicazione è molto semplice: viene visualizzato un controllo di tipo TextView con una linea di stato, “Hello Word, Helloword!“. Abbiamo creato e testato la nostra prima applicazione Android!

Adesso bisogna creare una configurazione di “Run” o di “Debug” per il progetto. Vediamo i passi:

  1. In Eclipse selezioniamo il percorso Run / Debug Configurations;
  2. Sulla parte sinistra eseguiamo doppio click sulla voce “Android Application” per creare una nuova configurazione;
  3. Cambiamo il nome della configurazione appena create da “New_configuration” con un altro nome, per esempio “Android Debug”;
  4. Clicchiamo sul pulsante Browse e scegliamo il progetto che vogliamo debuggare;
  5. Spostiamoci sulla scheda Target e controlliamo il target associato al nostro progetto.
  6. Clicchiamo sul pulsante Apply per confermare le modifiche.

La creazione di una configurazione per il running delle app è molto simile cambia che al posto della voce Run / Debug configurations dovremmo seguire il percorso Run / Run Configurations. Dalpunto di vista funzionale cambia che se usiamo quella di debugging il debugger di Eclipse sarà collegato alla nostra applicazione.

Quando eseguiamo il running o il debugging succedono queste cose:

  • Il progetto viene compilato e convertito in un eseguibile (.dex);
  • Gli eseguibili e le risorse esterne della applicazione vengono organizzate in un package Android (.apk);
  • Si avvia il device virtuale;
  • L’applicazione viene installata;
  • L’applicazione viene fatta partire.

Dopo aver testato la prima applicazione del device virtuale, vediamo come si comporta su un device reale. Colleghiamo il nostro smartphone al PC tramite cavo USB, selezioniamo Run / Debug Configurations, doppio click su Android Debug, andiamo sulla scheda Target e selezioniamo la voce Manual che ci permetterà di scegliere se eseguire il debug nell’emulatore o nel device, applichiamo le modifiche e colleghiamo lo smartphone al PC e infine facciamo clic sul pulsante Debug per concludere la configurazione.

Ora comparirà la finestra Android Device Chooser con i device, virtuali e/o reali, di cui possiamo disporre. A questo punto il device deve essere abilitato per il debug attraverso la connessione USB: nello smartphone andiamo su Menu / Impostazioni, atttiviamo l’opzione Origini sconosciute, selezioniamo la voce Sviluppo e attiviamo le voci Debug USB e Rimani attivo. Per concludere il processo è sufficiente fare doppio clic sul device in cui si vuole eseguire l’applicativo nella finestra Android Device Chooser. Eclipse installerà l’applicazione Android nel device che abbiamo selezionato e la eseguirà.

Ogni volta che finiamo di lavorare sullo smartphone dobbiamo ricordarci di disabilitare le impostazioni attivate sopra. L’attivazione permanente dello schermo, se non disabilitata, porta ad un rapido scaricamento della batteria, invece l’attivazione delle altre opzioni al di fuori del contesto di sviluppo lascia aperte molte falle per la sicurezza.

Riassunto tratto liberamente da HTML.IT