public static String restoreDatabaseInternal(final Context context, final Uri databaseUri) {
        return withChangeLock(() -> {
            final File tmpFile = ContentStorage.get().writeUriToTempFile(databaseUri, "backup_db.tmp");
            DBRestoreResult result = DBRestoreResult.RESTORE_FAILED_GENERAL;
            try {
                final SQLiteDatabase backup = SQLiteDatabase.openDatabase(tmpFile.getPath(), null, SQLiteDatabase.OPEN_READONLY);
                final int backupDbVersion = backup.getVersion();
                final int expectedDbVersion = DataStore.getExpectedDBVersion();
                if (!DataStore.versionsAreCompatible(backup, backupDbVersion, expectedDbVersion)) {
                    return String.format(context.getString(R.string.init_restore_version_error), expectedDbVersion, backupDbVersion);
                }
                closeDb();
                result = FileUtils.copy(tmpFile, databasePath()) ? DBRestoreResult.RESTORE_SUCCESSFUL : DBRestoreResult.RESTORE_FAILED_GENERAL;
                init();
                if (newlyCreatedDatabase) {
                    result = DBRestoreResult.RESTORE_FAILED_DBRECREATED;
                    Log.e("restored DB seems to be corrupt, needed to recreate database from scratch");
                }
                if (result == DBRestoreResult.RESTORE_SUCCESSFUL) {
                    Log.i("Database successfully restored from " + tmpFile.getPath());
                } else {
                    Log.e("Could not restore database from " + tmpFile.getPath());
                }
            } catch (SQLiteException e) {
                Log.e("error while restoring database: ", e);
            } finally {
                tmpFile.delete();
            }
            return context.getString(result.res);
        });
    }
Move the database to/from external cgdata in a new thread,
showing a progress window
main/src/main/java/cgeo/geocaching/storage/DataStore.java