From 9d4a52e9185caec9e5ed94f5b13c8182c8b62e99 Mon Sep 17 00:00:00 2001 From: k3b <1374583+k3b@users.noreply.github.com> Date: Thu, 18 Feb 2021 19:29:53 +0100 Subject: [PATCH] #155: ao10: fixed move photo(s) with and without autoprocessing --- .../media/AndroidExifInterfaceEx.java | 35 ++++++++++++++++++- .../queries/MergedMediaRepository.java | 4 +-- .../de/k3b/android/io/AndroidFileFacade.java | 9 ++++- .../android/io/DocumentFileTranslator.java | 11 +++--- .../metadata/android/en-US/changelogs/48.txt | 1 + .../src/main/java/de/k3b/io/FileCommands.java | 2 +- .../PhotoPropertiesBulkUpdateService.java | 7 ++-- 7 files changed, 57 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/de/k3b/android/androFotoFinder/media/AndroidExifInterfaceEx.java b/app/src/main/java/de/k3b/android/androFotoFinder/media/AndroidExifInterfaceEx.java index b24fcf50..af295183 100644 --- a/app/src/main/java/de/k3b/android/androFotoFinder/media/AndroidExifInterfaceEx.java +++ b/app/src/main/java/de/k3b/android/androFotoFinder/media/AndroidExifInterfaceEx.java @@ -20,6 +20,7 @@ package de.k3b.android.androFotoFinder.media; import android.content.ContentValues; +import android.net.Uri; import android.util.Log; import java.io.IOException; @@ -61,6 +62,18 @@ public ExifInterfaceEx create() { @Override public void saveAttributes(IFile inFile, IFile outFile, boolean deleteInFileOnFinish, Boolean hasXmp) throws IOException { + if (deleteInFileOnFinish) { + renameInDatabase(":saveAttributes", inFile.getCanonicalPath(), outFile.getCanonicalPath(), true); + } else { + if (inFile.equals(outFile)) { + // !!! + // renameSouraceFileBeforeReplaceOrThrow + + } else { + insertIntoDatabase(outFile, hasXmp); + } + } + //!!! update media database super.saveAttributes(inFile, outFile, deleteInFileOnFinish, hasXmp); this.hasXmp = hasXmp; } @@ -90,6 +103,26 @@ protected void beforeCloseSaveOutputStream() { super.beforeCloseSaveOutputStream(); } + private void insertIntoDatabase(IFile outFile, Boolean hasXmp) { + ContentValues values = new ContentValues(); + PhotoPropertiesMediaDBContentValues mediaValueAdapter = new PhotoPropertiesMediaDBContentValues().set(values, null); + + PhotoPropertiesUtil.copyNonEmpty(mediaValueAdapter, this); + + Date lastModified = new Date(); + TagSql.setFileModifyDate(values, lastModified); + if (this.hasXmp != null) { + if (this.hasXmp) { + TagSql.setXmpFileModifyDate(values, lastModified); + } else { + TagSql.setXmpFileModifyDate(values, TagSql.EXT_LAST_EXT_SCAN_NO_XMP); + } + } + + values.put(FotoSql.SQL_COL_PATH, outFile.getCanonicalPath()); + Uri result = FotoSql.getMediaDBApi().execInsert("Copy with Autoprocessing", values); + } + // TODO additional database parameters (see scanner) // DateLastModified, xmpDate, .... private boolean renameInDatabase(String dbgContext, String fromPath, String toPath, boolean thransferExif) { @@ -138,7 +171,7 @@ private void debugIdPaths(String dbgContext, String... paths) { " is not null"); final SelectedFiles selectedfiles = FotoSql.getSelectedfiles(sqlWhere.toString(), VISIBILITY.PRIVATE_PUBLIC); Log.d(Global.LOG_CONTEXT, dbgContext + "\n\t[" - + StringUtils.appendMessage((String[]) paths) + + StringUtils.appendMessage(paths) + "] :\n\t\t" + selectedfiles.toIdString() + " -> " + selectedfiles.toPathListString()); } diff --git a/app/src/main/java/de/k3b/android/androFotoFinder/queries/MergedMediaRepository.java b/app/src/main/java/de/k3b/android/androFotoFinder/queries/MergedMediaRepository.java index 74f4475a..693e5c52 100644 --- a/app/src/main/java/de/k3b/android/androFotoFinder/queries/MergedMediaRepository.java +++ b/app/src/main/java/de/k3b/android/androFotoFinder/queries/MergedMediaRepository.java @@ -74,7 +74,7 @@ public int execUpdate(String dbgContext, long id, ContentValues values) { public int execUpdate(String dbgContext, String path, ContentValues values, VISIBILITY visibility) { int result = super.execUpdate( dbgContext, path, values, visibility); - localDatabase.execUpdate(dbgContext, path, values, visibility); + result = localDatabase.execUpdate(dbgContext, path, values, visibility); return result; } @@ -185,7 +185,7 @@ public Uri execInsert(String dbgContext, ContentValues values) { // insert with same pk as contentprovider does values.put(FotoSql.SQL_COL_PK, FotoSql.getId(result)); } - localDatabase.execInsert(dbgContext, values); + result = localDatabase.execInsert(dbgContext, values); values.remove(FotoSql.SQL_COL_PK); return result; } diff --git a/app/src/main/java/de/k3b/android/io/AndroidFileFacade.java b/app/src/main/java/de/k3b/android/io/AndroidFileFacade.java index f381d550..4129a1f8 100644 --- a/app/src/main/java/de/k3b/android/io/AndroidFileFacade.java +++ b/app/src/main/java/de/k3b/android/io/AndroidFileFacade.java @@ -153,7 +153,14 @@ public boolean renameTo(@NonNull String newName) { @Override public boolean delete() { - return exists() && getAndroidFile(false).delete(); + boolean result = exists() && getAndroidFile(false).delete(); + + if (result) { + // File (and reference to it) does not exist any more + androidFileMayExist = false; + androidFile = null; + } + return result; } @Override diff --git a/app/src/main/java/de/k3b/android/io/DocumentFileTranslator.java b/app/src/main/java/de/k3b/android/io/DocumentFileTranslator.java index 793b44c6..d5083fa1 100644 --- a/app/src/main/java/de/k3b/android/io/DocumentFileTranslator.java +++ b/app/src/main/java/de/k3b/android/io/DocumentFileTranslator.java @@ -69,7 +69,7 @@ public class DocumentFileTranslator { private static final File internalRootCandidate = new File("/storage/emulated/0"); // for debugging private static int id = 1; - private String mDebugPrefix; + private final String mDebugPrefix; private static Root root = null; private DocumentFileTranslator(Context context, String namePrefix) { @@ -228,15 +228,16 @@ public DocumentFile getOrCreateDirectory(File directory) { */ public DocumentFile getDocumentFileOrDirOrNull(File fileOrDir, Boolean isDir) { DocumentFile result = null; - final String context = FileFacade.debugLogFacade ? (mDebugPrefix + "getDocumentFile('" + fileOrDir.getAbsolutePath() + - "') ") : null; + String path = fileOrDir != null ? fileOrDir.getAbsolutePath() : ""; + final String context = FileFacade.debugLogFacade ? (mDebugPrefix + "getDocumentFile('" + + path + "') ") : null; try { result = getDocumentFileOrDirImpl(fileOrDir); if ((context != null) && (result == null)) { Log.i(TAG, context + "not found"); } } catch (Exception ex) { - Log.w(TAG, mDebugPrefix + "getDocumentFile('" + fileOrDir.getAbsolutePath() + + Log.w(TAG, mDebugPrefix + "getDocumentFile('" + path + "') ", ex); } @@ -297,7 +298,7 @@ public static String pathFromUri(String uri) { private static class Root { private final Context context; - private Map dir2uri = new HashMap<>(); + private final Map dir2uri = new HashMap<>(); public Root(Context context) { this.context = context.getApplicationContext(); diff --git a/fastlane/metadata/android/en-US/changelogs/48.txt b/fastlane/metadata/android/en-US/changelogs/48.txt index fd970dc3..e52841cf 100644 --- a/fastlane/metadata/android/en-US/changelogs/48.txt +++ b/fastlane/metadata/android/en-US/changelogs/48.txt @@ -4,6 +4,7 @@ Changes from 0.8.3 to ??? * #155: Android-10 support (experimental) * #173: incremental media scanner * #180: Fixed: Show image with uri that cannot be translated to file (i.e. WhatsApp show photo in gallery) +* #93: Bugfix crash in Autoprocessing with date-based-rename when photo has no dateCreated * fixed CSV IPhotoProperties import * version bumbs android-9 (sdk-28), gradle-6.1.1, osmdroid-6.1.6 mapsforge:0.13.0 * new translation eu (Basque) diff --git a/fotolib2/src/main/java/de/k3b/io/FileCommands.java b/fotolib2/src/main/java/de/k3b/io/FileCommands.java index 6e6c1497..e8318eeb 100644 --- a/fotolib2/src/main/java/de/k3b/io/FileCommands.java +++ b/fotolib2/src/main/java/de/k3b/io/FileCommands.java @@ -155,7 +155,7 @@ private static boolean _osFileCopy(IFile targetFullPath, IFile sourceFullPath, F */ public int applyExifChanges(boolean move, PhotoPropertiesDiffCopy exifChanges, SelectedFiles selectedFiles, IProgessListener progessListener) { // source files are the same as dest files. - final File[] destFiles = selectedFiles.getFiles(); + final IFile[] destFiles = selectedFiles.getIFiles(); return moveOrCopyFiles(move, "change_exif", exifChanges, selectedFiles, destFiles, progessListener); } diff --git a/fotolib2/src/main/java/de/k3b/media/PhotoPropertiesBulkUpdateService.java b/fotolib2/src/main/java/de/k3b/media/PhotoPropertiesBulkUpdateService.java index 7e47abef..a13a588f 100644 --- a/fotolib2/src/main/java/de/k3b/media/PhotoPropertiesBulkUpdateService.java +++ b/fotolib2/src/main/java/de/k3b/media/PhotoPropertiesBulkUpdateService.java @@ -99,7 +99,7 @@ public PhotoPropertiesUpdateHandler applyChanges(IFile inFilePath, IFile outFile PhotoPropertiesUpdateHandler exifHandler = null; try { long lastModified = inFilePath.lastModified(); - exifHandler = PhotoPropertiesUpdateHandler.create(inFilePath, outFile, false, "PhotoPropertiesUpdateHandler:"); + exifHandler = PhotoPropertiesUpdateHandler.create(inFilePath, outFile, deleteOriginalWhenFinished, "PhotoPropertiesUpdateHandler:"); debugExif(sb, "old", exifHandler, inFilePath); List oldTags = exifHandler.getTags(); @@ -119,8 +119,11 @@ public PhotoPropertiesUpdateHandler applyChanges(IFile inFilePath, IFile outFile if (!sameFile || (changed != null)) { debugExif(sb, "assign ", exifHandler, inFilePath); + exifHandler.save("PhotoPropertiesUpdateHandler save"); + // After move inFilePath is invalid + if (LibGlobal.preserveJpgFileModificationDate) { // preseve file modification date inFilePath.setLastModified(lastModified); @@ -128,7 +131,7 @@ public PhotoPropertiesUpdateHandler applyChanges(IFile inFilePath, IFile outFile if (sb != null) { PhotoPropertiesUpdateHandler exifVerify = PhotoPropertiesUpdateHandler.create(inFilePath, - null, false, "dbg in PhotoPropertiesUpdateHandler", true, true, false); + null, deleteOriginalWhenFinished, "dbg in PhotoPropertiesUpdateHandler", true, true, false); debugExif(sb, "new ", exifVerify, inFilePath); }