Cerca con Google

12 ottobre 2011

Tutorial 22 - Il componente TinyDB per il salvataggio dei dati


Rieccoci con un nuovo tutorial! Questa volta parleremo del componente TinyDB che si trova nella palette Basic di App Inventor.

Questo componente (di tipo non visibile, ovvero non viene visualizzato nell'interfaccia utente) viene utilizzato tutte le volte che vogliamo memorizzare in maniera "permanente" dei dati nella nostra app.


Come avrete infatti notato con gli altri tutorial, tutti i dati inseriti dall'utente (come ad esempio il testo inserito in una textbox) vengono persi non appena l'applicazione viene chiusa (attenzione, per come gestisce la memoria Android potrete aver visto che anche dopo aver chiuso e riaperto un app creata con AI, l'applicazione è ripartita dall'esatto punto dove l'avevate lasciata, ma questo non vi deve trarre in inganno, se il telefono avesse avuto bisogno di più memoria avrebbe chiuso definitivamente la vostra app ed avreste così perso i dati).

Bene, con questo componente possiamo invece salvare i nostri dati sul telefono in maniera sicura.
TinyDB permette il salvataggio sottoforma di coppie "tag" / "value".
Il tag è il nome con cui vogliamo identificare il nostro dato
mentre il value è ovviamente il valore stesso che vogliamo salvare.
Possiamo così salvare ad esempio l'high score di un nostro videogioco, oppure la textbox inserita precedentemente dall'utente oppure ancora le preferenze della nostra applicazione, insomma come avrete capito il campo di utilizzo è veramente sterminato (per esempio nella mia acqua alta app lo uso per salvare tutta la tabella coi dati di marea in modo da poter usare l'app anche off-line)

Nel nostro esempio vediamo come è possibile salvare il contenuto di una tabella formata da 2 colonne e 3 righe in cui l'utente inserisce un ipotetica nota spese.
L'esempio è volutamente semplice ma fa vedere come si utilizza il componente TinyDB per il salvataggio ed il successivo caricamento dei dati.

Il componente TinyWebDB funziona praticamente allo stesso modo ma salva i dati sul web e richiede un database TinyWeb creato dall'utente sul web (magari in futuro ne vedremo anche il suo utilizzo)

Per ora buona visione!




Per finire vediamo alcune note tecniche su TinyDB:


Proprietà

nessuna

Eventi

nessuno

Metodi

StoreValue(text tag, valueToStore)
Salva il valore dato sotto lo specifico tag. il Tag deve essere una stringa di testo, il valore può essere una stringa o una lista (array)

GetValue(text tag)
Recupera il valore che è stato salvato con il tag specificato. Se nessun valore è stato salvato ritorna una stringa vuota (empty)

I dati salvati possono essere eliminati usando la funzione di sistema di Android, andiamo in applicazioni - gestisci applicazioni - selezioniamo la nostra app. Quando selezioniamo cancella dati andremo a cancellare i dati memorizzati con TinyDB.
Per i più smaliziati, i dati salvati li trovate sotto questo path (è necessario un root explorer per visualizzare la cartella /data/)

/data/data/appinventor.ai_seblog2k.Tutorial_TinyDb/shared_prefs/TinyDB.xml

come vedete il file è un xml e può quindi essere letto e modificato agevolmente anche con altri editor.

25 commenti:

  1. Da molto aspettavo questo tutorial!

    RispondiElimina
  2. ciao! Tramite tinyDB si possono salvare le scelte effettuate che l'utente compie cliccando su alcuni pulsanti e poi richiamarle per visualizzare dei dati in base alle scelte fatte? grazie :)

    RispondiElimina
  3. Puoi salvare qualsiasi campo testuale stringa o array, per esempio se hai una checkbox puoi impostare che alla sua pressione il valore di una variabile diventi "true" e poi con TinyDb salvi questa variabile.
    Nel momento poi in cui la carichi, reimposterai il valore della tua checkbox in base al valore caricato (quindi o true o false), spero di essere stato chiaro abbastanza :)

    RispondiElimina
  4. mmm forse ho capito...ci provo subito! grazie!

    RispondiElimina
  5. Ciao! avrei un quesito da porti? vorrei ordinare in maniera crescente (o decrescente) i valori di alcune label (o i valori di un DB) e restituirli in maniera ordinata. cosa consigli? ho visto in altri linguaggi comandi specifici. ho rozzamente sviluppato una sequenza su block editor, ma è immensa, piena di "Ifelse", label e variabili :D ) . Forse con una procedura farei meglio. ma come?

    credo esista qualcosa di molto più razionale e semplice, ma non riesco ad immaginarla. Potresti aiutarmi?
    Credo sarebbe utile per molte applicazioni. ad esempio temperature, maree, e qualunque altro insieme di dati statistici da riordinare.
    in pascal al liceo ricordo che servivano dei vettori (Array) ma quello che trovo on-line è relativo ad altri linguaggi e seppur comprensibile nel concetto di base non riesco a svilupparlo su AppInventor. Magari un prossimo tutorial potrà far luce sul mio quesito.
    Ti StraRingrazio come sempre!
    un tuo allievo fedele

    RispondiElimina
  6. un'altra domanda che mi viene da fare è la seguente: come posso importare un file CSV nel TinyDB e poi confrontare il valore inserito in una o più label o textbox con i vari valori del CSV.
    Ad esempio dato un CSV dei livelli dell'acqua alta a Venezia vorrei sapere quando e se il livello ha superato un determinato valore. oppure dato il csv dei risultati del Superenalotto vorrei sapere quando e se la sestina che inserisco nei sei (o più) textbox sono usciti.
    Grazie mille e buona serata

    RispondiElimina
  7. Ciao liberlpensiero, una cosa alla volta...:)
    1) per ordinare i valori di alcune label devi prima di tutto inserire tutti questi valori all'interno di una lista (che è poi quello che tu conoscevi come array o vettore)
    poi si può usare per esempio l'algoritmo di bubble sort per ordinarla, senza stare a rifare cose già fatte...ti linko la discussione in inglese della procedura che fa proprio quello che tu chiedi (spero tu sappia un pò di inglese)
    http://www.appinventorblocks.com/appinventor-tutorials-tips/appinventor-list-sorting-tutorial

    RispondiElimina
  8. 2) più o meno il concetto è simile a quello dell'ordinamento visto poco fa, con un block "for...range" analizzi tutti gli elementi della tua lista, poi per esempio se vuoi trovare il valore massimo confronti ogni elemento col massimo trovato fino a quel momento (quindi inzialmente col primo valore nella lista) se è maggiore, il nuovo massimo è il valore appena analizzato, altrimenti non fai nulla e analizzi l'elemento successivo in lista. Alla fine avrai trovato il tuo massimo con molta semplicità.
    Per il superenalotto avrai due liste, la sestina vincente e quella pronosticata. Prendi il primo elemento di quella pronosticata e la confronti se è uguale ad un elemento contenuto nella lista dei numeri vincenti, se si incrementi di uno un contatore che ti da il numero degli azzeccati.
    Poi analizzi il secondo numero e così via...
    In pratica sarà un doppio ciclo "for...range" (annidiato) da 6 elementi ognuno.
    Spero di essere stato sufficientemente chiaro, a volte prima di buttare giù blocchi su blocchi è meglio fermarsi un attimo e disegnare la procedura su carta ragionandoci su.
    In bocca al lupo! :)

    RispondiElimina
  9. grandeeee! Letto, capito, fatto! :)
    Grazie.

    RispondiElimina
  10. Ciao Seblog,
    grazie per i tuoi tutorial !
    Mi sai dire se è possibile salvare i dati all'uscita del programma ?
    Supponi che l'utente riempia le caselle testo, si dimentica di premere il pulsante SALVA ed esce.

    Grazie ;-)

    RispondiElimina
  11. in quel caso non verrebbero salvati i dati, devi chiamare te la tinydb con il metodo storevalue. Lo puoi fare anche all'uscita del programma, però considera che se l'utente torna alla home del suo telefono e poi il sistema Android ti forza la chiusura dell'app (per liberare memoria), la procedura storevalue non viene chiamata e i dati vengono persi.
    Se hai paura di perdere i dati puoi salvarli ogni qualvolta l'utente inserisce un nuovo valore ad esempio.

    RispondiElimina
  12. Ho pensato anch'io a salvare i dati all'uscita del programma, però non so a quale evento associare lo torevalue.
    Ho visto l'oggetto Screen, ma non ho trovato niente.
    Ho pensato anche di associarlo all'evento LostFocus dei text, come forse mi suggerisci tu, ma non so se funziona sull'ultimo valore inserito.

    RispondiElimina
  13. Ho fatto un tentativo :
    1) Creato 2 campi text
    2) Nel lostfocus di entrambi, inserito lo storevalue
    3) inserito valore nel primo text
    4) inserito valore nel secondo text
    5) esco con il tasto back
    6) rientro e trovo solo il primo dato salvato

    NON và.... :(

    RispondiElimina
  14. hai ragione, pensavo ci fosse l'evento "close app" invece non c'è, a questo punto è un bel problema...il lostfocus serviva solo sui telefoni dotati di cursore (tipo il primo desire) quindi per la maggior parte di quelli di oggi non serve a nulla...
    un alternativa potrebbe essere salvarli "a tempo" ogni tot secondi, non è molto elegante come soluzione ma in effetti non ne vedo altre.
    Se qualcuno ha altre idee si faccia avanti :)

    RispondiElimina
  15. C'è sintonia.....

    Grazie per il suggerimento

    ;-)

    RispondiElimina
  16. Ciao Seablog,

    ma con appinventor si può creare e gestire un vero e proprio db (con lettura, scrittura, cancellazione , ecc) di record??
    Per esempio per creare un app per gestire una collezione di canzoni o di film....

    RispondiElimina
  17. Puoi usare le google fusion tables che sono supportate in app inventor, spero di fare presto un Tutorial a riguardo...

    RispondiElimina
  18. :) Grazie mille!!!!
    Non vedo l'ora di vederlo.....

    RispondiElimina
  19. Grazie per tutti i tutorial che hai fatti. Sempre molto utili. Ti volevo chiedere, ma per creare un inserimento password all' accesso del programma, bisogna utilizzare lo stesso procedimento? Ma se e' facilmente leggibile ( file xml ) non c'e' sicurezza a riguardo. Consigli?

    RispondiElimina
    Risposte
    1. Ciao,esiste da design editor il componente password ma ti imposta semplicemente il testo con gli asterischi in modo che non si veda durante la digitazione.
      Una funzione vera e propria non esiste, puoi creare un qualcosa di basilare te, quando memorizzi la pwd nel tinydb esegui prima delle operazioni matematiche che poi farai al "rovesco" quando devi leggere la password.
      Per esempio l'utente inserisce 1234 tu memorizzi il risultato di
      ((1234 * 6) + 721)
      mentre in lettura farai:
      (pwd memorizzata - 721) / 6
      insomma spero di averti dato l'idea visto che funzioni apposite per il momento non ne esistono.
      La sicurezza capirai non è elevatissima ma meglio che memorizzare la pwd in chiaro in un xml nel telefono...

      Elimina
    2. grazie per l'idea, provero' il tuo consiglio...

      Elimina
  20. Ciao innanzitutto grazie per i tuoi utilissimi tutorial; volevo farti una domanda, esiste secondo te un metodo per ottenere una lista di tutti i tag salvati e contenuti nella memoria (tinyDB) per vari scopi, ad esempio per una ricerca avanzata? ciao e grazie.

    RispondiElimina
    Risposte
    1. intendi dall'interno dell'App? o in generale?
      perchè da AI devi per forza conoscere il nome del tag che vuoi estrarre mentre con un file explorer o adb puoi estrarre direttamente il file .xml con tutti i valori salvati come spiegato nella parte finale di questo articolo

      Elimina
  21. Ciao,intendevo proprio all'interno dell'app. Non esiste un modo di estrarre la lista di tutti i tag? L'unica cosa che mi è venuta in mente per ora è salvare tutti i tag contemporaneamente alla loro creazione in un array con un tag (es. LISTATAG) e manipolarlo all'occorrenza.

    RispondiElimina
    Risposte
    1. no,purtroppo non si può fare.
      la tua idea è sicuramente buona e può essere la soluzione ottimale (se hai paura di non ricordarti che tag hai salvato) bravo!

      Elimina