【发布时间】:2013-09-05 11:44:00
【问题描述】:
我正在我的 Android 应用中实现备份/恢复系统。
每隔几分钟自动备份一次。 在我的应用程序被卸载然后重新安装后,我正在尝试从我的 sd 卡恢复我的数据库备份文件。
备份有效,但问题出在:
每当用户再次安装我的应用程序时,都会出现找不到文件的异常,但是,如果用户关闭应用程序,然后再次打开它,恢复就很好了。不知何故,当应用程序首次启动时,恢复面临问题。
必须在首次启动时进行恢复。
注意:backupExists 函数返回 true。
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(backUpExists()){
restoreDB();
}
}
private boolean backUpExists()
{
try{
File sd = Environment.getExternalStorageDirectory();
if (sd.canRead()){
String backupDBPath = "myDB";
File backupedDB = new File(sd, backupDBPath);
if(backupedDB.exists()){
return true;
}
}
} catch(Exception ex) {
Toast.makeText(getBaseContext(), ex.toString(), Toast.LENGTH_LONG).show();
}
return false;
}
private void restoreDB()
{
try{
File sd = Environment.getExternalStorageDirectory();
File data = Environment.getDataDirectory();
if (sd.canWrite()) {
String restroredDBPath = "//data//myPackage//databases//myDB";
String backupDBPath = "myDB";
File restoredDB = new File(data, restroredDBPath);
File backupedDB = new File(sd, backupDBPath);
FileChannel src = new FileInputStream(backupedDB).getChannel();
FileChannel dst = new FileOutputStream(restoredDB).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
Toast.makeText(getBaseContext(), restoredDB.toString(), Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show();
}
}
回溯
09-09 22:49:50.931: I/Database(23206): sqlite returned: error code = 26, msg = statement aborts at 14: [SELECT COUNT(*) FROM Photos WHERE AlbumId=0] file is encrypted or is not a database
09-09 22:49:50.931: D/AndroidRuntime(23206): Shutting down VM
09-09 22:49:50.931: W/dalvikvm(23206): threadid=1: thread exiting with uncaught exception (group=0x4151c700)
09-09 22:49:50.931: E/AndroidRuntime(23206): FATAL EXCEPTION: main
09-09 22:49:50.931: E/AndroidRuntime(23206): net.sqlcipher.database.SQLiteException: file is encrypted or is not a database
09-09 22:49:50.931: E/AndroidRuntime(23206): at net.sqlcipher.database.SQLiteQuery.native_fill_window(Native Method)
09-09 22:49:50.931: E/AndroidRuntime(23206): at net.sqlcipher.database.SQLiteQuery.fillWindow(SQLiteQuery.java:73)
09-09 22:49:50.931: E/AndroidRuntime(23206): at net.sqlcipher.database.SQLiteCursor.fillWindow(SQLiteCursor.java:290)
[snipped]
【问题讨论】:
-
异常究竟发生在哪里?删除
try/catch以获得正确的堆栈跟踪。 -
当我尝试使用恢复的数据库进行查询时,出现“文件已加密或不是数据库”异常。这是完整的堆栈跟踪:pastebin.com/j4tQU26K
-
@CL。忘记标记了:)
-
这段代码在哪个类?是否有可能某些代码已经尝试打开数据库文件?
-
@CL。是的,有可能。我正在使用单调 DatabaseHelper 类,该类在还原操作之前已经实例化。但是,我尝试再次加载数据库库,并将我的数据库实例设置为 null,这样它将重新创建一个新的 DatabaseHelper 对象。不过,我遇到了同样的例外情况。
标签: android sqlite android-sdcard database-backups database-restore