Android从SD卡上的数据库文件恢复备份

时间:2013-05-17 11:21:02

标签: android android-sqlite database-backups database-restore

这里有一些关于stackoverflow的问题,其中人们使用BackupAgents将应用数据与googles cloud同步(参见here)。在我的具体情况下,由于或多或少敏感数据的性质,要求更具限制性。所有内容必须只存储在设备上,并且应用程序不得连接到互联网。

主Activity包含一个ViewPager,它承载一些ListFragments。每个ListFragment都有自己的Loader,它将光标交换到SimpleCursorAdapter类中。

在备份和恢复数据库之前,我使用以下命令销毁加载器:

getLoaderManager().destroy(LOADER_ID);

我的备用功能类似于此anwser

final String inFileName = "/data/data/<your.app.package>/databases/foo.db";
File dbFile = new File(inFileName);
FileInputStream fis = new FileInputStream(dbFile);

String outFileName = Environment.getExternalStorageDirectory()+"/database_copy.db";

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

// Close the streams
output.flush();
output.close();
fis.close();

恢复功能类似于将数据库从sdcard复制回内部app文件夹,停止加载器并覆盖数据库文件。

public static void restore(Context context) throws IOException {

    if (externalStorageIsWriteable()) {

        // getBackupDir() is a path to the folder on the sdcard
        File fileBackup = new File(getBackupDir(), WineSQLiteHelper.DB_NAME);

        if (!fileBackup.exists()) {
            throw new IOException("File not found");
        }

        File importFile = getImportDatabase();

        try {
            FileUtils.copyFile(fileBackup, importFile);
            MySQLiteHelper dbHelper = new MySQLiteHelper(context);
            dbHelper.close();
            dbHelper = null;

            File file = new File(Environment.getDataDirectory() + "/data/"
                 + PACKAGE + "/databases/" + WineSQLiteHelper.DB_NAME);
            FileUtils.copyFile(importFile, file);

            // Remove temporary import file.
            importFile.delete();
        } catch (IOException e) {
            throw e;
        }
    } else {
        throw new IOException("External Storage not writeable");
    }
}

但不知何故,在我覆盖了数据库文件后,MainActivity会被重新创建,我收到了一些

SQLiteException: no such column

我的猜测是,也许仍然存在与数据库的开放连接,但我不确定,因为这是我第一次与数据库紧密合作。

  1. 如何正确关闭ContentProvider的所有数据库连接?我在文档中找不到任何关于此的内容。这有必要吗?

  2. 如何正确恢复数据库?

0 个答案:

没有答案