问题描述
我正在android应用中实现备份/还原系统.
I'm implementing a backup/restore system in my android app.
每两分钟进行一次自动备份.卸载并重新安装应用程序后,我试图从SD卡恢复数据库备份文件.
An automatic backup occures every couple of minutes.I'm trying to restore my db backup file from my sd card, after my app was uninstalled and then installed again.
备份有效,但这是问题所在:
每当用户再次安装我的应用程序时,都找不到文件异常,但是,如果用户关闭该应用程序,然后再次打开它,则恢复就可以了.不知何故,在首次启动该应用程序时,还原会遇到问题.
Backup works, but here's the problem:
Whenever the user installs my app again, there's a file not found exception, but, if the user closes the app, and then opens it again, the restore is just fine. Somehow, the restoring faces problem when the app is first launched.
还原必须在首次启动时进行.
The restore must happen on first time launch.
注意:backupExists函数返回true.
Note: the backupExists function returns 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]
推荐答案
请使用此代码,它可能会对您有所帮助...我已经用这种方法做了同样的事情
Please use this code it may help you... I have done the same with this way
用于备份
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();
Toast.makeText(getApplicationContext(), "Backup is successful to SD card", Toast.LENGTH_SHORT).show();
}
}
} catch (Exception e) {
}
还原
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(backupDB).getChannel();
FileChannel dst = new FileOutputStream(currentDB).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
Toast.makeText(getApplicationContext(), "Database Restored successfully", Toast.LENGTH_SHORT).show();
}
}
} catch (Exception e) {
}
如果条件一致,两个文件之间的差异就可以在文件通道中看到.
A little dfference between both u can see in filechannel inside if condition.
这篇关于恢复SQLite数据库文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!