javaandroidimportexportandroid-sqlite

Export Sqlite database and Import after reinstall


I'm trying to export my SQLite database in order to import it as a backup after reinstall, but every time the export success, but when I want to import the file after I reinstall the app, It doesn't appear in the directory and I can't reach it, although the method of import is working well if I export and import without uninstall and reinstall the app again.

Also when I use (file.existes) it show that it's existed , but though it doesn't import anything. Hopefully I could find the solution from you.

This is my export method

public boolean exportDB() {
    StorageManager storageManager = (StorageManager) context.getSystemService(STORAGE_SERVICE);
    StorageVolume storageVolume = storageManager.getStorageVolumes().get(0);
    File folder = null;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R)
        folder = new File(storageVolume.getDirectory().getPath() + "/Documents");
    boolean success = true;
    assert folder != null;
    if (!folder.exists())
        success = folder.mkdirs();
    if (success) {
        DirectoryName = folder.getPath() + File.separator + "MMS-" + new SimpleDateFormat("dd-MM-yyyy-HH-mm-ss", Locale.ENGLISH).format(new Date());
        folder = new File(DirectoryName);
        if (!folder.exists())
            success = folder.mkdirs();
        if (success)
            try {
                File dbFile = new File(context.getDatabasePath(DATABASE_NAME).getAbsolutePath());
                FileInputStream fis = new FileInputStream(dbFile);
                String outFileName = DirectoryName + File.separator + DATABASE_NAME ;
                OutputStream output = Files.newOutputStream(Paths.get(outFileName));
                byte[] buffer = new byte[1024];
                int length;
                while ((length = fis.read(buffer)) > 0)
                    output.write(buffer, 0, length);
                output.flush();
                output.close();
                fis.close();
            } catch (IOException e) {
                success = false;
            }
    } else
        Toast.makeText(context, "Cannot create folder.", Toast.LENGTH_SHORT).show();
    return success;
}

And this is the import method

 public boolean importDB(String dbPath) throws IOException {
    String DB_FILEPATH = context.getDatabasePath(DATABASE_NAME).getAbsolutePath();
    close();
    File newDb = new File(dbPath);
    File oldDb = new File(DB_FILEPATH);
    if (newDb.exists()) {
        FileInputStream fromFile = new FileInputStream(newDb);
        FileOutputStream toFile = new FileOutputStream(oldDb);
        FileChannel fromChannel = null;
        FileChannel toChannel = null;
        try {
            fromChannel = fromFile.getChannel();
            toChannel = toFile.getChannel();
            fromChannel.transferTo(0, fromChannel.size(), toChannel);
        } finally {
            try {
                if (fromChannel != null)
                    fromChannel.close();
            } finally {
                if (toChannel != null)
                    toChannel.close();
            }
        }
        getWritableDatabase().close();
        return true;
    }
    return false;
}

Solution

  • You only have access to files in Documents/ that your app installation created. In your case, presumably your previous app installation created the file, so your new app installation cannot access it.

    Rather than making assumptions about storage volumes and paths, use the Storage Access Framework to allow the user to decide where your app should put the backup. You would use ACTION_CREATE_DOCUMENT / ActivityResultContracts.CreateDocument for the backup. You would use ACTION_OPEN_DOCUMENT / ActivityResultContracts.OpenDocument for the restore operation. I demonstrate how to do that with SQLite databases, in the context of Room, in this chapter of this free book.