web-dev-qa-db-fra.com

Comment sauvegarder un fichier de base de données sur la carte SD sur Android?

J'aimerais ajouter une fonctionnalité à mon Android qui sauvegarde automatiquement la base de données SQLite sur la carte SD .

Quelle est la meilleure façon de procéder? Existe-t-il des exemples ou des didacticiels?

58
CodeFusionMobile

Les bases de données SQLite sont des fichiers complètement autonomes et sont portables - vous pouvez simplement copier le fichier entier directement sur la carte SD.

Bien que je vérifie d'abord si une carte SD est installée dans l'appareil, et quel est son chemin (en utilisant Environment.getExternalStorageDirectory()).

9
Christopher Orr

Ce code fonctionne pour moi!

    try {
        File sd = Environment.getExternalStorageDirectory();
        File data = Environment.getDataDirectory();

        if (sd.canWrite()) {
            String currentDBPath = "//data//{package name}//databases//{database name}";
            String backupDBPath = "{database name}";
            File currentDB = new File(data, currentDBPath);
            File backupDB = new File(sd, backupDBPath);

            if (currentDB.exists()) {
                FileChannel src = new FileInputStream(currentDB).getChannel();
                FileChannel dst = new FileOutputStream(backupDB).getChannel();
                dst.transferFrom(src, 0, src.size());
                src.close();
                dst.close();
            }
        }
    } catch (Exception e) {
    }

Est-ce que quelqu'un sait si cela fonctionnera sur des téléphones non root? Je ne l'ai essayé que sur un G1 enraciné.

122
skeniver
try {
    File sd = Environment.getExternalStorageDirectory();
    File data = Environment.getDataDirectory();

    if (sd.canWrite()) {
        String currentDBPath = "//data//"+ packageName +"//databases//"+dbList[0];
        String backupDBPath = dbList[0];
        File currentDB = new File(data, currentDBPath);
        File backupDB = new File(sd, backupDBPath);

        FileChannel src = new FileInputStream(currentDB).getChannel();
        FileChannel dst = new FileOutputStream(backupDB).getChannel();
        dst.transferFrom(src, 0, src.size());
        src.close();
        dst.close();
        Toast.makeText(getBaseContext(), backupDB.toString(), Toast.LENGTH_LONG).show();
    }
} catch (Exception e) {
    Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show();
}

Cela fonctionne contrairement aux exemples ci-dessus dans lesquels les "/" sont "\" gaspillés 20 minutes de ma vie à le comprendre, mais j'aurais vraiment dû le voir plus tôt. Le Toast vous indiquera où le fichier a été placé ou vous indiquera ce qui ne va pas lorsqu'il ne fonctionne pas.

20
Rhys

I répond une question similaire à celle-ci avec une méthode que vous pouvez placer dans votre SQLiteOpenHelper. C'est aussi simple que de copier le fichier db d'une sorte de stockage externe vers le stockage d'application interne. Il y a aussi du code supplémentaire qui s'ouvre et lit le fichier db pour s'assurer qu'il est dans l'état approprié pour Android pour lui faire des appels de base de données.

3
Austyn Mahoney
public static void BackupDatabase() throws IOException
{
    boolean success =true;
    File file = null;
    file = new File(Environment.getExternalStorageDirectory() +"/M.O.L.S_Backup");

    if (file.exists())
    {
        success =true;
    }
    else
    {
        success = file.mkdir();
    }

    if (success)
    {
        String inFileName = "/data/data/com.sygic.sdk.demo/databases/MOLS_DB.s3db";
        File dbFile = new File(inFileName);
        FileInputStream fis = new FileInputStream(dbFile);

        String outFileName = Environment.getExternalStorageDirectory()+"/M.O.L.S_Backup/MOLS_DB.s3db";

        // Open the empty db as the output stream
        OutputStream output = new FileOutputStream(outFileName);

        // Transfer bytes from the inputfile to the outputfile
        byte[] buffer = new byte[1024];
        int length;
        while ((length = fis.read(buffer))>0) {
            output.write(buffer, 0, length);
        }

        output.flush();
        output.close();
        fis.close();
    }
}
3
Osama Ibrahim

Vous devez donner l'autorisation Android.permission.WRITE_EXTERNAL_STORAGE dans votre candidature. Cela fonctionne bien sur les appareils non rootés.

2
Tushar Jadhav

Je ne sais pas ce qui se passe si le téléphone est rooté ou non mais vous devez écrire vos fichiers dans:

/Android/data/{package_name}/files/

Cela fonctionnera, qu'il soit enraciné ou non.

1
JMA

Vous trouverez votre nom de base de données dans l'adaptateur de base de données si vous êtes nouveau dans ce domaine.

Notez que vous pouvez également le faire pour SharedPreferences, mais n'oubliez pas de changer votre Context.MODE_PRIVATE en Context.MODE_MULTI_PROCESS.

SharedPreferences_name devrait ressembler à ceci = ExportSP("temp.xml");

String currentPathForSharedPreferences = "/data/"+ context.getPackageName() +"/shared_prefs/"+ SharedPreferences_name;

Pour l'export

exportDB("MyDbName");

private void exportDB(String db_name){

File sd = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + 
                File.separator + "Your Backup Folder"+ 
                File.separator );

          boolean success = true;
           if (!sd.exists()) {
               success = sd.mkdir();
           }
           if (success) {

        File data = Environment.getDataDirectory();
       FileChannel source=null;
       FileChannel destination=null;
       String currentDBPath = "/data/"+ context.getPackageName() +"/databases/"+db_name;
       String backupDBPath = db_name;
       File currentDB = new File(data, currentDBPath);
       File backupDB = new File(sd, backupDBPath);
       try {
            source = new FileInputStream(currentDB).getChannel();
            destination = new FileOutputStream(backupDB).getChannel();
            destination.transferFrom(source, 0, source.size());
            source.close();
            destination.close();
            Toast.makeText(this, "Please wait", Toast.LENGTH_SHORT).show();
        } catch(IOException e) {
            e.printStackTrace();
        }
           }}

Pour l'importation

importDB("MyDbName");

private void importDB(String db_name){
        File sd = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + 
                File.separator + "Your Backup Folder"+ 
                File.separator );
        File data = Environment.getDataDirectory();
       FileChannel source=null;
       FileChannel destination=null;
       String backupDBPath = "/data/"+ context.getPackageName() +"/databases/"+db_name;
       String currentDBPath = db_name;
       File currentDB = new File(sd, currentDBPath);
       File backupDB = new File(data, backupDBPath);
       try {
            source = new FileInputStream(currentDB).getChannel();
            destination = new FileOutputStream(backupDB).getChannel();
            destination.transferFrom(source, 0, source.size());
            source.close();
            destination.close();
            Toast.makeText(this, "Please wait", Toast.LENGTH_SHORT).show();
        } catch(IOException e) {
            e.printStackTrace();
        }
}
1
ORY

@ code skeniver fonctionne pour moi. Je veux juste ajouter ce qui suit:

Utilisation:

String currentDbPath = getApplicationContext().getDatabasePath("{database name}");

Il vous donnera le chemin de votre base de données. Il est préférable de l'utiliser au lieu de coder en dur le chemin, comme:

String currentDbPath = "//data//{package name}//databases//{database name}";
1
Charles Gouws