wake-up-neo.com

Wie kann ich eine Datenbankdatei auf der SD-Karte unter Android sichern?

Ich möchte meiner App Android) eine Funktion hinzufügen, mit der die SQLite -Datenbank automatisch auf der SD-Karte gesichert wird.

Was ist der beste Weg, um dies zu tun? Gibt es Beispiele oder Tutorials?

58

SQLite-Datenbanken sind vollständig in sich geschlossene Dateien und portabel. Sie können einfach die gesamte Datei direkt auf die SD-Karte kopieren.

Allerdings würde ich zuerst prüfen, ob eine SD-Karte im Gerät installiert ist und welchen Pfad sie hat (mithilfe von Environment.getExternalStorageDirectory()).

9
Christopher Orr

Dieser Code funktioniert bei mir!

    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) {
    }

Weiß jemand, ob dies auf Nicht-Root-Telefonen funktioniert? Ich habe es nur auf einem verwurzelten G1 versucht.

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();
}

Das funktioniert im Gegensatz zu den obigen Beispielen, in denen die "/" 20 Minuten meines Lebens damit verschwendet wurden, das herauszufinden, aber ich hätte das wirklich früher sehen sollen. Das Toast teilt Ihnen mit, wo sich die Datei befunden hat oder was falsch ist, wenn es nicht funktioniert.

20
Rhys

I beantwortet eine ähnliche Frage mit einer Methode, die Sie in Ihrem SQLiteOpenHelper platzieren können. Es ist so einfach wie das Kopieren der Datenbankdatei von einem externen Speicher in den internen Anwendungsspeicher. Es gibt auch einen zusätzlichen Code, der die Datenbankdatei öffnet und liest, um sicherzustellen, dass sie sich im richtigen Zustand befindet, damit Android) Datenbankaufrufe an sie gerichtet werden können.

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

Du musst die Erlaubnis geben Android.permission.WRITE_EXTERNAL_STORAGE in Ihrer Bewerbung. Es funktioniert einwandfrei auf nicht gerooteten Geräten.

2
Tushar Jadhav

Ich weiß nicht, was passiert, wenn das Telefon gerootet ist oder nicht, aber Sie sollten Ihre Dateien schreiben an:

/Android/data/{package_name}/files/

Dies funktioniert unabhängig davon, ob es gerootet ist oder nicht.

1
JMA

Sie finden Ihren Datenbanknamen im Datenbankadapter, wenn Sie neu in diesem Bereich sind.

Beachten Sie, dass Sie dies auch für SharedPreferences tun können. Beachten Sie jedoch, dass Sie Context.MODE_PRIVATE in Context.MODE_MULTI_PROCESS ändern müssen.

SharedPreferences_name sollte folgendermaßen aussehen = ExportSP("temp.xml");

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

Für den 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();
        }
           }}

Für den Import

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

@ skeniver's code funktioniert bei mir. Ich möchte nur Folgendes hinzufügen:

Verwenden:

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

Es wird Ihnen Ihren Datenbankpfad geben. Es ist besser, dies zu verwenden, anstatt den Pfad fest zu codieren, wie:

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