lunedì 28 febbraio 2011

Vodafone IDEOS (U8150): skin per l'emulatore di Android


Non trovando in rete nessuna skin capace di mostrarmi sul monitor il mio IDEOS ho allora deciso di modificarne una di default. Trovate qui il file da me modificato, vi ricordo che la cartella estratta (l'ho chiamata IDEOS/) va messa nella cartella .../android-sdk/plattforms/android-version/skins/. Il tema non prevede la modalità landscape. Il tasto per rifiutare le chiamate svolge anche la funzione di spegnimento (se premuto a lungo). Non è un gran che ma meglio di niente. Purtroppo molte immagini in rete, pur sembrando vere, sono disegnate e/o ritoccate a computer, lo schermo e i tasti mi sembrano sempre distanti dalla cornice.

sabato 26 febbraio 2011

Rcolor per Android


Rcolor è un'applicazione per Android in grado di tradurre la sequenza di anelli colorati presente sui resistori. La lettura avviene selezionando i colori attraverso gli spinner disposti nel layout dell'applicazione, è possibile tradurre sequenze di 4 e 6 anelli colorati. L'applicazione è stata testata sul mio IDEOS U8150, non sembrano esserci problemi (effettuerò altre prove durante la composizione di skatch per Arduino). Vi invito a provarla sul vostro dispositivo Android, trovate il codice QR per l'installazione in fondo alla pagina. Qui, invece, è possibile scaricare il codice sorgente per ampliarne le funzionalità o modificarlo (in tal caso lasciatemi un messaggio, sarò felice di leggere e provare la nuova versione scritta da voi).

qrcode

Android, stati e metodi di callback per un'activity

Un'activity, dunque, descrive attraverso una schermata una possibile interazione per l'utente. Poiché in Android il focus spetta a una sola activity, il sistema operativo attribuisce alle attività diversi stati. Ognuno di questi contribuisce allora alla definizione di un ciclo di vita per le applicazioni. L'applicazione, quindi l'activity che la rappresenta in quel momento, viene condotta da uno stato a un altro attraverso dei metodi di callback. Un'activity può trovarsi in uno dei seguenti stati:
  • ACTIVE: l'activity è visibile all'utente che può quindi interagire con la stessa;
  • PAUSED: l'activity non è attiva e può essere visibile in parte (attraverso effetti di trasparenza);
  • STOPPED: l'activity non è né attiva e né visibile;
Se l'activity si trova nello stato PAUSED o STOPPED può essere terminata dal sistema operativo (attraverso il metodo finish()) per liberare le risorse impegnate a favore dell'activity in esecuzione (nello stato ACTIVE). Se la stessa activity viene poi richiesta dall'utente il sistema operativo procederà alla sua creazione, ripristinando i valori salvati.
Un'activity può trovarsi nello stato ACTIVE subito dopo l'istanza della stessa, attraverso i metodi onCreate(), onStart() e onResume(), eseguiti in successione. L'esecuzione di un'altra activity pone l'activity fin li usata dall'utente nello stato PAUSED, attraverso il metodo onPause(), ed esegue una nuova activity (attraverso la sequenza di metodi detti prima) oppure ne ripristina una già esistente. Tale ripristino può avvenire invocando il metodo onResume(), se l'applicazione da ripristinare è nello stato PAUSED, oppure il metodo onRestart() (seguito dai metodi onStart() e onResume()) se l'applicazione è invece nello stato STOPPED. Un'activity transita dallo stato PAUSED allo stato STOPPED attraverso il metodo onStop(). Per garantire all'utente la disponibilità dell'activity richiesta la transizione da PAUSED a STOPPED non avviene immediatamente. Il sistema operativo, infatti, ferma l'activity in esecuzione facendola transitare da RUNNING a PAUSED, quindi avvia l'activity richiesta dall'utente e solo dopo si preoccupa di ultimare il lavoro, fermando la precedente activity da PAUSED a STOPPED. Un'activity nello stato STOPPED, infine, rilascia le risorse impegnate attraverso il metodo onDestroy().


Metodi di callback:
  • onCreate(): viene chiamato quando l'activity è creata per la prima volta. E' qui che invocando il metodo findViewById() possiamo intercettare i componenti inseriti nel layout, con setContentView(), e programmarne i comportamenti. L'oggetto Bundle permette di ripristinare lo stato dell'activity, se quest'ultima è stata chiusa;
  • onStart(): viene invocato prima che l'activity diventi visibile all'utente;
  • onResume(): viene invocato prima che l'activity possa interagire con l'utente;
  • onPause(): viene invocato quando un'activity sta per essere messa in background, prima di ripristinare l'activity chiesta dall'utente. E' preferibile non appesantire questo metodo poiché finché esso non termina il sistema operativo non avvia l'activity richiesta! Meglio salvare lo stato con onSaveInstanceState(Bundle obj);
  • onStop(): viene invocato dal sistema operativo quando l'applicazione non è più usata dall'utente;
  • onDestroy(): viene invocato prima di terminare l'applicazione. Può essere invocato dall'utente per terminare l'applicazione (metodo finish()) o dal sistema operativo per liberare risorse;
  • onRestart(): viene chiamato prima del metodo onStart() per ripristinare un'activity dallo stato STOPPED;
  • onSaveInstanceState(Bundle obj): viene invocato per salvare informazioni sullo stato dell'activity che verrà fermata;
  • onRestoreInstanceState(Bundle obj): viene invocato per ripristinare i valori salvati;
Un'activity di un'applicazione non necessariamente deve implementare tutti i metodi di callback. Il ciclo di vita di un'applicazione Android può essere verificato attraverso un'applicazione che sovrascrivendo tutti i metodi di callback detti sopra mostri all'interno della finestra LogCat (di Eclipse) l'alternanza dei metodi coinvolti nell'utilizzo dell'applicazione. Trovate qui tale applicazione, due activity che regolano il valore di un contatore. La prima permette di aumentarne il valore attraverso la pressione di un bottone, oppure di avviare la seconda activity. Un altro bottone permette di chiudere l'applicazione. La seconda attività eredita dalla precedente activity lo stato del contatore e ne diminuisce il valore, oltre a permettere come la prima la chiusura dell'applicazione.
La stampa di messaggi di log avviene invocando nei metodi di callback il metodo Log, del package android.util.Log. A tale metodo occorre passare una stringa per etichettare con un tag i messaggi (variabile tag delle due activity) e una stringa che rappresenterà il messaggio da stampare. Ogni metodo di callback deve necessariamente chiamare il metodo della classe padre (per l'ereditarietà), con la parola chiave super. I bottoni dei layout applicati alle activity vengono rintracciati attraverso il metodo findViewById(). Nei metodi onSaveInstanceState(Bundle outState) e onRestoreInstanceState(Bundle savedInstanceState) vengono, rispettivamente, salvati e ripristinati i valori usati nell'applicazione. Il passaggio da un activity a un'altra avviene attraverso la definizione di un Intent. Ogni activity è in grado di svolgere un determinato lavoro e può dunque rispondere all'esigenza di un'altra applicazione in esecuzione. Questo permette di riutilizzare componenti già scritti! Nel codice dell'applicazione il passaggio alla seconda activity avviene con le seguenti istruzioni:
Intent intent=new Intent(LifecycleActivity.this,LifecycleSubActivity.class);
intent.putExtra("status",status);
startActivity(intent)
dove viene passato anche lo stato del contatore, con putExtra(). La seconda activity va dichiarata all'interno del manifesto dell'applicazione, attraverso il tag activity. L'attributo android:name del tag xml specifica il nome dell'activity da aggiungere all'applicazione. Avviando l'activity e seguendo l'output della finestra LogCat possiamo subito confermare l'invocazione, in sequenza, dei metodi onCreat(), onStart() e onResume().


Vi consiglio di applicare un filtro all'output di LogCat, usando proprio la stringa tag definita nelle due activity! Cliccando sul bottone exit leggeremo l'invocazione dei metodi onPause(), onStop() e onDestroy().


Avviamo nuovamente l'applicazione, modifichiamo il valore del contatore e invochiamo adesso la seconda activity (con il bottone Del). Nel LogCat leggeremo, come prima, i metodi della prima activity, quindi noteremo la presenza di onPause() per la prima activity e subito dopo i metodi onCreate(), onStart() e onResume() per la seconda activity. Per la prima activity leggeremo ora la presenza del metodo onStop().


Premendo il tasto back del dispositivo leggeremo la presenza di onPause() per la seconda activity, quindi onRestart(), onStart() ed infine onResume() per la prima activity (che è già stata creata prima). Per la seconda activity leggeremo, poi, la presenza di onStop(). Nell'output di LogCat noteremo inoltre la presenza dei metodi per salvare e ripristinare la variabile contatore. La seconda activity, infatti, non salva la variabile modificata (modificate il codice affinché ciò avvenga).

mercoledì 23 febbraio 2011

Android, LayerList


La risorsa LayerList, tag layer-list nei file xml, è in grado di visualizzare sotto un'unica immagine un array di risorse Drawable. Ogni risorsa viene disegnata rispettando l'ordine all'interno dell'array. La risorsa Drawable in coda all'array è la risorsa più alta in livello. L'aggiunta all'array avviene attraverso elementi item (figli, dunque, di layer-list). L'attributo android:drawable di item specifica la risorsa da aggiungere all'array mentre con android:id possiamo dare un id a ogni livello dell'immagine finale. I vari livelli possono essere spostati in alto, in baso, a destra e a sinistra rispettivamente con android:top, android:bottom, android:right e android:left (a cui occorre passare uno scostamento, usando una delle dimensioni riconosciute da Android). Il riferimento alla risorsa all'interno del codice avviene con la sintassi R.drawable.resource_name, nel file xml con @drawable/resource_name.
Il codice sorgente dell'esempio è disponibile qui. Nella cartella res/drawable/ si trovano i file cielo.png, nuvole.png e sole.png. Tutte usate nel file levels.xml per la composizione, su livelli, di una risorse di tipo LayerList. Quest'ultima viene quindi usata nell'activity principale, al layout main.xml (nella cartella res/layout/). Allo stesso layout ho poi aggiunto tre bottoni, la pressione di ognuno di questi provvede alla realizzazione di un nuovo oggetto LayerDrawable applicato quindi all'oggetto ImageView, in questo modo:
ImageView image=(ImageView)findViewById(R.id.image);
Drawable new_layers[]=new Drawable[2];
new_layers[0]=getResources().getDrawable(R.drawable.cielo);
new_layers[1]=getResources().getDrawable(R.drawable.sole);
LayerDrawable new_image=new LayerDrawable(new_layers);
image.setImageDrawable(new_image);
Potete installare questa applicazione sul vostro dispositivo Android anche attareverso il seguente codice QR:

qrcode

Android, NinePatchDrawable



La risorsa NinePatch, tag nine-patch nei file xml, descrive un'immagine di sfondo (scomposta in 9 pezzi) che può essere estesa su uno o più dei suoi lati. Decidiamo noi i lati da estendere, con il tool draw9patch fornito assieme al SDK di Android. In molti casi è preferibile seguire questo approccio piuttosto che estendere l'intera immagine al display (come è stato fatto nella seconda immagine). Possiamo ottenere un riferimento alla risorsa nel codice con la sintassi R.drawable.resource_name, nei file xml con @drawable/resource_name (il nome dato al file costituisce l'id per la risorsa). L'attributo android:src ci permette di specificare la risorsa di tipo Drawable, con android:dither, invece, possiamo abilitare o meno l'effetto dithering all'immagine (rispettivamente con i valori true e false).
Il codice sorgente dell'esempio è disponibile qui. Nella cartella res/drawable/ c'è il file second_image.9.png (notate la particolarità dell'estensione, il riferimento alla risorsa sarà @drawable/second_image). Nella stessa cartella il file background.xml descrive la risorsa di tipo NinePatchDrawable. Quindi, in main.xml, nella cartella res/layout/, viene utilizzata la risorsa appena definita attraverso l'attributo android:background="@drawable/background" del layout applicato all'activity.
Potete installare questa applicazione sul vostro dispositivo Android anche attraverso il seguente codice QR:

qrcode

martedì 22 febbraio 2011

Android, ClipDrawable


La risorsa ClipDrawable, tag clip nei file xml, descrive una risorsa come una porzione di un'altra risorsa Drawable. La porzione selezionata inizialmente può essere variata nel codice attraverso il metodo setLevel(int level) (che assegna un valore nell'intervallo 0-10000). Questa risorsa viene usata, come nell'esempio sopra, per la realizzazione di barre di avanzamento.
Nel codice il riferimento è ottenuto attraverso la sintassi R.drawable.resource_name, nei file xml con @drawable/resource_name. Il nome dato al file xml che descrive la risorse è anche l'id per la stessa. La risorsa di tipo Drawable da cui effettuare il taglio è specificata per mezzo dell'attributo android:drawable. La direzione in cui va tagliata la risorsa, invece, attraverso l'attributo android:clipOrientation (a cui possiamo passare i valori horizontal o vertical). Con l'attributo android:gravity, infine, possiamo indicare dove iniziare il taglio.
Il codice sorgente dell'esempio è disponibile qui. L'applicazione realizza una barra di avanzamento comandata dai click dell'utente su due bottoni del layout. Attenzione, il codice non si preoccupa di gestire il livello della risorsa tagliata (che può dunque andare oltre i valori riconosciuti)!
Nella cartella res/drawable/ (da me creata) si trova il file bar.png, l'intera barra di avanzamento. Nella stessa cartella il file progess_bar.xml descrive la risorsa ClipDrawable come taglio della risorsa android:drawable="@drawable/bar" (l'immagine bar.png). La risorsa viene tagliata in orizzontalmente (android:clipOrientation="horizontal"), a partire da sinistra (android:gravity="left"). Nella cartella res/layout/ il file main.xml descrive il layout applicato all'activity. E' qui che viene usata la risorsa ClipDrawable, in una ImageView. Vengono poi aggiunti i due bottoni per comandare la barra di avanzamento. Nel codice sorgente, dopo aver ottenuto un riferimento ai due bottoni, si procede alla regolazione del taglio in questo modo (+1000 per l'aumento, -1000 per la diminuzione):
ImageView resourceImageView=(ImageView)findViewById(R.id.clip_image);
ClipDrawable drawableClip=(ClipDrawable)resourceImageView.getBackground();
drawableClip.setLevel(drawableClip.getLevel()+1000);
Potete installare questa applicazione sul vostro dispositivo Android anche attraverso il seguente codice QR:

qrcode

Android, GradientDrawable


La risorsa GradientDrawable, tag gradient nei file xml, descrive una risorsa per un sfondo con un gradiente di colori. Possiamo specificare il colore iniziale e quello finale, rispettivamente, con l'attributo android:startColor e android:endColor. All'occorrenza possiamo anche indicare un colore centrale, con android:centerColor. Con android:angle regoliamo invece l'angolazione del gradiente. Il codice sorgente dell'esempio è disponibile qui. Nella cartella res/values/ il file string.xml definisce i colori usati per il gradiente. Nella cartella res/drawable/ il file background.xml descrive quindi l'effetto poi applicato al file main.xml (nella cartella res/layout/) con android:background="@drawable/background". Potete installare questa applicazione sul vostro dispositivo Android anche attraverso il seguente codice QR:

qrcode

lunedì 21 febbraio 2011

Android, InsetDrawable


La risorsa InsetDrawable, tag inset nel file xml, descrive una risorsa di tipo Drawable inserita in un'altra risorsa di tipo Drawable, con i dovuti spazi. Può essere referenziata nel codice con la sintassi R.drawable.resource_name e nei file xml con @drawable/resource_name. Il nome del file che descrive la risorsa rappresenta anche l'id per la stessa. La risorsa Drawable contenuta è specificata per mezzo dell'attributo android:drawable. Le distanze, invece, sono invece indicate dagli attributi android:insetTop, android:insetBottom, android:insetLeft e android:InsetRight, a cui va ovviamente passata una dimensione (con le unità già viste e accettate da Android).
Il codice sorgente dell'esempio è disponibile qui. Il file background2.xml, nella cartella res/drawable/ (da me creta), descrive una risorsa di tipo InsetDrawable. E' all'interno di questa che viene utilizzata la risorsa @drawable/background1. Potete installare questa applicazione sul vostro dispositivo Android anche attareverso il seguente codice QR:

qrcode

Android, ColorDrawable


La risorsa ColorDrawable, tag drawable nel file xml, descrive un rettangolo colorato che può essere usato come background per l'applicazione. L'attributo name, nel tag di apertura, permette di referenziare la risorsa in altri file xml, il valore che specifica il colore è invece racchiuso fra i tag di apertura e chiusura dell'elemento. Possiamo ottenere lo stesso effetto definendo anche una risorsa (elementare) di tipo color. Va comunque detto che con la risorsa ColorDrawable sarà possibile ottenere un riferimento all'oggetto Drawable con il metodo getDrawable().
Trovate un esempio per l'utilizzo di questa risorsa qui. Nella cartella res/drawable/ (da me creata) ho descritto nel file background.xml la risorsa di tipo ColorDrawable. La stessa risorsa è stata quindi applicata al file main.xml, nella cartella res/layout/, che descrive il layout dell'activity. Potete installare questa applicazione sul vostro dispositivo Android anche attareverso il seguente codice QR:

qrcode

sabato 19 febbraio 2011

Android, BitmapDrawable


La risorsa BitmapDrawable può essere definita all'interno di un file xml, attraverso il tag bitmap che prevede i seguenti attributi:
  • xmlns:android: definisce il nome dello schema xml, deve necessariamente valere http://schemas.android.com/apk/res/android e va usato solo se la risorsa dichiarata nel file xml è l'elemento radice (il primo) all'interno del file;
  • android:src="@drawable/resource_name": esprime il riferimento alla risorsa da disegnare;
  • android:antialias="value": abilita o disabilita l'effetto antialias, value può dunque valere true oppure false;
  • android:dither="value": abilita o disabilita il dithering, value può dunque valere true oppure false;
  • android:filter="value": abilita o disabilita il filtro per migliorare l'aspetto delle immagini quando essa appare ridotta o allungata, value può dunque valere true oppure false;
  • android:gravity="value": definisce l'allineamento nei confronti della risorsa che fa da contenitore, value può valere: top, bottom, left, right, center_vertical, fill_vertical, center_horizontal, fill_horizontal, center, fill, clip_vertical, clip_horizontal;
  • android:tileMode="value": stabilisce come deve essere visualizzata la risorsa al'interno del contenitore, se va disegnata una sola volta (disabled) oppure affiancata più volte (repeat);
Il codice sorgente dell'esempio è disponibile qui. Nella cartella res/drawable/ ho disposto il file pattern.png che ho quindi usato per la descrizione della risorsa background.xml, dove uso l'immagine ripetendola più volte. Nella cartella res/layout/, invece, ho aggiunto al file main.xml la risorsa definita in precedenza (lo sfondo dell'applicazione). Il nome della risorsa background.xml è anche l'id per referenziare la stessa all'interno di altri file xml. Nel file background.xml troveremo, infatti, il seguente riferimento: android:src="@drawable/background". Potete installare questa applicazione sul vostro dispositivo Android anche attareverso il seguente codice QR:

qrcode

Android, introduzione alle risorse

La cartella res/ di un progetto Android contiene le risorse utilizzate dall'applicazione. Alcune di queste, create di default dal SDK di Android, hanno lo stesso nome dei tipi di risorse riconosciute dal sistema operativo. All'occorrenza possiamo creare nuove cartelle e file per le nostre risorse. Le risorse nella cartella res/ vengono ottimizzate per l'utilizzo sul dispositivo, a differenza di quelle allocate nella cartella assets/ che sono utilizzate così come sono (attraverso oggetti della classe AssetManager).
Per dare al programmatore la possibilità di referenziare una risorsa all'interno del codice viene generato, nella classe R.java, un id. Non modificate la suddetta classe, la generazione degli id è un processo automatico! Vi invito a dare uno sguardo al contenuto del file R.java. Troverete, divisi per tipologia di risorsa, i nomi delle risorse e le costanti ad esse associate. Ad esempio, dopo aver generato con il tool di sviluppo le cartelle e i file del progetto, noterete la presenza della costante R.drawable.icon che fa riferimento all'icona usata per l'applicazione (all'interno del manifesto). L'icona da usare per l'applicazione viene scelta dal dispositivo, in base alle caratteristiche del proprio display! Esistono infatti più versioni della stessa icona detta sopra, raccolte nelle cartelle res/drawable-hdpi/, res/drawable-ldpi/ e res/drawable-mdpi/. Android offre svariati tipi di risorse che possiamo suddividere in:
  • risorse di tipo elementare;
  • risorse di tipo drawable:
  • risorse di tipo layout;
Le risorse di tipo elementare, raccolte dai tag resources (inizio e fine tag) in un file xml, definiscono stringhe e valori usati nell'applicazione, queste possono essere:
  • stringhe, tag string, l'attributo name="resource_name" (univoco) è l'id della risorsa mentre il contenuto racchiuso fra il tag di apertura e chiusura è la risorsa stringa;
  • array di stringhe, tag string-array, l'attributo name="resource_name" (univoco) è l'id della risorsa, ogni stringa dell'array è racchiusa dai tag item (il valore è fra i tag di inizio e fine);
  • array di interi, tag integer-array, l'attributo name="resource_name" (univoco) è l'id della risorsa, ogni intero dell'array è racchiuso dai tag item (il valore è fra i tag di inizio e fine);
  • rettangoli colorati, tag drawable, l'attributo name="resource_name" (univoco) è l'id della risorsa. Il valore fra i tag di apertura e chiusura definisce il colore della risorsa, espresso attraverso uno dei seguenti formati: #RGB, #RRGGBB, #AARRGGBB (quest'ultima notazione consente di specificare un valore per il canale alfa, la trasparenza);
  • colori, tag color, l'attributo name="resource_name" (univoco) è l'id della risorsa. Il valore fra i tag di apertura e chiusura definisce il colore della risorsa, espresso attraverso uno dei seguenti formati: #RGB, #RRGGBB, #AARRGGBB (quest'ultima notazione consente di specificare un valore per il canale alfa, la trasparenza);
  • dimensioni, tag dimension, l'attributo name="resource_name" (univoco) è l'id della risorsa. Il valore fra i tag di apertura e chiusura definisce la dimensione, espressa usando una delle seguenti unità di misura: px, per i pixel; in, per i pollici; mm, per i millimetri; pt, per i punti; dp, per le misure indipendenti dalla densità del display; sp, per le misure relative;
Le risorse elementari vengono dichiarate all'interno di file xml (oppure sono file binari) e possono essere referenziate sia all'interno del codice (metodo getResource()) e sia all'interno di altri file xml (seguendo la sintassi @resource_type/resource_name).
Le risorse di tipo drawable sono tutte quelle risorse che necessitano di essere disegnate sullo schermo del dispositivo. All'interno del codice possiamo ottenere un riferimento a risorse di tipo drawable (descritte dalla classe Drawable del package android.graphics.drawable) attraverso il metodo getDrawable(int id), a cui bisogna passare l'id della risorsa. La stessa risorsa può essere invece usata in altri file xml, seguendo la sintassi già vista in precedenza (@resource_type/resource_name). Android specializza ulteriormente questo tipo di risorse derivandone altre, alcune di esse sono:
  • BitmapDrawable, descrive una risorsa di tipo immagine (png, jpg e gif);
  • ColorDrawable, descrive una risorsa all'interno di un rettangolo colorato;
  • InsetDrawable, descrive una risorsa di tipo drawable con bordi e/o margini;
  • GradientDrawable, descrive una risorsa come gradiente di colore ;
  • ClipDrawable, descrive una risorsa come porzione di un'altra risorsa di tipo drawable;
  • NinePatchDrawable, definisce una risorsa con le informazioni necessarie a scalare l'immagine lungo uno dei suoi lati;
  • LayerDrawable, definisce una risorsa come un'immagine composta da più livelli (altre risorse di tipo Drawable);
  • TransitionDrawable, descrive una risorsa il cui stato varia fra due risorse di tipo drawable;
  • ScaleDrawable, descrive una risorse scalata;
  • RotateDrawable, descrive una risorsa ruotate;
  • ShapeDrawable, descrive una risorsa di natura geometrica;
Le risorse di tipo drawable possono essere dichiarate sia all'interno di file xml che all'interno del codice (attraverso le omonime classi Java).
Le risorse di tipo layout sono descritte da file xml, nella cartella res/layout/, e si occupano della descrizione dell'interfaccia grafica da applicare all'attività dell'applicazione. E' all'interno di questo file che disponiamo, con opportuni tag, i componenti che permetteranno all'utente di interagire con l'applicazione. E' particolarmente importante istruire il tool di sviluppo affinché ciascun componente aggiunto sia dotato di un proprio id. Questo faciliterà la ricerca dello stesso durante la scrittura del codice o del file xml che descrive altre risorse.
Tale proprietà va definita mediante l'attributo android:id="@resource_type/resource_name", dove resource_type specifica il tipo di risorsa e resource_name identifica la costante ad essa associata. Attenzione, la sintassi appena vista va usata solo se per il componente è stato già definito un id. Se quest'ultimo non esiste ancora va allora usata la seguente sintassi android:id"@+resource_type/resource_name".

venerdì 18 febbraio 2011

Android, il processo di sviluppo

Grazie all'uso di opportuni plugin il processo di sviluppo per applicazioni Android può essere seguito all'interno dell'IDE stesso. Sono disponibili plugin sia per Eclipse che per NetBeans, due dei più famosi ambienti di sviluppo per applicazioni Java. Esistono almeno due buoni motivi per conoscere e saper avviare il processo di sviluppo di un'applicazione Android anche senza l'uso dei suddetti plugin. Il primo è che, come dicevo poco fa, il plugin per sviluppare le applicazioni Android è disponibile solo per Eclipse e NetBeans. Pertanto, se il vostro IDE preferito non è fra questi non vi resta che utilizzare i tool messi a disposizione dal SDK (Service development kit) per Android. Il secondo motivo, invece, è strettamente didattico. Per imparare i meccanismi nascosti proprio dai plugin consiglio, almeno una volta, lo sviluppo di un'applicazione Android (anche semplice) attraverso i tool del SDK. Ecco cosa offre il il SDK di Android:
  • Android: comando per creare e aggiornare progetti e/o generare AVD (Android virtual device), i dispositivi Android virtuali usati dall'emulatore;
  • Android emulator: permette di emulare un terminale Android, consentendo l'installazione delle applicazioni sviluppate;
  • Android debug bridge: favorisce l'interazione con il dispositivo emulato o collegato;
Il SDK di Android va poi completato con altri tool esterni, occorrono infatti altre applicazioni: Ant, per compilare il progetto (in un unico file apk); Keytool (opzionale), per generare una chiave utile a segnare l'applicazione scritta; Jarsigner (opzionale), per usare la chiave generata sull'applicazione. Vi occorre ovviamente una versione di JDK (Java development kit) e un editor di testi.
La creazione di un nuovo progetto avviene con il comando android che, se non è seguito da alcuna opzione, avvia anche la schermata principale del tool attraverso cui possiamo gestire (graficamente) gli aggiornamenti delle piattaforme di sviluppo, i terminali virtuali e avviare l'emulatore.
Per creare un nuovo progetto va passato al comando android l'opzione create project, seguita dagli argomenti che caratterizzeranno il nuovo progetto, questa la sintassi: android create project --target target_id --name project_name --path path_of_project --activity name_of_activity --package name_of_package, dove:
  • --target indica la piattaforma da usare per lo sviluppo dell'applicazione. La lista delle piattaforme disponibili sul proprio computer può essere ottenuta con il comando android list targets;
  • --name specifica il nome del progetto;
  • --path indica la directory da usare per il progetto (se non esiste verrà creata nella directory di lavoro);
  • --activity specifica il nome dell'attività eseguita all'avvio dell'applicazione. Questo argomento permette di generare la classe Java che descrive l'attività;
  • --package indica il nome per il package del progetto;
Ad esempio, il comando android create project --target 1 --name FirstApp --path /home/user/FirstApp --activity FirstAppActivity --package android.firstapp crea la cartella /home/user/FirstApp con all'interno la struttura utile allo sviluppo dell'applicazione. Queste le cartelle e i file generati:
  • AndroidManifest.xml: il manifesto dell'applicazione;
  • build.xml: il file xml utile alla compilazione con ant;
  • default.properties: file con le proprietà di default per la compilazione (non modificatelo);
  • build.properties: file usato per sovrascrivere le proprietà da usare in fase di compilazione;
  • local.properties: file con le proprietà locali per ant, quelle aggiunte da noi;
  • src/ raccoglie la struttura, secondo le disposizioni dettate dal package di appartenenza, che ospita il codice sorgente dell'applicazione;
  • bin/ raccoglie il prodotto della compilazione, il file apk (da usare per installare l'applicazione), il file dex (l'applicazione compilata per l'esecuzione sulla DVM) e le classi compilati (all'interno di altre cartelle);
  • gen/ raccoglie i file generati automaticamente da ant, è qui che si trova la famosa classe R.java (che associa le risorse agli id, per referenziarli all'interno del codice);
  • libs/ raccoglie le librerie esterne usate dall'applicazione (se presenti);
  • res/ raccoglie le risorse utilizzate nell'applicazione;
  • tests/ raccoglie una copia della struttura fin qui vista, utile per svolgere test (opzionale);
Con il comando android possiamo inoltre aggiornare un vecchio progetto attraverso l'opzione update project e i parametri --name project_name --target id --path path_to_your_project, dove:
  • --name è il nuovo nome del progetto (parametro opzionale se non vogliamo modificare il nome);
  • --target specifica un nuovo target per l'applicazione;
  • --path indica il path del progetto da aggiornare (parametro indispensabile);
Ad esempio, il comando android update project --path /home/user/FirstApp --name FirstAppV2 modifica il nome dell'applicazione creata prima (eseguite una copia della vecchia applicazione quando ne modificate il target o il nome, per una nuova versione). La compilazione avviene eseguendo il comando ant nella cartella di progetto. L'installazione sul terminale, invece, avviene attraverso il comando adb install FirstAppV2.apk (eseguito all'interno della cartella di progetto).
Per rimuovere l'applicazione sul dispositivo virtuale, infine, abbiamo due possibilità. La prima, ovviamente, è attraverso l'interfaccia grafica del dispositivo emulato. Troviamo un elenco delle applicazioni installate nella scheda "Scaricate" oppure "In esecuzione" della voce "Gestisci applicazioni" del menu "Impostazioni, Applicazioni". Selezionando un'applicazione dall'elenco possiamo decidere se terminarla (task manager di Android) o disinstallarla. La seconda possibilità prevede invece l'uso del terminale, con il comando adb shell (che trovate nella cartella plattform-tools/) accediamo al terminale del dispositivo. Per cancellare l'applicazione è sufficiente digitare il comando rm /data/app/nome_applicazione. Per cercare il nome dell'applicazione e ottenere un elenco completo delle applicazioni esterne installate vi coniglio di provare con il comando ls /data/app/.
Attenzione, se non avete aggiunto una nuova variabile di ambiente al vostro sistema operativo (un nuovo path in cui il terminale deve cercare i comandi), i comandi saranno eseguibili solo se la directory di lavoro coincide con la directory che ospita i comandi (anteponendo agli stessi il path per la ricerca locale ./).

giovedì 17 febbraio 2011

Android, introduzione alle applicazioni

Le applicazioni per Android sono scritte in Java. Tuttavia, il bytecode generato dalla compilazione viene ottimizzato dal tool di sviluppo e l'applicazione viene eseguita sul dispositivo all'interno di una Dalvik Virtual Machine (DVM), una macchina virtuale molto più leggera della classica Java Virtual Machine (JVM). La DVM è infatti ottimizzata per l'esecuzione su dispositivi mobili, richiede poca memoria e permette pertanto l'istanza di più DVM sullo stesso dispositivo!
La distribuzione delle applicazioni avviene attraverso file apk (Android package), una variante del file JAR (gli archivi Java). All'interno di un file apk (che possiamo aprire con un gestore di archivi compressi, vi invito a farlo) troviamo le directory e i file destinati alle risorse (cartella res/ e file resources.arsc) e quella per le informazioni (cartella META-INF/), oltre ai file che descrivono al sistema operativo l'applicazione (AndroidManifest.xml, il manifesto dell'applicazione) e l'applicazione stessa (impacchettata in unico file, classes.dex).
Non va mai dimenticata una cosa: il kernel Linux è alla base di Android! Ogni applicazione viene eseguita all'interno di un processo Linux che dispone della propria virtual machine sicché il codice in esecuzione risulta isolato dal codice delle altre applicazioni. Questo conferisce al sistema operativo e alle applicazione un certo grado di stabilità. Esistono, ovviamente, delle tecniche per la comunicazione fra processi.
Le prestazioni delle applicazioni all'interno del sistema operativo derivano da un'attenta scomposizione dei componenti e delle risorse che la descrivono. La loro esecuzione può inoltre avvenire da più punti di accesso al codice del programma, questo permette al sistema operativo di eseguire all'occorrenza un preciso pezzo di codice piuttosto che l'intera applicazione! Tale necessità è ad esempio utile ad un'applicazione per invocare le funzionalità già sviluppate in un'altra applicazione. Per comprendere la suddetta modularità e per sfruttarla all'interno delle proprie applicazioni è necessario studiare e programmare pochi componenti (non necessariamente tutti, dipende dalla complessità dell'applicazione). Segue una loro breve descrizione:
  • Attività (Activity): rappresenta la schermata che consente all'utente l'interazione con l'applicazione, raccogliendo gli elementi che compongono l'interfaccia grafica e disponendoli secondo un opportuno layout. Ogni attività, implementata come sotto classe della classe Activity (del package android.app.Activity), è indipendente da un'altra. Solitamente un'attività svolge una precisa azione per l'applicazione, essa può essere orientata all'input dei dati, alla presentazione dell'output oppure a entrambe. Tutto dipende da come viene progettata dal programmatore. Nonostante l'indipendenza detta prima, le attività possono in ogni caso cooperare fra di loro per l'implementazione di una delle due fasi dette prima. In tal caso ci sarà un'attività principale che, dopo l'input o l'elaborazione dei dati, chiederà al sistema operativo il passaggio a una seconda attività, passando a quest'ultima le opportune informazioni. Il contenuto visivo dei componenti viene offerto da oggetti della classe View (del package android.view.View). Un'attività, quindi, contiene oggetti della classe View (bottoni, aree di testo, etichette, etc...);
  • Servizi (Services): lo svolgimento in background di una determinata funzione viene garantito da un preciso servizio, anche quando l'utente sta eseguendo altre operazioni sul dispositivo. Poiché un servizio non dispone di un'interfaccia grafica, l'unico modo per avviarne uno o fermarlo consiste nell'interazione con un'attività dell'applicazione (ad esempio con un bottone). La riproduzione di un flusso audio è un esempio di servizio. L'ascolto di un brano, avviato interagendo con i bottoni di un lettore audio, verrà garantito da un servizio anche quando l'utente avvia sul dispositivo una nuova applicazione! La comunicazione con un servizio può avvenire attraverso l'interfaccia che esso fornisce ai programmi;
  • Ricevitori (Broadcast receiver): questo componente notifica gli eventi alle applicazioni, come ad esempio lo stato della batteria, la disponibilità di una risorsa etc... Ogni applicazione, in base alle proprie necessità, può allora servirsi di un preciso numero di ricevitori. Anche questo componente non dispone di un'interfaccia grafica. Va comunque detto che al verificarsi di un evento questo componente può avviare un'attività per la notifica all'utente (mediante la classe NotificationManager). Le notifiche possono anche aggiungere icone nella barra di stato di Android;
  • Fornitori (Content provider): questo componente offre a un'applicazione la possibilità di gestire e condividere dati (ad esempio in un database). Tale possibilità avviene estendendo la classe base ContentProvider (del package android.content) e implementando i metodi per l'inserimento e il recupero dei dati. Le applicazioni non possono tuttavia invocare direttamente i suddetti metodi ma possono accedere ai dati solo attraverso gli oggetti della classe ContentResolver.

martedì 8 febbraio 2011

Xfce 4.8: installazione su Xubunutu 10.04


In attesa di Natty Narwhal (Ubuntu 11.04), dove per Xubuntu si passerà di default ad Xfce 4.8, vediamo come provare con pochi comandi il nuovo ambiente per desktop. Per Ubuntu 10.04:

sudo add-apt-repository ppa:alexx2000/xfce
sudo apt-get update
sudo apt-get install xubuntu-desktop

Il primo comando aggiunge un repository per la distribuzione dei pacchetti (non esistendo ancora un repository ufficiale). E' un'operazione fondamentale per aggiornare in seguito il vostro sistema con nuovi pacchetti già compilati, soprattutto se non volete compilare personalmente il codice sorgente (rilasciato qui). A tale proposito colgo l'occasione per ringraziare alexx2000 per aver svolto il processo di compilazione e pacchettizzazione di Xfce 4.8!
Il secondo comando procede, invece, all'aggiornamento del database locale per i pacchetti software disponibili. Dopo questa operazione il nostro sistema operativo saprà dove reperire i nuovi pacchetti per Xfce.
Il terzo comando, infine, procede all'installazione dell'ambiente desktop. Già dopo il secondo comando potrebbe comparire nell'area di notifica del pannello la disponibilità di nuovi pacchetti. Per Ubuntu 10.10:

sudo add-apt-repository ppa:koshi/xfce-4.8
sudo apt-get update
sudo apt-get install xfce4

Qui, invece, dovete ringraziare koshi! Il changelog di questa versione è davvero lungo, l'elenco completo può essere consultato qui. Thunar, il gestore di file, adesso supporta GVFS (un file system virtuale). Questo faciliterà la condivisione di file e cartelle (attraverso FTP o SSH, ad esempio) poiché avverrà direttamente all'interno di Thunar. E' stata aggiunta una nuova finestra per i processi di copia in parallelo. I dispositivi rimovibili hanno un bottone per l'operazione di umount. Il pannello è stato invece riscritto e la sua gestione è notevolmente migliorata! In Xfce 4.8 disponiamo, adesso, di un nuovo editor per la gestione dei componenti. Il pannello supporta inoltre un livello di trasparenza (possiamo regolarne sia l'opacità a fuoco che quella non a fuoco). Vi invito a consultare questa pagina per vedere le novità grafica di Xfce 4.8. Come sempre Xfce riesce a mantenere quello che promette: un ambiente leggero, veloce e gradevole da utilizzare!
Purtroppo alcuni dei vecchi plugin non sembrano funzionare, come ad esempio gli aggiornamenti meteo, free space checker e generic monitor. Dovendo tenere sotto controllo lo spazio disponibile sul mio Aspire One (che usa un disco SSD da 8GB) ho risolto in parte questo problema installando Conky (con il comando sudo apt-get install conky) e modificando il file /etc/conky/conky.conf in questo modo:

alignment middle_right
background no
border_width 1
cpu_avg_samples 2
default_color white
default_outline_color white
default_shade_color white
draw_borders no
draw_graph_borders yes
draw_outline no
draw_shades no
use_xft yes
xftfont Sans:size=10
override_utf8_locale yes
gap_x 10
gap_y 10
minimum_size 180 0
net_avg_samples 2
no_buffers yes
double_buffer yes
out_to_console no
own_window yes
own_window_class Conky
own_window_transparent yes
own_window_type desktop
own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager
stippled_borders 0
update_interval 2.0
uppercase no
use_spacer none
show_graph_scale no
show_graph_range no

TEXT
${color grey}CPU:${color} ${cpu cpu0}% ${alignr}${alignr}${cpubar 8,80 cpu}
${color grey}RAM:${color} $mem/$memmax ($memperc%) ${alignr}${membar 8,80}
${color grey}SWAP:${color} $swap/$swapmax ($swapperc%) ${alignr}${swapbar 8,80}
${color grey}SSD:${color} ${fs_free /root}/${fs_size /root} ($fs_used_perc%) ${alignr}${fs_bar 8,80 /}

${color grey}Download:${color} ${downspeedf wlan0} KB/s
${alignc}${downspeedgraph wlan0 25,200}
${color grey}Upload:${color} ${upspeedf wlan0} KB/s
${alignc}${upspeedgraph wlan0 25,200}