I looked at others answers like Backup and restore SQLite database to sdcard and Restoring SQLite DB file etc. but i still dont see the restoring of database when i uninstall and reinstall app and restore backup. Here is the code I have currently.
public class BackupAndRestore {
public static void importDB(Context context) {
try {
File sd = Environment.getExternalStorageDirectory();
if (sd.canRead()) {
File currentDB = context.getDatabasePath(AppDatabase.DATABASE_NAME);
File backupDB = new File(sd, AppDatabase.DATABASE_NAME);
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(context, "Database Restored successfully", Toast.LENGTH_SHORT).show();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void exportDB(Context context) {
try {
File sd = Environment.getExternalStorageDirectory();
File data = Environment.getDataDirectory();
if (sd.canWrite()) {
File currentDB = context.getDatabasePath(AppDatabase.DATABASE_NAME);
File backupDB = new File(sd, AppDatabase.DATABASE_NAME);
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(context, "Backup is successful to SD card", Toast.LENGTH_SHORT).show();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
So I install app and I add content to database. Then I also grant permission to write to external storage before calling this export method above. it shows toast message "Backup is successful... " and I can see the file created in the external storage. Then I uninstall and reinstall and I request permission again to external storage. Then call the method import above. The toast message again is seen "Database Restored.." but I don't see the database content that existed before. I tested on android 7 device and android 10 device. I will appreciate help. Thanks.
After testing and looking around much and thanks to @MikeT i was able to use this class below for backup and restore.
public class BackupAndRestore {
public static void importDB(Context context) {
try {
File sd = Environment.getExternalStorageDirectory();
// by closing the database some other database files ending with -shm and -wal are deleted so that there is one database file and it has all content
AppDatabase.getDatabaseInstance(context).close();
if (sd.canRead()) {
File currentDB = context.getDatabasePath(AppDatabase.DATABASE_NAME);
File backupDB = new File(sd, AppDatabase.DATABASE_NAME);
transfer(context, backupDB, currentDB);
Toast.makeText(context, "Database Restored successfully", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void exportDB(Context context) {
try {
File sd = Environment.getExternalStorageDirectory();
// by closing the database some other database files ending with -shm and -wal are deleted so that there is one database file and it has all content
AppDatabase.getDatabaseInstance(context).close();
if (sd.canWrite()) {
File currentDB = context.getDatabasePath(AppDatabase.DATABASE_NAME);
File backupDB = new File(sd, AppDatabase.DATABASE_NAME);
transfer(context, currentDB, backupDB);
Toast.makeText(context, "Backup is successful to SD card", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void transfer(Context context, File sourceFile, File destinationFile) throws IOException {
if (sourceFile.exists()) {
FileChannel src = new FileInputStream(sourceFile).getChannel();
FileChannel dst = new FileOutputStream(destinationFile).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
}
}
}
In my main activity I call method like below
...
if (item.getItemId() == R.id.backup) {
BackupAndRestore.exportDB(getBaseContext());
restartApplication();
} else if (item.getItemId() == R.id.restore) {
BackupAndRestore.importDB(getBaseContext());
restartApplication();
}
...
So the restartApplication method is called after backup because I noticed the room database was not working properly after backup unless i restart the application and also after after restoring I could not see the restored data unless the application was restarted. The restart method is below
private void restartApplication() {
finish();
startActivity(getIntent());
System.exit(0);
}