我正在我的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]
答案 0 :(得分:15)
请使用此代码,它可能对您有帮助......我也是这样做的
备份
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) {
}
如果条件允许,你们之间的一点点差异就可以在文件内部看到。
答案 1 :(得分:3)
try
{
String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/CALC/Backup";
//final
String inFileName = path+"/Calc_backup :"+date;
File dbFile = new File(inFileName);
FileInputStream fis = new FileInputStream(dbFile);
/*File dir = new File(path);
if(!dir.exists())
dir.mkdirs();*/
//Toast.makeText(getActivity(), "directory created @"+dir.getPath(), 2).show();
// String outFileName = Environment.getExternalStorageDirectory()+"Calac/hems.txt";
//String outFileName = path+"/"+date;
String outFileName = "/data/data/com.special.ResideMenuDemo/databases/Calq";
// 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);
}
Toast.makeText(getActivity(), "Restore Successfully", 2).show();
// Close the streams
output.flush();
output.close();
fis.close();
}
catch(Exception e)
{
e.printStackTrace();
}
答案 2 :(得分:0)
我觉得问题是阅读已经存在的db文件。你实际上没有阅读它,代码只是在每次安装应用程序时创建一个新代码。您必须提供所引用的db文件的确切名称,以便在 getExternalEvironment 函数中读取它。