SQLite in Android, programmando con i Toast

android_hello world

Abbiamo visto i giorni scorsi qualche spunto su come programmare in Android, abbiamo visto alcuni componenti, come i Button e la TextView. Oggi vedremo altri due importanti componenti, la TextField di tipo Plain Text e di tipo MultiLine, insieme a SQLite, fondamentale se vogliamo salvare dei dati sul nostro robottino.

Più precisamente andremo ad ampliare la precedente app Contatore, creata qui, aggiungendo il supporto al database SQLite, facendo in modo che l’app ricordi diversi numeri contati, salvati mediante un Button e memorizzati con un identificatore scelto dall’utente grazie ad un EditText. Una volta salvati i dati saranno reperibili attraverso un pulsante “Load”. L’eliminazione dei dati sarà possibile ma non la implementeremo ora.

GUI (Graphic User Interface)

Apriamo quindi Eclipse, e, se siete nuovi vi consiglio di leggere anche il precedente articolo, a cui ora allego anche la cartella dell’app zippata, da estrarre e piazzare nel vostro workspace di Eclipse stesso.

Creiamo una GUI simile a questa:

GUI del Contatore modificato per SQLiteE modifichiamo le stringhe così come abbiamo visto nell’articolo precedente, ma in più scegliamo un generico tipo di EditText: “text”, rendendo l’app qualcosa di simile a questo:

Panoramica Design App
Panoramica Design App

Bene, la GUI è pronta, ora occorre….

…Programmare!

Per accedere ad un database SQLite le cose si fanno un po’ complesse (non troppo, tranquilli), e sarà preferibile creare una classe apposita per l’accesso, la modifica, l’interrogazione e la chiusura del databse. Il db sarà strutturato in modo estremamente semplice, una tabella con due colonne, “nome” e “valore”, che conterranno vari record. Esempio:

tabella del db SQLite
tabella del db SQLite

Iniziamo, creiamo nello stesso package una nuova classe vuota, che chiameremo dbManage. Questa classe a sua volta si dovrà appoggiare ad un’altra classe, che chiameremo…

SQLite Helper

Questa classe estenderà la fornita da android SQLiteOpenHelper. Quest’ultima semplicemente chiede di implementare i metodi onCreate e onUpgrade che dicono cosa fare alla creazione e all’aggiornamento del db. Eccola:

Ovviamente SCRIPT_CREATE_DATABASE lo definiamo dopo. Se volete modificare in un futuro prossimo la struttura del database, allora nel metodo onUpgrade dovrete inserire le funzioni per fare ciò. onUpgrade viene chiamato ogni volta che una costante (che definiamo dopo) viene incrementata, quindi si può, nel modo più semplice, eliminare tutta la tabella e ricrearla, o meglio, prendere i dati e inserirli in una nuova tabella. A noi questa funzionalità non occorre perché il nostro db sarà sempre così per questo tutorial.

Ora passiamo con la vera e propria classe, dbManage, che conterrà SQLiteHelper.

dbManage

Iniziamo con la dichiarazione di alcune variabili e costanti:

Ci sono: la variabile che conterrà l’helper, quella per il vero e proprio db, il context che serve a SQLiteOpenHelper, e le costanti del nome del db, e quindi del nome del file, la versione del database da incrementare appunto quando vogliamo che venga eseguito onUpgrade, la tabella del db che abbiamo chiamato “main”, e un piccolo snippet SQL per la creazione del db. Se non sapete questa sintassi, con cui i database SQL interagiscono, capirla non è difficile, ma se volete approfondire Google aiuta 😉

In sostanza noi creiamo un db con una tabella con una colonna chiamata “nome” che sarà di tipo “string” e sarà la chiave primaria, quindi un ID univoco, e una colonna “valore” di tipo intero che non può essere nullo.

Ora passiamo ai metodi, prima di tutti il costruttore, che richiede il contesto, da salvare in una variabile per passarlo poi all’SQLiteHelper. Poi avremo bisogno di un modo per aprire il database: SQLiteOpenHelper ce ne offre due, uno per aprirlo in lettura e uno in scrittura.

Il codice non è difficile, bisogna solo sapere che la variabile sqLiteHelper viene inizializzata quando viene chiamato uno dei due metodi, creando un SQLiteHelper passando il contesto, il nome del db, chiedendo di aprirlo in modo standard (null) e con la versione del db. Dopodiché chiediamo di aprirlo in lettura o scrittura.

Ora, una volta aperto, ci serviranno metodi per l’inserimento, l’interrogazione, l’eliminazione e la chiusura del db.

La chiusura è molto semplice come vedete; per l’inserimento ci appoggiamo a ContentValues ed è anch’esso comunque semplice, passiamo i valori del “nome” e del “valore” a questo metodo insert e questo procederà con l’inserimento tramite SQLiteHelper.

Per l’eliminazione abbiamo inserito due null perché vogliamo eliminare tutto il contenuto, se avessimo voluto eliminare solo un record avremmo dovuto inserire una clausola “where” di SQL proprio nel secondo e terzo argomento.

Infine per l’interrogazione di tutto il db creiamo un array delle colonne da richiedere, e in seguito, con SQLiteHelper, chiediamo queste al db, senza filtrare e quindi ponendo tutti i null del dovere. Il risultato va a finire in un Cursor, che viene ritornato.

Ora che abbiamo la classe, implementarla nel nostro progetto sarà pressoché semplice.

Contatore.java

Apriamo il Contatore.java e aggiungiamo nello stesso modo del precedente articolo i vari button, e aggiungiamo dei listener ai due pulsanti. Aggiungiamo anche l’editText multiLine.

Definizione dei componenti necessari
Definizione dei componenti necessari

Vedete che non c’è niente di sconvolgente.

saveButton

Ora passiamo al pulsante “saveButton” con id button3.

Listener del saveButton
Listener del saveButton

Vediamo di commentarlo un po’. Innanzitutto creiamo un nuovo oggetto dbManage, e passiamogli il contesto dell’applicazione con il metodo ereditato da Activity “getApplicationContext()”. Poi apriamo in scrittura il db, e inseriamo i dati prelevati dalla prima editText e dal testo1, che sarebbe il contatore. Qui ho usato questo modo per far vedere che anche senza avere l’accesso diretto a cont, possiamo ottenere il contatore basandoci sul numero che c’è in quel momento nella textView.

Il risultato lo mettiamo in “res”; a cosa serve? Semplice, se l’utente prova ad inserire due chiavi primarie identiche (cosa ovviamente non consentita), res sarà -1, e quindi lo avviseremo con un Toast.

Il Toast

A differenza di quanto può pensare l’utente medio, i Toasts non si mangiano, sono delle notifiche che appaiono per qualche secondo, di solito nella parte in basso dello schermo. Per esempio:

La nostra app che segnala un salvataggio andato a buon fine

Quel “Record aggiunto” è una notifica Toast. Per mostrarne uno possiamo fare direttamente come abbiamo scritto più in alto, RICORDANDOCI di mettere alla fine “.show();”, altrimenti lo creeremo ma non lo mostreremo -> inutile.

Come vedete prima ho usato la res/values/strings.xml mettendo al posto di un testo “R.string.errKey” e “R.string.ok1”. Questo significa che in quel file ho aggiunto due stringhe con questi nomi e con i valori “Record aggiunto” e “Impossibile aggiungere il record al db. Prova con una chiave diversa”.

Alla fine chiudiamo il database con “dbm.close();”

loadButton

Il loadButton servirà per mostrare nella editText multiLine i valori salvati. Iniziamo a vederlo.

loadButton
Listener del loadButton

Come prima apriamo il db  dopo aver creato l’oggetto, ma questa volta per leggerlo. Otteniamo tutti i risultati con dbm.queueAll(), e, se sono più di zero, azzeriamo la editText multiLine, li sfogliamo ad uno ad uno e li aggiungiamo alla multiLine stessa. Infine chiudiamo il database.

Bene, l’app è pronta! Eccola a voi!

Ed eccovi la cartella di Eclipse con tutti i sorgenti.

Seguiteci anche su Facebook, Google Plus e Twitter, per restare sempre in contatto con noi e con le nostre guide.