In questo articolo mostreremo come creare un'applicazione con PhoneGap e come estendere le sue funzionalità, concentrando il lavoro su piattaforma Android.
PhoneGap è uno strumento di sviluppo open source, creato da Nitobi, per fare da ponte tra le applicazioni Web e i dispositivi mobili. Con PhoneGap possiamo scrivere un'applicazione mobile sfruttando HTML, Javascript e CSS, ma anche utilizzare le principali risorse del dispositivo, quali file system, fotocamera, accelerometro, gps o multitouch.
>> Leggi la guida completa allo sviluppo su Apache Cordova (Phonegap)
Hello PhoneGap!
Iniziamo impostando il nostro ambiente di lavoro e perm prima cosa scarichiamo ed installiamo PhoneGap.
Procediamo quindi creando il primo progetto su Eclipse e aggiungendo la libreria esterna dedicata ad Android e il gioco è fatto. Proviamo ora a creare un classico Hello World
di prova.
Nell'archivio zip di Phonegap, cerchiamo la cartella "xml", che contiene la lista dei plugin attivi, e la copiamo nella nostra cartella di risorse "res". Creiamo quindi una cartella chiamata "www", come sottocartella della directory "assets" del progetto e copiamo la libreria phonegap-1.0.0.js
. In quest'ultima cartella creiamo una semplice pagina Html con scritto "Hello World!"
impostando anche uno stile adeguato. Questa cartella rappresenterà la root della nostra applicazione.
Creiamo dunque un nuovo progetto Android con una nuova activity HelloGapActivity
importando com.phonegap.*;
ed estendendo da DroidGap. Infine sarà sufficente richiamare:
super.loadUrl("file:///android_asset/www/index.html");
Da questo momento possiamo dedicarci escusivamente alla parte Html. Nell'header
della pagina includiamo phonegap-1.0.0.js
e un semplice script di prova che utilizza PhoneGap per accedere alle informazioni del dispositivo:
<script type="text/javascript" charset="utf-8">
var deviceInfo = function() {
document.getElementById("platform").innerHTML = device.platform;
document.getElementById("version").innerHTML = device.version;
document.getElementById("uuid").innerHTML = device.uuid;
document.getElementById("name").innerHTML = device.name;
document.getElementById("width").innerHTML = screen.width;
document.getElementById("height").innerHTML = screen.height;
document.getElementById("colorDepth").innerHTML = screen.colorDepth;
};
function init() {
document.addEventListener("deviceready", deviceInfo, true);
};
</script>
Nella funzione init()
, richiamata al load del body, aggiungiamo un listener all'evento deviceready
che chiamerà deviceInfo()
appena il dispositivo sarà pronto. Questa funzione non fa altro che accedere alle informazioni del device sul quale sta girando la vostra applicazione e sul relatvo schermo. Le informazioni come vediamo sono contenute in due apposite strutture screen e device. Lanciate la vostra applicazione ed avrete un risultato simile a questo:
Figura 1. Hello World con PhoneGap
Questo piccolo esempio, oltre ad introdurre PhoneGap, mostra tutta la semplicità di questo strumento: come vedremo tra poco, accedere alle funzioni del dispositivo è semplice e si baserà spesso su chiamate asincrone e relative definizioni di callback in caso di successo e di insuccesso, alle quali verrano passati dei parametri che potremo riutilizzare. Potete trovare tutta la documentazione sul sito di PhoneGap.
Realizziamo una applicazione
Adesso inizieremo lo sviluppo di una vera e propria applicazione, costruita interamente con HTML, CSS e Javascript. L'applicazione in questione, che trovate allegata, ha lo scopo di scattare una foto e selezionare una cornice da sovrapporre ad essa.
Infine tale foto sarà salvata nella sdcard del dispositivo. Vedremo quindi come anche jQuery potrà esserci d'aiuto per migliorare l'esperienza utente nella nostra applicazione.
Impostiamo ora nella pagina di index
il layout, includendo un apposito CSS, le librerie jQuery, Phonegap e tutte le altre librerie utilizzate di contorno, ad esempio Pixastic per l'editing delle immagini e Slide per creare appunto l'effetto slide. Abbiamo quindi 2 pulsanti, quello per scattare la foto e quello per visualizzare la galleria delle cornici che inizialmente risulterà invisibile.
Il primo pulsante richiamerà la funzione show_pic
che tramite PhoneGap si collegherà alla nostra fotocamera, attraverso questo codice:
navigator.camera.getPicture(dump_pic, fail, {
quality : 50, destinationType: Camera.DestinationType.FILE_URI
});
Come possiamo vedere PhoneGap mette a disposizione l'oggetto Camera
per eseguire tutte le operazioni con la fotocamera del nostro dispositivo. Sarà sufficiente richiamare il metodo getPicture
passandogli due callback, la prima in caso di successo, la seconda in caso di fallimento, e una lista di parametri, la qualità dell'immagine e il tipo di risorsa restituita alla callback di successo.
Camera.DestinationType.FILE_URI
specifica l'URI del file di destinazione, in alternativa potremmo farci restituire i dati e applicarli al campo src
del nostro canvas. Adesso definiamo la funzione callback di successo.
function dump_pic(file) {
resizeImg(file);
}
Come parametro in ingresso riceve l'URI di cui sopra, che viene passata alla routine di resizeImg
per ridimensionare l'immagine altrimenti troppo grande. La routine di fail
si limita invece a loggare il messaggio di errore e lanciare un alert con tale messaggio.
function fail(msg) {
console.log(msg.code);
alert(msg);
}
In questo caso abbiamo utilizzato la funzione javascript alert
, ma è possibile ricorrere ad oggetti PhoneGap per avere una finestra più strutturata con titolo e testo per il pulsante, ecco un esempio:
function fail(msg) {
console.log(msg.code);
try{
navigator.notification.alert(msg, alertCallback, "Titolo", "Testo del pulsante");
}
catch (e) {
alert(msg);
}
}
Il blocco try catch
permette di poter eseguire questa funzione anche su un normale browser che non dispone di PhoneGap. Infine per loggare qualsiasi messaggio basta ricorrere all'oggetto console
e richiamare il metodo log.
Torniamo al nostro programma. Nella funzione resizeImg
rendiamo visibile il pulsante delle cornici e mostriamo nella pagina la nostra foto appena scattata e ridimensionata. Come mostrato nella pagina index, tra il pulsante per scattare una foto e quello per visualizzare le cornici, abbiamo inserito 3 miniature delle cornici racchiuse in un tag <ul>
: questo trick ci permette di far comparire le miniature con l'effetto slide al click del pulsante.
Ognuna delle miniature ha associata la funzione blending
al click, procedura che, sempre sfruttando pixastic, permetterà di sovrapporre la cornice scelta all'immagine appena fotografata, passando come parametro l'immagine intera che si trova nella cartella "cornici".
Come ultima funzionalità vogliamo avere la possibilità di salvare la nostra foto con cornice annessa, ma l'unica possibilità per farlo è quella di creare un proprio plugin per estendere PhoneGap.
Link utili
Estendere PhoneGap
Creare un plugin per PhoneGap non è complicato, ma richiede comunque una preparazione di base nell'uso
dell'sdk per Android, o in generale della piattaforma sulla quale vorrete crearlo.
Il plugin che svilupperemo sarà SaveImage
e lo potete trovare nell'esempio allegato.
Il funzionamento del nostro plugin è molto semplice: avrà in input i dati relativi alla posizione nella pagina e alla
dimensione dell'immagine da salvare, dopodichè creerà un array di byte presi dalla WebView che utilizza PhoneGap e li
salverà in un file.
Creiamo quindi un nuovo progetto PhoneGap con 2 classi: SaveImageActivity, che sarà la nostra activity di test,
e SaveImagePlugin che sarà la classe del nostro Plugin. Importiamo ora i necessari packages:
import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;
import com.phonegap.api.PluginResult.Status;
ed estendiamo la classe Plugin con la nostra SaveImagePlugin
public class SaveImagePlugin extends Plugin
Dovrete quindi aggiungere il metodo execute
, che sarà il cuore del nostro plugin:
public PluginResult execute(String action, JSONArray data, String callbackId)
Il primo parametro, action
, è indica l'azione che vogliamo far eseguire al nostro plugin. Infatti esso può
eseguire infinite azioni, nel nostro caso ci basterà definire l'azione "save". Il secondo parametro, data
, invece
rappresenta un array JSON di parametri che passeremo al plugin, nel nostro caso saranno la path di destinazione del file e tutti i
dati relativi all'immagine.
Vediamo adesso come implementare la parte di Javascript.
Creiamo in assets/www
la nostra libreria saveimage.js
e definiamo il prototipo della funzione save
in questo modo:
SaveImage.prototype.save = function(path, canvas, mimeType, successCallback, failureCallback)
Quindi chiunque voglia utilizzare il metodo "save" nel nostro plugin deve passare la path di destinazione, la canvas, il mimeType (png o jpeg),
la callback in caso di successo e quella in caso di fallimento. All'interno di questa funzione richiameremo il cuore del nostro plugin creato
prima in questo modo:
return PhoneGap.exec(successCallback, failureCallback,
'SaveImagePlugin', 'save',
[path, canvasProps.mimeType,
canvasProps.xpos, canvasProps.ypos,
canvasProps.width, canvasProps.height, canvasProps.screenWidth]);
La funzione chiave che permette di eseguire l'azione è exec
di PhoneGap, che riceve in input una callback di successo,
una di fallimento, il nome della classe Java del plugin, l'azione da eseguire e un'array JSON di parametri. A questo punto il controllo passa al
nostro plugin Java. In questa libreria troverete anche ulteriori istruzioni che servono a PhoneGap per registrare il servizio e la classe del
plugin, rimando al codice per approfondimenti.
Come ultima cosa aprite adesso il file res/xml/plugin
e aggiungete questa riga:
<plugin name="SaveImagePlugin" value="com.phonegap.plugin.saveimage.SaveImagePlugin"/>
Adesso resta solo da richiamare il nostro codice nell'html. Nel file di esempio abbiamo creato una funzione saveMe
definita in questo modo:
function saveMe() {
var cat = document.getElementById("test_img");
window.plugins.saveimage.save("/sdcard/cat.png", cat, "image/png", function(r){printResult(r)},
function(e){log(e)});
}
Importare il plugin nel progetto
Non rimane che importare il nostro nuovo plugin all'interno della nostra applicazione. Copiamo la cartella SaveImage/src/com/phonegap
in CorniceDroid/src/com
, includiamo saveimage.js
in assets/www
e modifichiamo il file xml, come abbiamo fatto
in precedenza. Adesso il nostro plugin è pronto all'uso, e abbiamo nel progetto anche il codice per poterlo modificare se necessario.
Per prima cosa dobbiamo riprendere il listener visto in precedenza che chiama una callback appena il dispositivo è pronto e creare una
cartella nella nostra sdcard chiamata "cornicidroid" dove andremo a salvare i nostri lavori. Quindi sempre in main.js
andiamo ad aggiungere:
function init() {
document.addEventListener("deviceready", setEnv, true);
}
function setEnv() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, saveFolder, fail);
}
function saveFolder(fs) {
var entry=fs.root;
entry.getDirectory("cornicedroid", {create: true, exclusive: false}, successSave, fail);
}
E richiamiamo init()
al load del body. Una volta che il dispositivo è pronto, eseguiamo una richiesta per ottenere
il controllo del file system, in particolare della parte persistente e andiamo a creare la nostra directory nella root
(i flag stanno ad indicare di usare, se esiste, la cartella con il nome specificato o crearla altrimenti).
Aggiungiamo quindi al nostro index una scritta cliccabile:
<p onclick="saveMe()">Clicca qui per salvare l'immagine</p>
e definiamo anche in questo caso la nostra funzione di salvataggio:
<script type="text/javascript" charset="utf-8">
function success_save(msg) {
try{
navigator.notification.alert("Immagine salvata con successo", null, "Risultato");
}catch (e) {
alert(msg);
}
};
function failed_save(msg) {
try{
navigator.notification.alert("Errore!", null, "Risultato");
}catch (e) {
alert(msg);
}
};
function saveMe() {
var cat = document.getElementById("test_img");
var date_now = new Date();
window.plugins.saveimage.save("/sdcard/cornicedroid/" + date_now.getTime() + ".png",
cat, "image/png", success_save, failed_save);
};
</script>
Molto simile alla procedura di test del nostro plugin, solo che in questo caso andremo a salvare le nostre foto nella cartella assegnata
all'applicazione con un nome del file generato dai millisecondi presi dall'oggetto date_now. La nostra prima applicazione con
PhoneGap è pronta!
Conclusioni
PhoneGap è un nuovo grande strumento di sviluppo per il mondo mobile, la sua estendibilità e semplicità, la possibilità
di utilizzare linguaggi come Javascript, HTML e CSS, aumenterà il numero di sviluppatori in questo nuovo settore. Se volete inziare lo
sviluppo di PhoneGap e contribuire al progetto, rimandiamo alla pagina di Github
e al repository che raccoglie molti plugin.