Autore Topic: [medio] Backup di un database SQLite su sdcard.  (Letto 3865 volte)

Offline Nicola_D

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 2469
  • SBAGLIATO!
  • Respect: +321
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
[medio] Backup di un database SQLite su sdcard.
« il: 24 Luglio 2012, 23:45:35 CEST »
+5
Livello di difficoltà : medio
Min SDK : 4
Sorgente : ZIP allegato


fonti:

Introduzione

Viste le numerose richieste di informazioni, tutorial e snippet su come effettuare il backup di un database, in modo da averlo disponibile anche su cellulari non rootati e fuori dall'emulatore, mi sono deciso a sperimentare la procedura e a fare un piccolo tutorial per rendere disponibile a tutti questa procedura.

Il "Tutorial" in realtà è molto semplice, in quanto la procedura non richiede particolari skill.
Nel caso in cui si volesse utilizzare una procedura differente, il codice è pronto per essere riadattato.

Contenuto del tutorial e layout

Partendo dai tutorial già citati (che sono abbastanza importanti per capire bene il codice di questo tutorial), vediamo cosa abbiamo a disposizione nel tutorial:

Il tema del tutorial è "Nazioni" ; andremo a creare un database di nazioni contenenti Codice,Nome e descrizione, avendo la possibilità di visualizzarle in una comoda listview, e di farne un backup sulla sd.

Activity composta da view pager con 3 tabs:
 - Aggiunta
 - Visualizzazione
 - Backup
Database SQLite creato da script a runtime


Tralasciando il layout dell'activity (uguale a quello dei tutorial precedenti) e dei tre fragment (molto banale, se vi serve è nel file allegato), passiamo alla parte più importante, cioè la fase di backup:

Per prima cosa, va configurato il manifest per dare il permesso di scrittura su sd:
Codice (XML): [Seleziona]
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="it.anddev.dbBackup"
   android:versionCode="1"
   android:versionName="1.0" >
    <uses-sdk
       android:minSdkVersion="4"
       android:targetSdkVersion="16" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <application
       android:icon="@drawable/ic_launcher"
       android:label="@string/app_name"
       android:theme="@style/AppTheme" >
        <activity
           android:name=".MainActivity"
           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>

E quindi, il "cuore" del backup:
Codice (Java): [Seleziona]
        Button backup;
        private final String _backupFileName = "countries";

        ....

                backup = (Button) view.findViewById(R.id.backup);
                        backup.setOnClickListener(new OnClickListener() {

                                public void onClick(View v) {
                                        if (null != mCountriesDB) {
                                                backupDatabase(mCountriesDB.getDbPath());//mCountriesDb è la classe estesa che permette la gestione del database.
                                        }
                                }
                        });
                return view;
        }

        public void backupDatabase(String dbPath) {
                if (dbPath == null) {
                        Toast.makeText(getActivity(), getString(R.string.msg_db_null), Toast.LENGTH_LONG).show();
                        return;
                }
                try {
                        File sd = Environment.getExternalStorageDirectory();
                        if (sd.canWrite()) {                           
                                File currentDB = new File(dbPath);//path del db su telefono
                                File backupDB = new File(sd, _backupFileName);//file di destinazione

                                FileChannel src = new FileInputStream(currentDB).getChannel();//apriamo un filechannel sul db e sul file di destinazione
                                FileChannel dst = new FileOutputStream(backupDB).getChannel();
                                dst.transferFrom(src, 0, src.size());//trasferiamo il contenuto
                                src.close();
                                dst.close();
                                Toast.makeText(getActivity().getBaseContext(), String.format(getString(R.string.msg_db_location), backupDB.toString()), Toast.LENGTH_LONG).show();

                        } else {
                                Log.e("Permission denied", "Can't write to SD card, add permission");
                        }
                } catch (Exception e) {
                        Toast.makeText(getActivity().getBaseContext(), e.toString(), Toast.LENGTH_LONG).show();
                }
        }

Il metodo è davvero semplice, l'unica cosa di cui avete bisogno è il path del database, che si ottiene con il metodo:
Citazione
SQLiteDatabase.getPath()
Vi verrà restituita una stringa contenente il path completo per arrivare al database, che (vi ricordo) è accessibile solo dalla vostra app, quindi solo voi potete farne il backup.


Verifica e apertura db
Una volta lanciata l'applicazione ed eseguito il backup, vi ritroverete il file al path specificato sul layout (di solito /sdcard/countries oppure /mnt/sdcard/countries , in blu nell'immagine).
Da qui è facile fare un export da interfaccia di eclipse (in verde nell'immagine), da copia file su pc dopo aver montato la memoria come pennetta usb oppure aprire il file direttamente sul telefono.


I possibili miglioramenti o le espansioni sono molte, a partire dalla possibilità di inviare via mail il db (magari come funzionalità di test), allo sharing intent, oppure, cosa ancora più utile, la possibilità di lanciare il backup solo tramite combinazione particolare Utilizzare i Telephony.SECRET_CODE - Android Developers Italia

Ed ora, un paio di screenshot per mostrarvi i risultati:


Piccole aggiunte personali:
- Gestione degli stili in base alla versione android, con Theme di default per versioni < 11 e holo per versioni => 11
- Gestione doppia lingua (italiano/inglese)
- Gestione e visualizzazione degli errori sugli edit text (come da framework)
- Gestione ListView con ViewHolder
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline tiziano0371

  • Nuovo arrivato
  • *
  • Post: 20
  • Respect: 0
    • Mostra profilo
Re:[medio] Backup di un database SQLite su sdcard.
« Risposta #1 il: 26 Luglio 2012, 14:51:36 CEST »
0
OTTIMO TUTORIAL!!!
visto che ci sei sarebbe interessante completare il tutto con la funzione RECUPERO BACKUP, molto utile nel caso di reset del dispositivo. grazie.

Offline Nicola_D

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 2469
  • SBAGLIATO!
  • Respect: +321
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:[medio] Backup di un database SQLite su sdcard.
« Risposta #2 il: 26 Luglio 2012, 20:29:12 CEST »
0
OTTIMO TUTORIAL!!!
visto che ci sei sarebbe interessante completare il tutto con la funzione RECUPERO BACKUP, molto utile nel caso di reset del dispositivo. grazie.
non ci avevo pensato, ottima idea... vediamo cosa arrivo a fare, ma la procedura (a naso) è molto semplice, basta invertire i filechannel, aggiungiendo però i permessi di lettura su sd card...
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline lucab

  • Nuovo arrivato
  • *
  • Post: 49
  • Respect: +10
    • Mostra profilo
    • Lucabportal
  • Dispositivo Android:
    Nexus 5 - Nexus One
  • Play Store ID:
    Luca Biasotto
  • Sistema operativo:
    Mac OS X
Re:[medio] Backup di un database SQLite su sdcard.
« Risposta #3 il: 28 Settembre 2013, 12:42:39 CEST »
+1
Salve a tutti,
se vi può servire ho scritto uno Snippet su come ripristinare il backup partendo da questo ottimo tutorial:

Backup nella SD e Restore dalla SD del Database della vostra app  - Android Developers Italia
Le occasioni arrivano una volta sola, se non le afferri al volo passeranno altri alla storia.

Offline paul78

  • Utente normale
  • ***
  • Post: 268
  • Respect: +1
    • Mostra profilo
    • Android Code
  • Sistema operativo:
    Linux - Windows
Re:[medio] Backup di un database SQLite su sdcard.
« Risposta #4 il: 30 Settembre 2013, 09:52:36 CEST »
0
ottimo tutoria!!!!

ma manca un piccolissimo dettaglio....se volessi reinstallare il backup salvato, come faccio???
tutti possiamo programmare...basta volerlo!!!

Offline Nicola_D

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 2469
  • SBAGLIATO!
  • Respect: +321
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:[medio] Backup di un database SQLite su sdcard.
« Risposta #5 il: 30 Settembre 2013, 09:59:57 CEST »
0
ottimo tutoria!!!!

ma manca un piccolissimo dettaglio....se volessi reinstallare il backup salvato, come faccio???
Guardi il post subito prima del tuo!
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline danielgp6

  • Nuovo arrivato
  • *
  • Post: 2
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    Windows 7
Re:[medio] Backup di un database SQLite su sdcard.
« Risposta #6 il: 05 Gennaio 2014, 10:19:07 CET »
0
Ciao sono nuovo in questo forum... Potreste indicarmi dove posso trovare il sorgente in formato ZIP in allegato cui si fà riferimento all'inizio? Grazie

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 3971
  • keep it simple
  • Respect: +550
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:[medio] Backup di un database SQLite su sdcard.
« Risposta #7 il: 05 Gennaio 2014, 10:41:28 CET »
0
Ciao sono nuovo in questo forum... Potreste indicarmi dove posso trovare il sorgente in formato ZIP in allegato cui si fà riferimento all'inizio? Grazie

C'è un link subito sotto l'ultima riga dell'articolo.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline danielgp6

  • Nuovo arrivato
  • *
  • Post: 2
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    Windows 7
Re:[medio] Backup di un database SQLite su sdcard.
« Risposta #8 il: 05 Gennaio 2014, 11:37:32 CET »
0
Ok grazie
« Ultima modifica: 10 Gennaio 2014, 17:31:39 CET da danielgp6, Reason: Merged DoublePost »