24 agosto 2012

Check Check-It!

Finalmente dopo tanto tempo speso a lavorare con Android, pubblico anch'io la mia prima app!
Come molti, mi son buttata su qualcosa di semplice, per capire i meccanismi che stanno dietro a Google Play (sembrerà strano, ma personalmente non avevo ancora pubblicato nulla). Si tratta, infatti, di una semplice app per gestire note e todo list che guarda caso si chiama Check-It!

"Tutto qua?" Starete pensando. Ebbene sì, ma con una piccola chicca. La creazione, cancellazione, spunta e il ritorno alla schermata principale si effettuano tramite 'gesti'. In poche parole si disegna il comando che si desidera impartire all'applicazione invece che andarlo a selezionare da un menù a tendina o da una lista di icone. Questo dovrebbe permettere un uso più rapido dell'app ed evitare di riempire il piccolo schermo dello smartphone di troppe immagini, non sempre facilmente selezionabili e/o differenziabili.
Alcuni comandi impartibili tramite gesti:


AGGIUNGERE UNA NUOVA NOTA
Per aggiungere una nuova nota basta disegnare un "+"










SALVARE UNA NUOVA NOTA
Per salvare una nota, basta disegnare una "S"










E così via...
Al momento l'app è davvero basilare, ma ho intenzione di sviluppare il concept e di aggiungere alcune funzioni come la modifica delle note create e una risposta aptica al riconoscimento del comando. Se la cosa vi ha incuriosito, scaricatela da Google Play (è gratuita) e lasciatemi un commento. Critiche e consigli son ben accetti :)

19 aprile 2012

Sfarfallio ATI Radeon Xpress 200M su linux

Dopo tanto parlare di Android, ecco una breve guida su linux che spero torni utile a quanti come me hanno avuto (e tutt'ora hanno) problemi con la scheda video ATI Radeon Xpress 200M.

Nel mio caso, la scheda video in questione è montata su di un Acer Aspire 5102WLMi (serie 5100) del 2006. Il problema si presenta immancabilmente dopo essere ritornati dalla sospensione in RAM con uno sfarfallio talmente marcato da rendere impossibile l'utilizzo del portatile e costringere al riavvio forzato.
Finalmente, dopo anni, ho trovato una soluzione che voglio condividere con quanti non hanno perso la speranza di risolvere questo fastidiosissimo problema.

Potete trovare la soluzione in inglese a questo indirizzo, post #11. Di seguito invece il mio mini-tutorial in italiano:


PROBLEMA
Sugli Acer Aspire 5100 con scheda video ATI Xpress 200M e linux per 64bit, mandare in sospensione il portatile e ripristinarlo provoca sfarfallii e tremolii molto marcati, tanto da richiedere il riavvio forzato della macchina.

SOLUZIONE
utilizzare il seguente comando da root:
pm-suspend --quirk-radeon-off --quirk-vbemode-restore --quirk-vbestate-restore --quirk-vbe-post
Questo comando dovrebbe mandarvi il portatile in sospensione. A questo punto provate a riattivarlo premendo un tasto qualsiasi: lo sfarfallio dovrebbe essere scomparso :)

Se il comando precedente ha fatto il suo lavoro, provate ad eseguirlo di nuovo aggiungendo:
--store-quirks-as-lkw
In questo modo le opzioni verranno salvate e utilizzate ad ogni futura sospensione.
Spero che questo risolva definitivamente il problema anche sulla vostra macchina :)


APPROFONDIMENTO
Se volete approfondire, di seguito trovate una breve spiegazione delle opzioni utilizzate.

--quirk-radeon-off: Forza l'hardware Radeon a spegnere il display durante la sospensione e a riaccenderlo al ripristino.

--quirk-vbemode-restore: Salva e ripristina la modalità VESA corrente. Può rendersi necessario per impedire la corruzione di X.

--quirk-vbestate-restore: Salva e ripristina degli stati hardware di basso livello che potrebbero essere invalidati dopo la sospensione.

--quirk-vbe-post: Prova a re-inizializzare la scheda video durante il riavvio da sospensione, utilizzando lo stesso codice che usa il BIOS durante il boot.

--store-quirks-as-lkw: Salva i quirks in /etc/pm/last_known_working.quirkdb.

2 marzo 2012

Gesti composti con Gestures Builder

Recentemente ho cominciato ad approfondire alcuni aspetti un po' più avanzati delle API Android e tra questi mi ha subito incuriosito la possibilità di creare gesti personalizzati attraverso il Gestures Builder, uno strumento presente all'interno dell'emulatore che viene caricato automaticamente all'avvio se si è aggiunta una scheda di memoria SD virtuale al sistema emulato.
L'utilizzo del Gestures Builder e dei metodi per riconoscere i gesti personalizzati è spiegato molto bene in questo tutorial presente sul sito ufficiale per sviluppatori, per cui eviterò una descrizione approfondita di tali aspetti in questa sede.
Ho però riscontrato alcune difficoltà nell'utilizzo del Gestures Builder (altrimenti che scrivevo a fare questo post? ^_^) una volta che ho voluto cimentarmi con l'utilizzo di gesti composti. Per gesti composti intendo tutti quei gesti che per essere eseguiti hanno bisogno che il dito si alzi dalla superficie touch e si posi ad un certa distanza. Pensate a come disegnereste un " + " o una " x ". Ecco, questi gesti!

Ovviamente sul sito ufficiale nemmeno l'ombra di una spiegazione, perché evidentemente il problema non si dovrebbe nemmeno porre. In teoria i gesti composti vengono tranquillamente rilevati dal tool e salvati, esattamente come tutti gli altri gesti. In realtà, a meno di essere davvero veloci, risulta molto difficile create gesti composti attraverso il mouse su emulatore e quindi il primo pezzo del nostro gesto scomparirà prima di riuscire a completare l'operazione.
La soluzione è abbastanza semplice, ma per risolvere il problema dovrete scaricare gli esempi forniti attraverso SDK Manager per la versione delle API con cui state sviluppando l'applicazione.
Se siete interessati alla spiegazione originale che ho utilizzato per questo mini-tutorial, la potete trovare qui

UNO: LOCALIZZARE I SORGENTI DI GESTURES BUILDER
Una volta scaricati gli esempi, in inglese "sample for SDK", dovrete andare a cercare la cartella in cui sono stati salvati. Generalmente si trovano all'interno della cartella dell'SDK sotto:
samples/android-#/ 
dove # sta per la versione di API che state utilizzando. All'interno troverete una cartella chiamata Gestures Builder: quelli sono i sorgenti del tool.

DUE: IMPORTARE I SORGENTI COME PROGETTO ANDROID
Per importare i sorgenti all'interno di Eclipse create un nuovo progetto del tipo "Android Sample Project". Eclipse vi aiuterà con una creazione guidata del progetto. Seguitela e vi ritroverete a scegliere direttamente il sorgente per il Gestures Builder.

TRE: MODIFICARE IL FILE create_gesture.xml
A questo punto aprite il file res/layout/create_gesture.xml, trovate l'elemento android.gesture.GestureOverlayView ed aggiungete tra i parametri android:fadeOffset="1000".  Nel mio caso ho scelto di inserire un'attesa di 1 secondo (1000ms = 1s) prima della scomparsa del precedente gesto, ma potete inserire un valore a piacimento.
Salvate e avviate il progetto sull'emulatore.

A questo punto siete pronti per seguire il tutorial ufficiale e creare tutti i vostri bellissimo gesti composti :)

9 novembre 2011

Fragments of Android Ice Cream Sandwich

Ed eccomi con una nuova piccola nota sullo sviluppo Android.
Dopo aver finito la mia prima app per Android 2.2, ho pensato bene di renderla compatibile con Android Ice Cream Sandwich e ottimizzarla anche per tablet. Tralasciando i problemi che ha l'emulatore sotto OS X 10.6 (diciamo solo che va una volta su 10 e ha tempi di caricamento biblici -_-), sto comunque avendo delle difficoltà a capire il funzionamento dei Fragment.
I Fragment sono una funzionalità aggiunta in Honeycomb e dovrebbero rendere la gestione dell'interfaccia grafica più semplice per i programmatori. In realtà, essendoci veramente pochi esempi in giro per la rete (personalmente ne ho trovato solo uno replicato all'infinito) risulta difficile capire esattamente come vadano usati. E qui arriviamo all'ultimo di una serie di difficoltà che ho riscontrato nel loro utilizzo.

Volendo inserire un fragment in maniera programmatica all'interno di un Activity, si legge sul sito ufficiale di Android, bisogna utilizzare la classe FragmentTransaction in questo modo:
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
peccato che si dimentichino di far notare che all'interno del metodo onCreateView della classe Fragment bisogna definire una View tramite il metodo inflate(int resource, ViewGroup root, boolean attachToRoot) passando false come ultimo parametro, pena il crash dell'applicazione, cioè:
public static class ExampleFragment extends Fragment {
    @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup
                                          container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.example_fragment, container,                                              false);
    }
}
Senza impostare il flag a false, la View così creata viene assegnata a root e non può essere richiamata all'interno dell'Activity in cui vorremmo inserire programmaticamente il Fragment e il programma si interrompe con un poco significativo:
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
Per ora è tutto, ma temo che tornerò presto per colpa di Android 4.
Stay Tuned :)

24 settembre 2011

Visualizzare un'immagine diversa per riga in una ListView Android

Dopo le vacanze, il TOEFL e il periodo esami, torno ad inserire una piccola guida, ricavata in ore e ore di ricerca sul web. Spero torni utile ad altri ;)

Recentemente ho ripreso in mano lo studio di Android e, visto che credo nell'utilità della pratica, ho pensato di creare una piccola applicazione; nulla di fantascientifico, ma abbastanza complessa da costringermi ad utilizzare le principali classi a disposizione.
Una delle opzioni che mi ha fatto più penare fino ad ora, è stata la visualizzazione di un'immagine diversa, in ogni riga di una ListView, a seconda di un determinato valore estratto da un database. In sè la cosa non dovrebbe essere particolarmente difficile, ma quando tentavo di richiedere ad Android l'ID dell'ImageView tramite cui visualizzare l'immagine, ricevevo sempre e comunque un NullPointerException.
Il codice originale che cercavo di utilizzare era qualcosa di questo tipo:
...
setContentView(R.layout.lista);
listaEventi = (ListView) findViewById(R.id.lista);
imageRow = (ImageView) findViewById(R.id.img_row);
imageRow.setImageDrawable(aDrawable);
// NullPointerException
cursor = db.query(somequery);
startManagingCursor(cursor);
adapter = new SimpleCursorAdapter(this, R.layout.row, cursor, FROM, TO);
listaEventi.setAdapter(adapter);
...
Il problema era che imageRow non veniva istanziato e quindi la successiva chiamata a setImageDrawable() generava un NullPointerException. All'inizio credevo si trattasse di un problema di ordine delle chiamate (dovevo prima settare l'adapter?), ma dopo svariate prove ho capito che il problema risiedeva proprio nell'uso del SimpleCursorAdapter: cedendo il controllo sulla generazione delle singole righe della ListView al SimpleCursorAdapter, dovevo trovare il modo di dire a quell'adapter come gestire ImageView presente all'interno di R.layout.row.
La soluzione, dopo due giorni di smanettamenti, è arrivata grazie al libro Learning Android di Marko Gargenta (a proposito, ottimo libro per principianti ^_-):
In pratica bisogna passare all'adapter un parametro di tipo ViewBinder in cui è inserita l'implementazione di setViewValue() che verrà poi utilizzata per personalizzare il comportamento dell'adapter  nella gestione delle View. Non avete capito cosa intendo? Effettivamente anch'io all'inizio ero perplessa, perciò ecco a voi un esempio concreto:

Questo è il parametro da passare all'adapter. Si, avete letto bene: è un parametro!
static final ViewBinder VIEW_BINDER = new ViewBinder(){
   public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
      if(view.getId() != R.id.img_row)
         return false;
      int type = cursor.getInt(columnIndex);
      ImageView image = (ImageView)view;
      switch(type){
      case 0:
         image.setImageResource(R.drawable.pippo);
         return true;
      case 1:
         image.setImageResource(R.drawable.pluto);
         return true;
      default:
         return true;
      }
   }
};
E questo è il codice precedente, modificato correttamente. Ora funziona :)
...
setContentView(R.layout.lista);
listaEventi = (ListView) findViewById(R.id.lista);
cursor = db.query(somequery);
startManagingCursor(cursor);
adapter = new SimpleCursorAdapter(this, R.layout.row, cursor, FROM, TO);
adapter.setViewBinder(VIEW_BINDER); // Importante
listaEventi.setAdapter(adapter);
...
Ora avete capito cosa intendevo? ^_^
Personalmente è la prima volta che mi capita di trovare una soluzione del genere e, senza l'esempio del sopraccitato libro, non credo ci sarei mai arrivata, nemmeno leggendo da cima a fondo la documentazione. Conoscete altri esempi dove viene utilizzato un parametro in maniera simile a questa, oppure è solo una chicca di Android?

8 luglio 2011

Usare libreria RXTX su Snow Leopard

Non so per quale motivo, ma è un periodo che devo continuamente penare per far funzionare su OS X quello che mi serve per i miei progetti e siccome so cosa significhi passare ore alla ricerca di qualche blogger di buon cuore che abbia condiviso con il mondo la soluzione, non posso fare a meno di scrivere un post per ogni nuova esperienza acquisita. Questa volta parliamo della libreria Java RXTX per la comunicazione con porte seriali.

Volendo passare a qualcosa di più della semplice accensione temporizzata di LED tramite Arduino, ci si imbatte subito nella comunicazione tramite porta seriale che, lato microcontrollore, è gestita egreggiamente dalle librerie standard della piattaforma mentre, lato computer, è più o meno banale a seconda del linguaggio scelto.
Prevedendo una possibile integrazione con alcune funzionalità offerte dalla libreria WiiRemoteJ ho pensato bene di utilizzare Java e quindi la libreria RXTX che dovrebbe sostituisce le funzionalità delle Java Communication API. Ovviamente essendo su OS X 10.6 non poteva di certo andare tutto liscio e di fatti mi ritrovavo con il seguente errore, non appena cercavo di invocare la libreria:
java.lang.UnsatisfiedLinkError: /Library/Java/Extensions/librxtxSerial.jnilib: no suitable image found. Did find: /Library/Java/Extensions/librxtxSerial.jnilib: no matching architecture in universal wrapper thrown while loading gnu.io.RXTXCommDriver
Se avete scaricato dal sito ufficiale della libreria l'ultima versione, sapete che una volta estratta la cartella, vi ritroverete con due file: librxtxSerial.jnilib e RXTXcomm.jar. Il primo (.jnilib) va inserito in /Library/Java/Extensions/ mentre il secondo va inserito nel build path del vostro progetto Java.
Il problema però è proprio il file .jnilib che è stato compilato per 32bit ma non per 64bit (e ti pareva -_-). Per risolvere la questione potete scaricare dal sito ufficiale i sorgenti e compilarli per la vostra macchina oppure, se siete pigri, potete trovare il file già compilato sul sito di Robert Harder che ha gentilmente pensato di mettere a disposizione la versione per 64bit, qui.
A questo punto basta sostituire il file originale con quello scaricato dal blog precedentemente menzionato e voilà, il vostro codice funzionerà come per magia.

Spero che anche questa volta vi possa risultare utile questa piccola guida in italiano. Se vi è piaciuta (o se non vi è piaciuta), fatemelo sapere nei commenti. ^_-

P.s. piccola nota personale: mi chiedo come sia possibile che nonostante Snow Leopard sia in giro da qualche anno ormai, molte librerie Java non siano state aggiornate per 64bit. Con l'arrivo di Lion, cosa succederà?

7 luglio 2011

Wiimote e Bluecove: errore PSM

Come promesso ecco il secondo post sul tema Wiimote e bluecove.
Se avete già tentato di sperimentare con i due, vi sarete accorti che tentando di connettere il Wiimote al computer si riceve il seguente errore:
java.lang.IllegalArgumentException: PCM 11, PCM values restricted by JSR-82 to minimum 4097, see BlueCoveConfigProperties.PROPERTY_JSR_82_PSM_MINIMUM_OFF
Il problema è legato alla gestione del PSM da parte del Wiimote. Infatti il controller ha un PSM inferiore a 0x1001, limite inferiore posto dalle specifiche JSR-82 alle quali bluecove si attiene. Per risolvere è quindi necessario settare bluecove in modo tale da permettergli di ignorare tale restrizione, e questo è possibile inserendo nel codice, prima del tentativo di connessione, la seguente istruzione Java:
System.setProperty(BlueCoveConfigProperties.PROPERTY_JSR_82_PSM_MINIMUM_OFF, "true");
A questo punto il codice non dovrebbe più generare errori e il vostro Wiimote dovrebbe connettersi senza alcun problema.

6 luglio 2011

WiiRemoteJ sotto Snow Leopard

Come promesso torno con qualcosa di inerente alla programmazione, questa volta Java.
Ormai avrete capito che le mie attenzioni si rivolgono soprattutto verso l'interazione uomo-macchina e una delle cose, a mio parere, più divertenti in questo campo è il riutilizzo di un Wiimote come interfaccia.

Avevo già sperimentato un anno fa con il controller Nintendo e con la libreria Java WiiRemoteJ, realizzata da Michael Diamond (aka Cha0s) e scaricabile gratuitamente dal suo sito, ma poi avevo dovuto abbandonare il tutto a causa di mancanza di tempo e di problemi con la libreria. Dopo aver aggiornato a Mac OS X 10.6 infatti, continuavo a ricevere questo errore connesso al bluetooth:
java.lang.IllegalStateException: Bluetooth failed to initialize. There is probably a problem with your local Bluetooth stack or API.
che non sono riuscita a risolvere fino a ieri.

Avevo scelto WiiRemoteJ poiché tale libreria è compatibile con Windows, Linux e Mac OS X grazie al fatto che si appoggia su un altro componente, bluecove (implementazione delle specifiche JSR-82), che si occupa di interfacciarsi con i driver bluetooth della macchina su cui risiede.
Il problema era che da Snow Leopard in poi, lo stack bluetooth è diventato 64bit e la libreria bluecove veniva compilata solo per il 32bit (potete leggere la storia del bug qui). Il bug è stato risolto, ma non è ancora disponibile una versione stabile della libreria che contenga la soluzione.
Se volete far funzionare WiiRemoteJ su OS X 10.5 con Java 1.6 o su OS X 10.6 dovete utilizzare uno degli snapshot di bluecove a questo indirizzo, dal numero 61 in avanti.

Esiste ancora un piccolo problema da risolvere nell'utilizzo di bluecove e Wiimote prima di potersi mettere in pista con gli esperimenti, ma rimando ad un altro post.

Stay tuned ;)

22 giugno 2011

Random Thoughts

No, non sono sparita nel nulla come qualcuno di voi potrebbe aver pensato. L'università si porta via la maggior parte del tempo a disposizione e così il tempo per sperimentare è poco. Recentemente ho ripreso a guardare la mia Arduino UNO con gli occhi luccicanti, in previsione di chissà quali utilizzi. Mi sono dotata di un multimetro e di una Solviden (lampada ikea) perché vorrei provare a riutilizzare il piccolo modulo solare, ma ancora non ho le idee chiare. Appena avrò qualche aggiornamento su questo progetto, metterò un post dedicato.

Nel frattempo ho partecipato ad un piccolo corso sull'amministrazione di un sistema Linux organizzato da alcuni ragazzi dell'associazione POuL. Devo dire di essere rimasta davvero soddisfatta. Mi ha tolto molta della confusione che avevo in testa riguardo ai SO Linux e mi hanno mostrato alcuni tool davvero utili di cui non conoscevo l'esistenza. Sul loro sito ci sono slide e video delle quattro lezioni, disponibili gratuitamente.

Rimanendo in tema, venerdì 24 giugno (tra due giorni) il signor Richard Stallman sarà presente alla V Conferenza italiana sul software libero con un intervento dal titolo "A Free Digital Society". Studio permettendo mi piacerebbe parteciparvi.

Per questa volta solo qualche pensiero sparso. Spero di tornare presto con notizie sul progetto Arduino e qualche altra chicca software.

21 marzo 2011

Wireshark su Snow Leopard

Non so per quale motivo, ma Wireshark mi ha sempre creato qualche problema al momento dell'installazione su OS X. Dicono si tratti di problemi di permessi sulle interfacce ed effettivamente, una volta installato e avviato non viene rilevata nemmeno un'interfaccia dalla quale catturare pacchetti.
Su Leopard avevo risolto tempo fa, ma non ricordo più esattamente come e, infatti, una volta passata a Snow Leopard mi sono ritrovata punto e a capo. Mi ero illusa che avessero risolto il conflitto nelle realease più recenti ed invece quello che offrono è una semi-pezza.

All'interno del dmg di Wireshark 1.4.4 c'è una cartella chiamata ChmodBPF che va copiata tutta intera in /Library/StartupItems/ . Quello che fa questa cartella è semplicemente settare all'avvio i permessi necessari perchè Wireshark possa vedere le interfacce. Quello che però succede è che questa cartella non ha i permessi necessari per settare un bel niente. Infatti riavviando il computer vi apparirà una bella finestra che vi avvisa che ChmodBPF non è stato avviato ("Insecure Startup Item disabled"). Tutto ciò non è comico? XD
Effettivamente nemmeno io l'ho trovato molto comico all'inizio, tanto che ho lasciato perdere il tutto fino a data da destinarsi. L'altro giorno, stufa di vedere il messaggio di errore all'avvio del mio povero Mac, ho scavato nella rete e ho trovato la soluzione!
Nel blog da cui ho preso la soluzione dicono che il problema è l'ownership (ma come si dice in italiano??) dello script e usando queste due linee su terminale dovrebbe andare tutto a posto.
cd /Library/StartupItems
sudo chown -R root:wheel ChmodBPF
Una volta sistemati i permessi di ChmodBPF bisogna riavviare il computer oppure, semplicemente, avviare ChmodBPF tramite:
sudo /Library/StartupItems/ChmodBPF/ChmodBPF start
Per ora il tutto funziona, vedremo cosa succederà alla prossima release.

AGGIORNAMENTO: ad oggi (release 1.8.3) il problema sembra essersi risolto.