sabato 21 gennaio 2012

Programmazione Android: I menù - Costruire una web application (terza parte)

Una piccola premessa: smartphone e tablet gestiscono i menù che vedremo in modo differente. Mentre i tablet mostrano i pulsanti del menù nella barra di titolo (TitleBar, quella eliminata dal tema FullScreen nel post precedente), gli smartphone esigono la pressione di un determinato tasto del telefono per mostrare a video il menù (per ovvie ragioni di spazio). Ovviamente se vogliamo mostrare su un tablet il menù, dovremo eliminare l'impostazione del tema "Fullscreen".
Ricordando i post precedenti, Android sfrutta perfettamente il modello MVC: la prima cosa da fare, quindi, è creare il layout del nostro menù personalizzato. Per fare ciò, per prima cosa bisogna creare una cartella "menu" sottocartella di "res". Selezionare la cartella appena creata e premere "Ctrl + N" oppure fare click con il pulsante destro e scegliere New->Other. Scegliere a questo punto Android XML File e cliccare su Next.

Nella schermata successiva dare un nome al file, ad esempio menubar.xml e fare click su "Finish". Eclipse a questo punto apre automaticamente l'editor per l'xml appena creato, riconoscendo che andrà a specificare la struttura di un menù. Basterà cliccare su "Add" e poi scegliere "Item" per aggiungere un elemento al menù. Ovviamente bisogna specificare:
  • Id: @+id/item_exit
    Tutti gli id iniziano per @+id/ e sono seguiti dal nome identificativo, in questo caso item_exit
  • Title e Title Condensed: Esci
    Sono il titolo e il titolo breve del menù, in questo caso "Esci"
  • Icon: @drawable/ic_exit
    L'icona associata al bottone. Android cercherà l'icona ic_exit.png sotto le cartelle res/drawable-*
Per il momento basta questa semplice configurazione. Ovviamente si dovrà spiegare ad Android quando e soprattutto in quale attività (Activity) questo menù dovrà essere mostrato. Per fare ciò, apriamo il file sorgente dell'attività principale (per chi non si ricordasse il primo post sull'argomento, il nome è webappActivity.java) e aggiungiamo questa funzione:
@Override
 public boolean onCreateOptionsMenu(Menu menu) {
     MenuInflater inflater = getMenuInflater();
     inflater.inflate(R.menu.menubar, menu);
     return true;
 }
Il codice crea un menù sulla base del file xml specificato (menubar, sotto la cartella menu). Adesso bisogna associare un determinato comportamento alla pressione dei vari bottoni del menù creato. Anche qui, un semplice override con un codice che discrimina l'id del pulsante premuto:
@Override
 public boolean onOptionsItemSelected(MenuItem item) {
     switch (item.getItemId()) {
         case R.id.item_exit:
          finish();
             return true;
         default:
             return super.onOptionsItemSelected(item);
     }
 }
La funzione finish() chiede ad Android di "terminare" l'attività corrente; se quest'ultima è quella principale, il sistema tornerà al menù principale (la home). In realtà, Android ha una gestione dei processi e della loro terminazione tutta sua, quindi anche se l'applicazione non viene mostrata a schermo, può essere che sia ancora in memoria.
Ed ora il risultato finale:
Questo è un esempio con un solo bottone nel menù; ovviamente basta ripetere le semplici operazioni precedenti per aggiungerne ad oltranza. Con una piccola restrizione: Android non mostra più di 6 bottoni. Tutti quelli che oltrepassano questa soglia vengono raccolti un un bottone magico "Altro".

martedì 17 gennaio 2012

Programmazione Android: Costruire una web application (seconda parte) - jQuery Mobile

In questa seconda parte incontriamo jQuery Mobile, una versione del famoso framework appositamente creata per gestire e mostrare contenuti per dispositivi quali smartphone e tablet. E' possibile analizzarne il comportamento accedendo alla demo disponibile, che mostra tutti i componenti utili per realizzare una splendida web application. Ovviamente la cosa più semplice è scaricare l'intero framework, caricarlo sul sito che farà da base per l'applicazione web, studiarsi il sorgente html + javascript della demo e modificarlo a piacimento; vediamo però a grandi linee quale sia la struttura:
Header
<!DOCTYPE html> 
<html> 
 <head> 
 <title>My Page</title> 
 <meta name="viewport" content="width=device-width, initial-scale=1"> 
 <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css" />
 <script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
 <script src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js"></script>
</head> 
Fino a qui niente di particolare: in sostanza il caricamento delle librerie necessarie al funzionamento di jQuery Mobile. Da notare però la parola chiave "viewport" all'interno di un meta tag, fondamentale per l'impostazione delle dimensioni dello schermo per il risultato finale html.

Body
<body> 

<div data-role="page">

 <div data-role="header">
  <h1>My Title</h1>
 </div><!-- /header -->

 <div data-role="content"> 
  <p>Hello world</p>  
 </div><!-- /content -->

</div><!-- /page -->

</body>
</html>
Da questa parte di codice si comprende come una pagina sia indicata come una div con attributo "data-role" impostato su "page". La barra di navigazione in alto a sua volta avrà ruolo "header", mentre il contenuto vero e proprio della pagina avrà ruolo "content".

L'idea di base è quella di mostrare un sito (o una sezione di sito) appositamente sviluppato con jQuery Mobile all'interno dell'applicazione Android; all'utente sarà quindi invisibile se questa parte sia sviluppata con il framework Android o con il più immediato e graficamente appagante html, css e javascript. Ovviamente, riprendendo il codice del post precedente, è sufficiente modificare la pagina alla quale l'oggetto webView si deve connettere:
webView1.loadUrl("http://code.jquery.com/mobile/latest/demos/");
Ho chiaramente usato l'url del demo per semplicità; andrà sostituito con la parte del sito mobile che avrete destinato ad Android (ad esempio, www.example.com/android).
Per terminare questa parte, mostro un piccolo accorgimento grafico: se si prova ad eseguire l'applicazione android creata in precedenza si nota una fastidiosa barra in alto, con il nome dell'applicazione. Questa barra può essere migliorata graficamente (e lo mostrerò nei post successivi) oppure, più facilmente, può essere nascosta. Per fare quest'ultima operazione è sufficiente aprire il file manifest AndroidManifest.xml e creare, all'interno del tag activity principale, l'attributo "android:theme", impostandolo ad un determinato valore. Vediamo il risultato:
<?xml version="1.0" encoding="utf-8"?>  
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    package="net.stefanobianchini.webapp"  
    android:versionCode="1"  
    android:versionName="1.0" >  
  
    <uses-sdk android:minSdkVersion="10" />  
    <uses-permission android:name="android.permission.INTERNET"/>  
    <application  
        android:icon="@drawable/ic_webapp"  
        android:label="@string/app_name" >  
        <activity  
            android:name=".webappActivity"  
            android:label="@string/app_name" 
            android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">  
            <intent-filter>  
                <action android:name="android.intent.action.MAIN" />  
  
                <category android:name="android.intent.category.LAUNCHER" />  
            </intent-filter>  
        </activity>  
    </application>  
  
</manifest>
Questa direttiva chiederà ad Android di mostrare l'applicazione a tutto schermo, senza la fastidiosa TitleBar. In figura il risultato finale, visualizzato dentro l'emulatore:

lunedì 16 gennaio 2012

Programmazione Android: Costruire una web application (prima parte)

Grazie al regalo di Natale di mia moglie (un tablet Acer Iconia Tab A500), ultimamente mi sono interessato alla programmazione di applicazioni Android. questo è il primo di una serie di post in cui affronterò l'ambiente android ed in particolare lo sviluppo di applicazioni Web per android, un misto tra applicazioni android ed applicazioni Web. Tralascio volutamente tutta la parte relativa alla preparazione dell'ambiente di sviluppo, ampiamente disponibile via web; l'unica cosa a cui accenno è che è necessario fornirsi di:

Preparato l'ambiente, Eclipse è ora in grado di gestire al meglio i progetti Android. Per iniziare un nuovo progetto, File ->New->Project e selezioniamo Android Project.
Quindi diamo un nome al progetto (ad esempio, webapp) e selezioniamo la versione dell'sdk di riferimento. I tablet in commercio attualmente sono equipaggiati della versione 3.2 (Honeycomb), ma molti telefoni hanno ancora la versione 2.3, ragion per cui io scelgo di sviluppare con una versione meno recente, come si vede in figura.
Successivamente verrà chiesto il package, è norma utilizzare tre parole separate dal punto ".", ad esempio net.stefanobianchini.applicazioneweb. Lo scheletro del progetto è quindi pronto.

L'icona
Una applicazione che si rispetti ha bisogno di un'icona giusta. Cercate un'icona 72x72 pixel in formato png che più rappresenta la vostra applicazione e posizionatela sotto res/drawable-hdpi (qui una spiegazione sulle directory delle risorse grafiche), chiamandola ad esempio ic_webapp.png. A questo punto si apre il file AndroidManifest.xml e nella sezione application->application attributes->icon impostare @drawable/ic_webapp. Questa configurazione chiederà ad android di utilizzare l'immagine che avete scelto come icona nel menù principale, una volta che l'applicazione sarà installata. La modifica è simile anche se si sceglie di modificare direttamente l'xml anziché utilizzare il wizard dell'ADT.

I permessi
Fondamentale per lo sviluppo Android è la corretta gestione dei permessi. Una applicazione ha bisogno di permessi particolari, infatti, per collegarsi ad internet, usare il GPS, la fotocamera eccetera. Il consenso al rilascio di questi permessi viene effettuato al momento dell'installazione da parte dell'utente. Ma dobbiamo spiegare ad Android di quali permessi ha bisogno la nostra applicazione! Nel nostro caso, solo dei permessi della navigazione internet. Apriamo quindi il manifest (AndroidManifest.xml) e cerchiamo la parte "Permission": cliccando su "Add" si selezione "Uses Permission" e poi "Android.Permission.Internet". Tutto qua, niente di trascendentale.

Vediamo quindi il risultato xml di queste modifiche:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.stefanobianchini.webapp"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:icon="@drawable/ic_webapp"
        android:label="@string/app_name" >
        <activity
            android:name=".webappActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Come si vede dall'xml, il nome che sarà visualizzato nel menù di android che identificherà l'applicazione è un valore chiamato app_name all'interno delle risorse stringa del progetto. Le risorse stringa sono simili alle risorse grafiche (drawable), è praticamente un file xml con coppie di nomi - valori. Se apriamo il file res->values->strings.xml possiamo modificare il valore della stringa app_name, in modo da personalizzarla:

Il Layout
Android predilige il modello MVC, quindi il layout sarà separato dalla parte del funzionamento dell'applicazione. E cosa meglio di XML per disegnare i vari componenti grafici dell'applicazione? Ovviamente si può anche sfruttare l'editor visuale di Eclipse che dà una bella mano. La parte grafica si trova sotto res->layout e poiché Eclipse già crea nel progetto base una impaginazione "Hello World", basterà modificare il file main.xml già presente. Nel nostro caso è molto, molto semplice: eliminiamo la textview esistente ed andiamo ad inserire un componente magico, chiamato WebView (sotto la linguetta Composite).
Un'occhiata al risultato xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <WebView
        android:id="@+id/webView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>
Come si vede dalla figura, Eclipse ha chiamato il componente appena inserito "webView1". Ovviamente il nome può essere cambiato.

Il codice sorgente
Ora che tutto è pronto, diamo una occhiata al comportamento che l'applicazione deve adottare. Apriamo il file creato automaticamente webappActivity.java (ovviamente, se il progetto si chiama pincopallino il file che eclipse creerà automaticamente sarà nominato pincopallinoActivity.java). Iniziamo dalla base: appena l'applicazione viene lanciata, viene eseguito un metodo standard chiamato onCreate() dell'attività scelta per essere la principale (ossia quella eseguita per prima). Questo metodo viene reimplementato (override) e possiamo inserire dentro tutte le istruzioni utili al funzionamento base dell'applicazione, non prima però di aver definito una variabile pubblica relativa all'oggetto webview:
public WebView webView1;
/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //istruzione che imposta il layout main.xml
        setContentView(R.layout.main);      
        //ottengo l'oggetto webview
        webView1 = (WebView) findViewById(R.id.webView1);
        //Attivo il supporto javascript
        webView1.getSettings().setJavaScriptEnabled(true);
        //Carico la pagina desiderata
        webView1.loadUrl("http://www.stefanobianchini.net");
    }
E la prima funzione di base è pronta: ora però vogliamo che, navigando tra le pagine, la pressione del pulsante indietro del sistema android permetta di navigare nella cronologia anziché tornare al menù principale. Questo può essere fatto attraverso un override semplice:
@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && webView1.canGoBack()) {
         webView1.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
Bene. L'applicazione ha già la sua funzionalità di base, come si comprende se viene eseguito il progetto da Eclipse nell'emulatore. Se però si carica l'applicazione su un device, aprendo e chiudendo l'applicazione si possono avere dei problemi: questo perché l'applicazione, quando si torna al menù principale del sistema, viene messa in pausa automaticamente dall'OS Android. Per risolvere questo problema bastano poche righe di codice:
public void onResume() {
       super.onResume();
       if (webView1 != null) {
        webView1.resumeTimers();
       }
     }

    public void onPause() {
       super.onPause();
       if (webView1 != null) {
        webView1.pauseTimers();
       }
     }

Ora l'applicazione è funzionante. Nei futuri post spiegherò come utilizzare un framework per lo sviluppo di applicazioni web mobile (jquery mobile), ossia simulare una applicazione vera e propria via internet. Inoltre verranno integrate piccole migliorie all'applicazione base mostrata in questo post, come ad esempio un pulsante esci, un pulsante home, una finestra di caricamento e magia delle magie, un ponte che collega javascript al codice java della nostra applicazione android, ovvero come eseguire comandi java dal una pagina web per android. Questo ovviamente apre vasti scenari (utlizzo della fotocamera, GPS eccetera). Ovviamente con i permessi opportuni :-)