6

I'm implementing a backup/restore system in my android app.

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.

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

Backtrace

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]
8
  • And where exactly does the exception happen? Remove the try/catch to get a proper stack trace. Commented Sep 9, 2013 at 11:33
  • I'm getting a "file is encrypted or is not a database" exception right when I try to query using the restored DB. Here's the full stacktrace: pastebin.com/j4tQU26K Commented Sep 9, 2013 at 19:52
  • @CL. Forgot to tag :) Commented Sep 9, 2013 at 19:53
  • In which class is this code? Is it possible that some code already has tried to open the database file? Commented Sep 9, 2013 at 20:30
  • @CL. Yes, it is possible. I'm using a singletone DatabaseHelper class, that is already instantiated before the restore operation. But, I tried to load the database libraries once again, and also set the instance of my database to null so it will re-create a new DatabaseHelper object. Though, I'm getting the same exception. Commented Sep 9, 2013 at 20:39

3 Answers 3

20
+50

Please use this code it may help you... I have done the same with this way

For Backup

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

For Restore

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Your answer hasn't solved my problem, but it made me look once again what really happens before the restore operation. I found out that I was using the new DB functions, so that caused all the problems. Thank you.
It sometimes don't copy database file content in internal storage. If i pull database from device, it shows blank. Sometimes it does. Unable to recognize the problem.
@Patriotic it is may be because I make this post almost 5 years back. So after that so many changes made by google for data security. That may be the problem for such behaviour.
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();
}

Comments

0

The problem I feel is with reading the already existing db file. You actually are not reading it, the code is just creating a new one every time the app is installed. You will have to give the exact name of the db file you are referring to in order to read it in your getExternalEvironment function..

1 Comment

Ehm, the problem is already solved, the solution wasn't about the specified code, but there was another problem. Take a look at the comment in the answer above you, thanks :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.