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 c3a5a45d..8b699848 100644 --- a/app/src/main/java/de/k3b/android/androFotoFinder/FotoGalleryActivity.java +++ b/app/src/main/java/de/k3b/android/androFotoFinder/FotoGalleryActivity.java @@ -43,6 +43,7 @@ import de.k3b.android.util.IntentUtil; import de.k3b.android.widget.AboutDialogPreference; import de.k3b.android.widget.BaseQueryActivity; +import de.k3b.android.widget.Dialogs; import de.k3b.database.QueryParameter; import de.k3b.io.IDirectory; import de.k3b.io.collections.SelectedItemIds; @@ -206,10 +207,10 @@ public boolean onOptionsItemSelected(MenuItem item) { AboutDialogPreference.createAboutDialog(this).show(); return true; case R.id.cmd_db_reload: - AndroFotoFinderApp.getMediaContent2DbUpdateService().rebuild(this, null); - return true; + return onDbReloadQuestion(item.getTitle().toString()); case R.id.cmd_db_update: - AndroFotoFinderApp.getMediaContent2DbUpdateService().update(this, null); + if (0 != AndroFotoFinderApp.getMediaContent2DbUpdateService().update(this, null)) + notifyPhotoChanged(); return true; case R.id.cmd_more: new Handler().postDelayed(new Runnable() { @@ -225,6 +226,34 @@ public void run() { } + private boolean onDbReloadQuestion(String title) { + Dialogs dlg = new Dialogs() { + @Override + protected void onDialogResult(String result, Object[] parameters) { + setAutoClose(null, null, null); + if (result != null) { + onDbReloadAnswer(); + } + } + }; + + this.setAutoClose(null, dlg.yesNoQuestion(FotoGalleryActivity.this, title, title), null); + + return true; + } + + private void onDbReloadAnswer() { + if (0 != AndroFotoFinderApp.getMediaContent2DbUpdateService().rebuild(this, null)) { + notifyPhotoChanged(); + } + } + + public void notifyPhotoChanged() { + if (mGalleryGui instanceof GalleryCursorFragment) { + ((GalleryCursorFragment) mGalleryGui).notifyPhotoChanged(); + } + } + /** * Call back from sub-activities.
* Process Change StartTime (longpress start), Select StopTime before stop diff --git a/app/src/main/java/de/k3b/android/androFotoFinder/queries/FotoSql.java b/app/src/main/java/de/k3b/android/androFotoFinder/queries/FotoSql.java index 9e72a8f8..45c5b637 100644 --- a/app/src/main/java/de/k3b/android/androFotoFinder/queries/FotoSql.java +++ b/app/src/main/java/de/k3b/android/androFotoFinder/queries/FotoSql.java @@ -148,7 +148,7 @@ public class FotoSql extends FotoSqlBase { public static final int MEDIA_TYPE_IMAGE = MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE; // 1 // used to translate between LAST_MODIFIED in database (secs since 1970) and internal format (java date milli secs simce 1970) - private static final int LAST_MODIFIED_FACTOR = 1000; + public static final int LAST_MODIFIED_FACTOR = 1000; public static final int MEDIA_TYPE_IMAGE_PRIVATE = 1000 + MEDIA_TYPE_IMAGE; // 1001 APhoto manager specific public static final int MEDIA_TYPE_IMAGE_HIDDEN = 1100 + MEDIA_TYPE_IMAGE; // 1101 APhoto manager specific 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 b40c5094..ee157c1e 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 @@ -44,6 +44,7 @@ public void onChange(boolean selfChange, Uri uri) { } }; + public static MediaContent2DBUpdateService instance = null; private final Context context; private final SQLiteDatabase writableDatabase; @@ -57,24 +58,25 @@ public void clearMediaCopy() { DatabaseHelper.version2Upgrade_RecreateMediDbCopy(writableDatabase); } - public void rebuild(Context context, IProgessListener progessListener) { + public int rebuild(Context context, IProgessListener progessListener) { long start = new Date().getTime(); clearMediaCopy(); - MediaDBRepository.Impl.updateMediaCopy(context, writableDatabase, null, null, progessListener); - start = (new Date().getTime() - start) / 1000; - final String text = "load db " + start + " secs"; + int changeCount = MediaDBRepository.Impl.updateMediaCopy(context, writableDatabase, null, null, progessListener); + 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; } - public void update(Context context, IProgessListener progessListener) { + public int update(Context context, IProgessListener progessListener) { long start = new Date().getTime(); - MediaDBRepository.Impl.updateMediaCopy(context, writableDatabase, progessListener); - start = (new Date().getTime() - start) / 1000; - final String text = "update db " + start + " secs"; + int changeCount = MediaDBRepository.Impl.updateMediaCopy(context, writableDatabase, progessListener); + long timeInSecs = (new Date().getTime() - start) / 1000; + final String text = "update 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/androFotoFinder/queries/MediaDBRepository.java b/app/src/main/java/de/k3b/android/androFotoFinder/queries/MediaDBRepository.java index 44faa632..e277c0c8 100644 --- a/app/src/main/java/de/k3b/android/androFotoFinder/queries/MediaDBRepository.java +++ b/app/src/main/java/de/k3b/android/androFotoFinder/queries/MediaDBRepository.java @@ -23,6 +23,7 @@ import android.content.SharedPreferences; import android.database.Cursor; import android.database.DatabaseUtils; +import android.database.sqlite.SQLiteConstraintException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteStatement; import android.net.Uri; @@ -614,7 +615,7 @@ public static int updateMediaCopy( SharedPreferences prefsInstance = PreferenceManager .getDefaultSharedPreferences(context.getApplicationContext()); long maxDateAddedSecs = prefsInstance.getLong("maxDateAddedSecs", 0l); - return updateMediaCopy(context, db, null, new Date(maxDateAddedSecs), progessListener); + return updateMediaCopy(context, db, null, new Date(maxDateAddedSecs * FotoSql.LAST_MODIFIED_FACTOR), progessListener); } public static int updateMediaCopy( @@ -627,7 +628,7 @@ public static int updateMediaCopy( Calendar nextMonth = Calendar.getInstance(); nextMonth.add(Calendar.MONTH, 1); - nextMonthTimeInSecs = nextMonth.getTimeInMillis() / 1000; + nextMonthTimeInSecs = nextMonth.getTimeInMillis() / FotoSql.LAST_MODIFIED_FACTOR; long filterLastUpdateMinInMillis = (filterLastUpdateMin != null) ? (filterLastUpdateMin.getTime()) : 0L; if (filterLastUpdateMinInMillis != 0) { @@ -668,7 +669,7 @@ public static int updateMediaCopy( if (curDateAddedSecs > maxDateAddedSecs) { maxDateAddedSecs = curDateAddedSecs; } - isUpdate = (curDateAddedSecs <= filterLastUpdateMinInMillis / 1000); + isUpdate = (curDateAddedSecs <= filterLastUpdateMinInMillis / FotoSql.LAST_MODIFIED_FACTOR); long curDateUpdatedSecs = getDateInSecs(c, colLAST_MODIFIED); if (curDateUpdatedSecs > maxDateUpdatedSecs) { @@ -676,16 +677,23 @@ public static int updateMediaCopy( } if (isUpdate) { - updateCount++; lastSql = sqlUpdate; isUpdate = bindAndExecUpdate(c, sqlUpdate, curDateAddedSecs, curDateUpdatedSecs) > 0; // 0 affected update rows: must insert + + if (isUpdate) { + updateCount++; + } } if (!isUpdate) { - insertCout++; lastSql = sqlInsert; - bindAndExecInsert(c, sqlInsert, curDateAddedSecs, curDateUpdatedSecs); + try { + bindAndExecInsert(c, sqlInsert, curDateAddedSecs, curDateUpdatedSecs);//!!! + insertCout++; + } catch (SQLiteConstraintException ignore) { + // already in local database, ignore + } } lastSql = null; @@ -708,7 +716,7 @@ public static int updateMediaCopy( ", updated:" + updateCount + ", toal:" + progress + " / " + itemCount + - ") in " + ((endTime.getTime() - startTime.getTime()) / 1000) + + ") in " + ((endTime.getTime() - startTime.getTime()) / FotoSql.LAST_MODIFIED_FACTOR) + " Secs"; Log.i(LOG_TAG, message); } @@ -718,7 +726,7 @@ public static int updateMediaCopy( ", updated:" + updateCount + ", toal:" + progress + " / " + itemCount + - ") in " + ((endTime.getTime() - startTime.getTime()) / 1000) + + ") in " + ((endTime.getTime() - startTime.getTime()) / FotoSql.LAST_MODIFIED_FACTOR) + " Secs"; Log.e(LOG_TAG, "Cannot insert/update: " + lastSql + " from " + c + " in " + message, ex); } finally { @@ -745,12 +753,12 @@ private static void saveStats(Context context, long maxDateAddedSecs, long maxDa } protected static long getDateInSecs(Cursor c, int colPosition) { - long curDateAdded = (c.isNull(colPosition)) ? 0 : c.getLong(colPosition); - if (curDateAdded > nextMonthTimeInSecs) { + long dateInSecs = (c.isNull(colPosition)) ? 0 : c.getLong(colPosition); + if (dateInSecs > nextMonthTimeInSecs) { // colDATE_ADDED: some apps/libs use milliscs instead of secs. Fix this. - curDateAdded = curDateAdded / 1000; + dateInSecs = dateInSecs / FotoSql.LAST_MODIFIED_FACTOR; } - return curDateAdded; + return dateInSecs; } private static void save(SQLiteDatabase db, Cursor c, ContentValues contentValues, long lastUpdate) { diff --git a/app/src/main/java/de/k3b/android/widget/Dialogs.java b/app/src/main/java/de/k3b/android/widget/Dialogs.java index 51520b9a..dd4198a5 100644 --- a/app/src/main/java/de/k3b/android/widget/Dialogs.java +++ b/app/src/main/java/de/k3b/android/widget/Dialogs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020 by k3b. + * Copyright (c) 2015-2021 by k3b. * * This file is part of AndroFotoFinder / #APhotoManager. * @@ -173,17 +173,17 @@ protected boolean onContextMenuItemClick(int menuItemId, int itemIndex, String[] /** must be overwritten to implement dialog result. null==canceled */ abstract protected void onDialogResult(String clickedName, Object... parameters); - public void yesNoQuestion(Activity parent, final String title, String question, final Object... parameters) { - AlertDialog.Builder builder = new AlertDialog.Builder(parent); - builder.setTitle(title); - final TextView textView = new TextView(parent); - textView.setText(question); - builder.setView(textView); - builder.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - onDialogResult(null); - dialog.dismiss(); + public AlertDialog yesNoQuestion(Activity parent, final String title, String question, final Object... parameters) { + AlertDialog.Builder builder = new AlertDialog.Builder(parent); + builder.setTitle(title); + final TextView textView = new TextView(parent); + textView.setText(question); + builder.setView(textView); + builder.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + onDialogResult(null); + dialog.dismiss(); } }); builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { @@ -197,6 +197,7 @@ public void onClick(DialogInterface dialog, int which) { alertDialog.show(); fixLayout(alertDialog, textView); + return alertDialog; } public AlertDialog editFileName(Activity parent, CharSequence title, String name, final Object... parameters) {