package cgeo.geocaching.utils; import cgeo.geocaching.MainActivity; import cgeo.geocaching.R; import cgeo.geocaching.storage.DataStore; import cgeo.geocaching.ui.dialog.Dialogs; import android.app.Activity; import android.app.ProgressDialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.res.Resources; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import java.io.File; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicBoolean; import io.reactivex.functions.Consumer; import io.reactivex.schedulers.Schedulers; import org.apache.commons.lang3.StringUtils; public class DatabaseBackupUtils { private DatabaseBackupUtils() { // utility class } /** * After confirming to overwrite the existing caches on the devices, restore the database in a new thread, showing a * progress window * * @param activity * calling activity */ public static void restoreDatabase(final Activity activity) { if (!hasBackup()) { Dialogs.message(activity, R.string.init_backup_restore, R.string.init_backup_no_backup_available); return; } final int caches = DataStore.getAllCachesCount(); if (caches == 0) { restoreDatabaseInternal(activity); } else { Dialogs.confirm(activity, R.string.init_backup_restore, activity.getString(R.string.restore_confirm_overwrite, activity.getResources().getQuantityString(R.plurals.cache_counts, caches, caches)), new OnClickListener() { @Override public void onClick(final DialogInterface dialog, final int which) { restoreDatabaseInternal(activity); } }); } } private static void restoreDatabaseInternal(final Activity activity) { final Resources res = activity.getResources(); final ProgressDialog dialog = ProgressDialog.show(activity, res.getString(R.string.init_backup_restore), res.getString(R.string.init_restore_running), true, false); final AtomicBoolean restoreSuccessful = new AtomicBoolean(false); AndroidRxUtils.andThenOnUi(Schedulers.io(), new Runnable() { @Override public void run() { restoreSuccessful.set(DataStore.restoreDatabaseInternal()); } }, new Runnable() { @Override public void run() { dialog.dismiss(); final boolean restored = restoreSuccessful.get(); final String message = restored ? res.getString(R.string.init_restore_success) : res.getString(R.string.init_restore_failed); Dialogs.message(activity, R.string.init_backup_restore, message); if (activity instanceof MainActivity) { ((MainActivity) activity).updateCacheCounter(); } } }); } /** * Create a backup after confirming to overwrite the existing backup. * */ public static void createBackup(final Activity activity, final Runnable runAfterwards) { // avoid overwriting an existing backup with an empty database // (can happen directly after reinstalling the app) if (DataStore.getAllCachesCount() == 0) { Dialogs.message(activity, R.string.init_backup, R.string.init_backup_unnecessary); return; } if (hasBackup()) { Dialogs.confirm(activity, R.string.init_backup, activity.getString(R.string.backup_confirm_overwrite, getBackupDateTime()), new OnClickListener() { @Override public void onClick(final DialogInterface dialog, final int which) { createBackupInternal(activity, runAfterwards); } }); } else { createBackupInternal(activity, runAfterwards); } } private static void createBackupInternal(final Activity activity, final Runnable runAfterwards) { final ProgressDialog dialog = ProgressDialog.show(activity, activity.getString(R.string.init_backup), activity.getString(R.string.init_backup_running), true, false); AndroidRxUtils.andThenOnUi(Schedulers.io(), new Callable<String>() { @Override public String call() { return DataStore.backupDatabaseInternal(); } }, new Consumer<String>() { @Override public void accept(final String backupFileName) { dialog.dismiss(); Dialogs.message(activity, R.string.init_backup_backup, backupFileName != null ? activity.getString(R.string.init_backup_success) + "\n" + backupFileName : activity.getString(R.string.init_backup_failed)); if (runAfterwards != null) { runAfterwards.run(); } } }); } @Nullable public static File getRestoreFile() { final File fileSourceFile = DataStore.getBackupFileInternal(true); return fileSourceFile.exists() && fileSourceFile.length() > 0 ? fileSourceFile : null; } public static boolean hasBackup() { return getRestoreFile() != null; } @NonNull public static String getBackupDateTime() { final File restoreFile = getRestoreFile(); if (restoreFile == null) { return StringUtils.EMPTY; } return Formatter.formatShortDateTime(restoreFile.lastModified()); } }