diff --git a/app/src/main/java/de/k3b/android/androFotoFinder/FotoGalleryActivity.java b/app/src/main/java/de/k3b/android/androFotoFinder/FotoGalleryActivity.java index daaefb9c..7373404d 100644 --- a/app/src/main/java/de/k3b/android/androFotoFinder/FotoGalleryActivity.java +++ b/app/src/main/java/de/k3b/android/androFotoFinder/FotoGalleryActivity.java @@ -49,6 +49,7 @@ import de.k3b.android.util.IntentUtil; import de.k3b.android.util.PhotoPropertiesMediaFilesScanner; import de.k3b.android.widget.AboutDialogPreference; +import de.k3b.android.widget.AsyncTaskRunnerWithProgressDialog; import de.k3b.android.widget.BaseQueryActivity; import de.k3b.android.widget.Dialogs; import de.k3b.database.QueryParameter; @@ -260,7 +261,7 @@ private int onDbUpdateCommand(MenuItem item) { } private boolean onDbReloadQuestion(String title) { - Dialogs dlg = new Dialogs() { + final Dialogs dlg = new Dialogs() { @Override protected void onDialogResult(String result, Object[] parameters) { setAutoClose(null, null, null); @@ -276,9 +277,19 @@ protected void onDialogResult(String result, Object[] parameters) { } private void onDbReloadAnswer() { - if (0 != AndroFotoFinderApp.getMediaContent2DbUpdateService().rebuild(this, null)) { - notifyPhotoChanged(); - } + new AsyncTaskRunnerWithProgressDialog(this, R.string.load_db_menu_title) { + @Override + protected void onPostExecute(Integer itemCount) { + super.onPostExecute(itemCount); + if (itemCount != 0) { + FotoGalleryActivity fotoGalleryActivity = (FotoGalleryActivity) getActivity(); + if (fotoGalleryActivity != null) { + fotoGalleryActivity.notifyPhotoChanged(); + } + } + } + + }.execute(AndroFotoFinderApp.getMediaContent2DbUpdateService().getRebbuildRunner()); } public void notifyPhotoChanged() { diff --git a/app/src/main/java/de/k3b/android/androFotoFinder/queries/MediaContent2DBUpdateService.java b/app/src/main/java/de/k3b/android/androFotoFinder/queries/MediaContent2DBUpdateService.java index c1bc189f..cdf33cc5 100644 --- a/app/src/main/java/de/k3b/android/androFotoFinder/queries/MediaContent2DBUpdateService.java +++ b/app/src/main/java/de/k3b/android/androFotoFinder/queries/MediaContent2DBUpdateService.java @@ -26,6 +26,7 @@ import java.util.Date; +import de.k3b.android.widget.ITaskRunner; import de.k3b.io.IProgessListener; /** @@ -58,6 +59,16 @@ public void clearMediaCopy() { DatabaseHelper.version2Upgrade_ReCreateMediaDbTable(context, writableDatabase); } + public ITaskRunner getRebbuildRunner() { + return new ITaskRunner() { + @Override + public int run(Context context, IProgessListener progessListener) { + return rebuild(context, progessListener); + } + }; + + } + public int rebuild(Context context, IProgessListener progessListener) { long start = new Date().getTime(); if (progessListener != null) @@ -73,7 +84,6 @@ public int rebuild(Context context, IProgessListener progessListener) { DatabaseHelper.restoreFromBackup(writableDatabase); long timeInSecs = (new Date().getTime() - start) / 1000; final String text = "load db " + timeInSecs + " secs"; - Toast.makeText(context, text, Toast.LENGTH_LONG).show(); if (progessListener != null) progessListener.onProgress(0, 0, text); return changeCount; } diff --git a/app/src/main/java/de/k3b/android/widget/ActivityWithAsyncTaskDialog.java b/app/src/main/java/de/k3b/android/widget/ActivityWithAsyncTaskDialog.java new file mode 100644 index 00000000..c3c847c3 --- /dev/null +++ b/app/src/main/java/de/k3b/android/widget/ActivityWithAsyncTaskDialog.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021 by k3b. + * + * This file is part of AndroFotoFinder / #APhotoManager. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see + */ + +package de.k3b.android.widget; + +import android.os.Bundle; + +import java.lang.ref.WeakReference; + +/** + * {@link ActivityWithAsyncTaskDialog} is an Activity that shows a Progress-Dialog while + * {@link AsyncTaskRunnerWithProgressDialog} runs a {@link ITaskRunner} in the Background + */ +public abstract class ActivityWithAsyncTaskDialog extends ActivityWithAutoCloseDialogs { + // only one current AsyncTaskDialog can exist at a time. + private static WeakReference runner = null; + + private static void setActivityIfActive(ActivityWithAsyncTaskDialog activity) { + AsyncTaskRunnerWithProgressDialog task = (runner == null) ? null : runner.get(); + if (task != null) { + task.setActivity(activity); + } + } + + public static void setRunner(AsyncTaskRunnerWithProgressDialog runner) { + ActivityWithAsyncTaskDialog.runner = (runner == null) ? null : new WeakReference(runner); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // After rotation the dialog will be destroyed. Make shure that a new progressDialog is created. + setActivityIfActive(this); + } +} \ No newline at end of file diff --git a/app/src/main/java/de/k3b/android/widget/AsyncTaskRunnerWithProgressDialog.java b/app/src/main/java/de/k3b/android/widget/AsyncTaskRunnerWithProgressDialog.java new file mode 100644 index 00000000..f83b1afc --- /dev/null +++ b/app/src/main/java/de/k3b/android/widget/AsyncTaskRunnerWithProgressDialog.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 by k3b. + * + * This file is part of AndroFotoFinder / #APhotoManager. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see + */ +package de.k3b.android.widget; + +import android.content.Context; + +import de.k3b.io.IProgessListener; + +/** + * {@link ActivityWithAsyncTaskDialog} is an Activity that shows a Progress-Dialog while + * {@link AsyncTaskRunnerWithProgressDialog} runs a {@link ITaskRunner} in the Background + */ + +public class AsyncTaskRunnerWithProgressDialog extends AsyncTaskWithProgressDialog implements IProgessListener { + private final Context context; + + public AsyncTaskRunnerWithProgressDialog(ActivityWithAsyncTaskDialog activity, int idResourceTitle) { + super(activity, idResourceTitle); + context = activity.getApplicationContext(); + } + + @Override + protected Integer doInBackground(ITaskRunner... executers) { + int result = 0; + for (ITaskRunner executer : executers) { + ActivityWithAsyncTaskDialog.setRunner(this); + result += executer.run(context, this); + } + return result; + } + + @Override + public void destroy() { + setActivity(null); + super.destroy(); + } + +} diff --git a/app/src/main/java/de/k3b/android/widget/AsyncTaskWithProgressDialog.java b/app/src/main/java/de/k3b/android/widget/AsyncTaskWithProgressDialog.java index a27dbcd4..5f9a3321 100644 --- a/app/src/main/java/de/k3b/android/widget/AsyncTaskWithProgressDialog.java +++ b/app/src/main/java/de/k3b/android/widget/AsyncTaskWithProgressDialog.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020 by k3b. + * Copyright (c) 2017-2021 by k3b. * * This file is part of AndroFotoFinder / #APhotoManager. * @@ -21,36 +21,50 @@ import android.app.Activity; import android.app.ProgressDialog; import android.os.AsyncTask; +import android.util.Log; import android.widget.Toast; import java.io.Closeable; import java.lang.ref.WeakReference; import de.k3b.android.androFotoFinder.R; +import de.k3b.io.IProgessListener; +import de.k3b.zip.LibZipGlobal; /** * Async task that displays ProgressDialog while running. - * + *

* Created by k3b on 09.07.2017. */ abstract public class AsyncTaskWithProgressDialog extends AsyncTask - implements Closeable{ + implements Closeable, IProgessListener { private final int idResourceTitle; private WeakReference activity; protected ProgressDialog dlg = null; + public AsyncTaskWithProgressDialog(Activity activity, int idResourceTitle) { this.idResourceTitle = idResourceTitle; this.setActivity(activity); } + protected void onProgressUpdate(String... values) { if (dlg != null) { - if (!dlg.isShowing()) dlg.show(); + if (!dlg.isShowing()) { + dlg.show(); + setDialog(getActivity(), dlg); + } dlg.setMessage(values[0]); } } + private void setDialog(Activity activity, ProgressDialog dlg) { + if (activity instanceof ActivityWithAutoCloseDialogs) { + ((ActivityWithAutoCloseDialogs) activity).setAutoClose(null, dlg, null); + } + } + @Override protected void onPostExecute(Integer itemCount) { super.onPostExecute(itemCount); @@ -72,12 +86,29 @@ protected void onCancelled(Integer result) { public void close() { destroy(); } + public void destroy() { setActivity(null); } - /** periodically called while work in progress. */ - protected void publishProgress(int itemCount, int total, Object message) { + /** + * de.k3b.io.IProgessListener: + *

+ * called every time when command makes some little progress in non gui thread. + * return true to continue + */ + @Override + public boolean onProgress(int itemCount, int total, String message) { + return publishProgress(itemCount, total, message); + } + + public boolean publishProgress(int itemCount, int total, Object message) { + final boolean cancelled = this.isCancelled(); + if (cancelled) { + if (LibZipGlobal.debugEnabled) { + Log.d(LibZipGlobal.LOG_TAG, this.getClass().getSimpleName() + " cancel pressed "); + } + } StringBuilder msg = new StringBuilder(); if (itemCount > 0) { msg.append("(").append(itemCount); @@ -90,23 +121,28 @@ protected void publishProgress(int itemCount, int total, Object message) { msg.append(message); } publishProgress(msg.toString()); + return !cancelled; } + protected Activity getActivity() { if (activity == null) return null; return activity.get(); } - public void setActivity(Activity activity) { + public AsyncTaskWithProgressDialog setActivity(Activity activity) { boolean isActive = isNotFinishedYet(); - if (isActive && (activity == getActivity())) { + Activity oldActivity = getActivity(); + if (isActive && (activity == oldActivity)) { // no change - return; + return this; } + this.activity = (isActive && (activity != null)) ? new WeakReference<>(activity) : null; if ((dlg != null) && dlg.isShowing()) { dlg.dismiss(); + setDialog(activity, null); } dlg = null; @@ -114,6 +150,7 @@ public void setActivity(Activity activity) { dlg = new ProgressDialog(activity); dlg.setTitle(idResourceTitle); } + return this; } public boolean isNotFinishedYet() { diff --git a/app/src/main/java/de/k3b/android/widget/FilePermissionActivity.java b/app/src/main/java/de/k3b/android/widget/FilePermissionActivity.java index fac14f99..e7859757 100644 --- a/app/src/main/java/de/k3b/android/widget/FilePermissionActivity.java +++ b/app/src/main/java/de/k3b/android/widget/FilePermissionActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 by k3b. + * Copyright (c) 2020-2021 by k3b. * * This file is part of AndroFotoFinder / #APhotoManager. * @@ -46,7 +46,7 @@ * * write to external-storage and * * write to sdcard/usbstick,.... */ -public abstract class FilePermissionActivity extends ActivityWithAutoCloseDialogs { +public abstract class FilePermissionActivity extends ActivityWithAsyncTaskDialog { private static final int REQUEST_ROOT_DIR = 2001; public static final String TAG = "k3b.FilePermAct"; private static IOnDirectoryPermissionGrantedHandler currentPermissionGrantedHandler = null; diff --git a/app/src/main/java/de/k3b/android/widget/ITaskRunner.java b/app/src/main/java/de/k3b/android/widget/ITaskRunner.java new file mode 100644 index 00000000..c8eb020f --- /dev/null +++ b/app/src/main/java/de/k3b/android/widget/ITaskRunner.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 by k3b. + * + * This file is part of AndroFotoFinder / #APhotoManager. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see + */ + +package de.k3b.android.widget; + +import android.content.Context; + +import de.k3b.io.IProgessListener; + +/** + * {@link ActivityWithAsyncTaskDialog} is an Activity that shows a Progress-Dialog while + * {@link AsyncTaskRunnerWithProgressDialog} runs a {@link ITaskRunner} in the Background + */ +public interface ITaskRunner { + int run(Context context, IProgessListener iProgessListener); +} diff --git a/app/src/main/java/de/k3b/android/widget/PermissionBaseActivity.java b/app/src/main/java/de/k3b/android/widget/PermissionBaseActivity.java index b05b4276..1e144c95 100644 --- a/app/src/main/java/de/k3b/android/widget/PermissionBaseActivity.java +++ b/app/src/main/java/de/k3b/android/widget/PermissionBaseActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 by k3b. + * Copyright (c) 2020-2021 by k3b. * * This file is part of AndroFotoFinder / #APhotoManager. * @@ -44,7 +44,7 @@ * onActivityResult(REQUEST_SAVE_EDIT_PICTURE_AS, RESULT_OK, data) : * edit.onSaveEditPictureAsOutputUriPickerResult(outUri=data.getData()) */ -public abstract class PermissionBaseActivity extends ActivityWithAutoCloseDialogs { +public abstract class PermissionBaseActivity extends ActivityWithAsyncTaskDialog { private static final CallbackHandler permissionHandler = new CallbackHandler(); /** diff --git a/fotolib2/src/main/java/de/k3b/io/IProgessListener.java b/fotolib2/src/main/java/de/k3b/io/IProgessListener.java index c4f1115b..fe98f924 100644 --- a/fotolib2/src/main/java/de/k3b/io/IProgessListener.java +++ b/fotolib2/src/main/java/de/k3b/io/IProgessListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020 by k3b. + * Copyright (c) 2017-2021 by k3b. * * This file is part of AndroFotoFinder / #APhotoManager. * @@ -25,7 +25,7 @@ public interface IProgessListener { /** - * called every time when command makes some little progress. Can be mapped to async progress-bar. + * called every time (inside background-task) when command makes some little progress. Can be mapped to async progress-bar. * return true to continue */ boolean onProgress(int itemcount, int size, String message);