diff --git a/app/src/main/java/de/k3b/android/androFotoFinder/gallery/cursor/GalleryCursorFragment.java b/app/src/main/java/de/k3b/android/androFotoFinder/gallery/cursor/GalleryCursorFragment.java
index 434ed4e5..41621815 100644
--- a/app/src/main/java/de/k3b/android/androFotoFinder/gallery/cursor/GalleryCursorFragment.java
+++ b/app/src/main/java/de/k3b/android/androFotoFinder/gallery/cursor/GalleryCursorFragment.java
@@ -609,7 +609,7 @@ private void repairMissingDisplayNames() {
@Override
protected void doInBackground(Long id, Cursor cursor) {
if (mPathColNo == -2) mPathColNo = cursor.getColumnIndex(FotoSql.SQL_COL_PATH);
- mResultCount += PhotoPropertiesMediaFilesScanner.getInstance(getActivity()).updatePathRelatedFields(getActivity(), cursor, cursor.getString(mPathColNo), mColumnIndexPK, mPathColNo);
+ mResultCount += PhotoPropertiesMediaFilesScanner.getInstance(getActivity()).updatePathRelatedFields(cursor, cursor.getString(mPathColNo), mColumnIndexPK, mPathColNo);
}
@Override
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 e277c0c8..77353bba 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
@@ -74,7 +74,7 @@ public class MediaDBRepository implements IMediaRepositoryApi {
public static final String LOG_TAG = FotoSql.LOG_TAG + "DB";
// #155
- public static final boolean debugEnabledSqlRefresh = true;
+ public static final boolean DEBUG_ENABLED_SQL_REFRESH = true;
private static final String MODUL_NAME = MediaDBRepository.class.getSimpleName();
private static String currentUpdateReason = null;
@@ -87,13 +87,13 @@ public MediaDBRepository(SQLiteDatabase db) {
}
@Override
- public Cursor createCursorForQuery(StringBuilder out_debugMessage, String dbgContext,
+ public Cursor createCursorForQuery(StringBuilder outDebugMessage, String dbgContext,
QueryParameter parameters, VISIBILITY visibility,
CancellationSignal cancellationSignal) {
if (visibility != null) {
FotoSql.setWhereVisibility(parameters, visibility);
}
- return createCursorForQuery(out_debugMessage, dbgContext,
+ return createCursorForQuery(outDebugMessage, dbgContext,
parameters.toWhere(), parameters.toAndroidParameters(),
parameters.toGroupBy(), parameters.toHaving(),
parameters.toOrderBy(),
@@ -102,11 +102,11 @@ public Cursor createCursorForQuery(StringBuilder out_debugMessage, String dbgCon
}
@Override
- public Cursor createCursorForQuery(StringBuilder out_debugMessage, String dbgContext, String from,
+ public Cursor createCursorForQuery(StringBuilder outDebugMessage, String dbgContext, String from,
String sqlWhereStatement, String[] sqlWhereParameters,
String sqlSortOrder, CancellationSignal cancellationSignal,
String... sqlSelectColums) {
- return createCursorForQuery(out_debugMessage, dbgContext,
+ return createCursorForQuery(outDebugMessage, dbgContext,
sqlWhereStatement, sqlWhereParameters,
null, null,
sqlSortOrder, cancellationSignal, sqlSelectColums);
@@ -115,7 +115,7 @@ public Cursor createCursorForQuery(StringBuilder out_debugMessage, String dbgCon
/**
* every cursor query should go through this. adds logging if enabled
*/
- private Cursor createCursorForQuery(StringBuilder out_debugMessage, String dbgContext,
+ private Cursor createCursorForQuery(StringBuilder outDebugMessage, String dbgContext,
String sqlWhereStatement, String[] selectionArgs, String groupBy,
String having, String sqlSortOrder,
CancellationSignal cancellationSignal, final String... sqlSelectColums) {
@@ -125,24 +125,24 @@ private Cursor createCursorForQuery(StringBuilder out_debugMessage, String dbgCo
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- query = db.query(false, Impl.table, sqlSelectColums, sqlWhereStatement, selectionArgs,
+ query = db.query(false, Impl.DATABASE_TABLE_NAME, sqlSelectColums, sqlWhereStatement, selectionArgs,
groupBy, having, sqlSortOrder, null, cancellationSignal);
} else {
- query = db.query(false, Impl.table, sqlSelectColums, sqlWhereStatement, selectionArgs,
+ query = db.query(false, Impl.DATABASE_TABLE_NAME, sqlSelectColums, sqlWhereStatement, selectionArgs,
groupBy, having, sqlSortOrder, null);
}
} catch (Exception ex) {
excpetion = ex;
} finally {
- if ((excpetion != null) || Global.debugEnabledSql || (out_debugMessage != null)) {
+ if ((excpetion != null) || Global.debugEnabledSql || (outDebugMessage != null)) {
final int count = (query == null) ? 0 : query.getCount();
- StringBuilder message = StringUtils.appendMessage(out_debugMessage, excpetion,
+ StringBuilder message = StringUtils.appendMessage(outDebugMessage, excpetion,
dbgContext, MODUL_NAME +
".createCursorForQuery:\n",
- QueryParameter.toString(sqlSelectColums, null, Impl.table, sqlWhereStatement,
+ QueryParameter.toString(sqlSelectColums, null, Impl.DATABASE_TABLE_NAME, sqlWhereStatement,
selectionArgs, sqlSortOrder, count));
- if (out_debugMessage == null) {
+ if (outDebugMessage == null) {
Log.i(LOG_TAG, message.toString(), excpetion);
} // else logging is done by caller
}
@@ -187,7 +187,7 @@ public int exexUpdateImpl(String dbgContext, ContentValues values, String sqlWhe
int result = -1;
Exception excpetion = null;
try {
- result = db.update(Impl.table, values, sqlWhere, selectionArgs);
+ result = db.update(Impl.DATABASE_TABLE_NAME, values, sqlWhere, selectionArgs);
if (result != 0) {
currentUpdateId++;
currentUpdateReason = dbgContext;
@@ -211,7 +211,7 @@ public ContentValues getDbContent(long id) {
Cursor c = null;
try {
c = this.createCursorForQuery(null, "getDbContent",
- Impl.table, FotoSql.FILTER_COL_PK, new String[]{"" + id}, null, null, "*");
+ Impl.DATABASE_TABLE_NAME, FotoSql.FILTER_COL_PK, new String[]{"" + id}, null, null, "*");
if (c.moveToNext()) {
ContentValues values = new ContentValues();
DatabaseUtils.cursorRowToContentValues(c, values);
@@ -238,7 +238,7 @@ public Uri execInsert(String dbgContext, ContentValues values) {
Exception excpetion = null;
try {
// on my android-4.4 insert with media_type=1001 (private) does insert with media_type=1 (image)
- result = db.insertWithOnConflict(Impl.table, null, values, SQLiteDatabase.CONFLICT_REPLACE );
+ result = db.insertWithOnConflict(Impl.DATABASE_TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE);
if (result == -1) {
return null;
}
@@ -284,7 +284,7 @@ public int deleteMedia(String dbgContext, String where, String[] selectionArgs,
lastUsedWhereClause = FotoSql.SQL_COL_PATH + " is null";
lastSelectionArgs = null;
- delCount = db.delete(Impl.table, lastUsedWhereClause, lastSelectionArgs);
+ delCount = db.delete(Impl.DATABASE_TABLE_NAME, lastUsedWhereClause, lastSelectionArgs);
if (Global.debugEnabledSql || LibGlobal.debugEnabledJpg) {
Log.i(LOG_TAG, dbgContext + "-b: " +
MODUL_NAME +
@@ -293,7 +293,7 @@ public int deleteMedia(String dbgContext, String where, String[] selectionArgs,
lastUsedWhereClause, lastSelectionArgs, null, delCount));
}
} else {
- delCount = db.delete(Impl.table, lastUsedWhereClause, lastSelectionArgs);
+ delCount = db.delete(Impl.DATABASE_TABLE_NAME, lastUsedWhereClause, lastSelectionArgs);
if (Global.debugEnabledSql || LibGlobal.debugEnabledJpg) {
Log.i(LOG_TAG, dbgContext + ": " +
MODUL_NAME +
@@ -330,7 +330,7 @@ public long getCurrentUpdateId() {
@Override
public boolean mustRequery(long updateId) {
final boolean modified = currentUpdateId != updateId;
- if (modified && MediaDBRepository.debugEnabledSqlRefresh) {
+ if (modified && MediaDBRepository.DEBUG_ENABLED_SQL_REFRESH) {
Log.i(MediaDBRepository.LOG_TAG, "mustRequery: true because of " + currentUpdateReason);
}
return modified;
@@ -397,11 +397,12 @@ public static ContentValues getContentValues(String fullFilePathFilter, ContentV
public static class Impl {
+ public static final String DATABASE_TABLE_NAME = "files";
/**
* SQL to create copy of contentprovider MediaStore.Images.
* copied from android-4.4 android database. Removed columns not used
*/
- public static final String[] DDL = new String[]{
+ protected static final String[] DDL = new String[]{
"DROP TABLE IF EXISTS \"files\"",
"CREATE TABLE \"files\" (\n" +
"\t_id INTEGER PRIMARY KEY AUTOINCREMENT,\n" +
@@ -431,8 +432,7 @@ public static class Impl {
"CREATE INDEX sort_index ON files(datetaken ASC, _id ASC)",
"CREATE INDEX title_idx ON files(title)",
};
-
- public static final String table = "files";
+ private static final int COL_INT_MIN = 0;
// same colum order as in DDL
private static final String[] USED_MEDIA_COLUMNS = new String[]{
// INTEGER 0 .. 10
@@ -460,17 +460,22 @@ public static class Impl {
SQL_COL_LAT,
SQL_COL_LON,
};
+ private static final int COL_INT_MAX = 10;
+ private static final int COL_TXT_MIN = 11;
+ private static final int COL_TXT_MAX = 16;
+ private static final int COL_DBL_MIN = 17;
+ private static final int COL_DBL_MAX = 18;
+ // COL_ID must be col#0 to macke update where id=? work
+ private static final int COL_ID = COL_INT_MIN; // = 0
+ private static final int COL_DATE_ADDED = 1;
+ private static final int COL_LAST_MODIFIED = 2;
+ // do not copy 6==SQL_COL_EXT_XMP_LAST_MODIFIED_DATE
+ // on android-10 and above wich is used as rescan marker
+ private static final int COL_INT_COPY_IGNORE = (Global.useAo10MediaImageDbReplacement) ? 6 : -1;
+
+ private Impl() {
+ }
- private static final int intMin = 0;
- private static final int intMax = 10;
- private static final int txtMin = 11;
- private static final int txtMax = 16;
- private static final int dblMin = 17;
- private static final int dblMax = 18;
-
- private static final int colID = 0;
- private static final int colDATE_ADDED = 1;
- private static final int colLAST_MODIFIED = 2;
private static final String FILTER_EXPR_AFFECTED_FILES
= "(" + FotoSql.FILTER_EXPR_PRIVATE_PUBLIC
+ " OR " + SQL_COL_PATH + " like '%" + AlbumFile.SUFFIX_VALBUM + "' "
@@ -484,23 +489,23 @@ public static class Impl {
private static long nextMonthTimeInSecs;
private static boolean isLomg(int index) {
- return index >= intMin && index <= intMax;
+ return index >= COL_INT_MIN && index <= COL_INT_MAX;
}
// private Object get(Cursor cursor, columIndex)
private static boolean isString(int index) {
- return index >= txtMin && index <= txtMax;
+ return index >= COL_TXT_MIN && index <= COL_TXT_MAX;
}
private static boolean isDouble(int index) {
- return index >= dblMin && index <= dblMax;
+ return index >= COL_DBL_MIN && index <= COL_DBL_MAX;
}
private static String getSqlInsertWithParams() {
StringBuilder sql = new StringBuilder();
- sql.append("INSERT INTO ").append(table).append("(").append(USED_MEDIA_COLUMNS[0]);
+ sql.append("INSERT INTO ").append(DATABASE_TABLE_NAME).append("(").append(USED_MEDIA_COLUMNS[0]);
for (int i = 1; i < USED_MEDIA_COLUMNS.length; i++) {
sql.append(", ").append(USED_MEDIA_COLUMNS[i]);
}
@@ -515,7 +520,7 @@ private static String getSqlInsertWithParams() {
private static String getSqlUpdateWithParams() {
StringBuilder sql = new StringBuilder();
- sql.append("UPDATE ").append(table).append(" SET ");
+ sql.append("UPDATE ").append(DATABASE_TABLE_NAME).append(" SET ");
for (int i = 1; i < USED_MEDIA_COLUMNS.length; i++) {
if (i > 1) sql.append(", ");
sql.append(USED_MEDIA_COLUMNS[i]).append("=?");
@@ -528,28 +533,28 @@ private static int bindAndExecUpdate(Cursor c, SQLiteStatement sql, long dateAdd
sql.clearBindings();
// sql where
- sql.bindLong(dblMax + 1, c.getLong(intMin));
+ sql.bindLong(COL_DBL_MAX + 1, c.getLong(COL_ID));
- for (int i = intMin + 1; i <= intMax; i++) {
- if (!c.isNull(i)) {
+ for (int i = COL_INT_MIN + 1; i <= COL_INT_MAX; i++) {
+ if (COL_INT_COPY_IGNORE != i && !c.isNull(i)) {
sql.bindLong(i, c.getLong(i));
}
}
- for (int i = txtMin; i <= txtMax; i++) {
+ for (int i = COL_TXT_MIN; i <= COL_TXT_MAX; i++) {
if (!c.isNull(i)) {
sql.bindString(i, c.getString(i));
}
}
- for (int i = dblMin; i <= dblMax; i++) {
+ for (int i = COL_DBL_MIN; i <= COL_DBL_MAX; i++) {
if (!c.isNull(i)) {
sql.bindDouble(i, c.getDouble(i));
}
}
if (dateAdded != 0) {
- sql.bindLong(colDATE_ADDED, dateAdded);
+ sql.bindLong(COL_DATE_ADDED, dateAdded);
}
if (dateUpdated != 0) {
- sql.bindLong(colLAST_MODIFIED, dateUpdated);
+ sql.bindLong(COL_LAST_MODIFIED, dateUpdated);
}
return sql.executeUpdateDelete();
}
@@ -557,26 +562,26 @@ private static int bindAndExecUpdate(Cursor c, SQLiteStatement sql, long dateAdd
private static void bindAndExecInsert(Cursor c, SQLiteStatement sql, long dateAdded, long dateUpdated) {
sql.clearBindings();
- for (int i = intMin; i <= intMax; i++) {
- if (!c.isNull(i)) {
+ for (int i = COL_INT_MIN; i <= COL_INT_MAX; i++) {
+ if (COL_INT_COPY_IGNORE != i && !c.isNull(i)) {
sql.bindLong(i + 1, c.getLong(i));
}
}
- for (int i = txtMin; i <= txtMax; i++) {
+ for (int i = COL_TXT_MIN; i <= COL_TXT_MAX; i++) {
if (!c.isNull(i)) {
sql.bindString(i + 1, c.getString(i));
}
}
- for (int i = dblMin; i <= dblMax; i++) {
+ for (int i = COL_DBL_MIN; i <= COL_DBL_MAX; i++) {
if (!c.isNull(i)) {
sql.bindDouble(i + 1, c.getDouble(i));
}
}
if (dateAdded != 0) {
- sql.bindLong(colDATE_ADDED + 1, dateAdded);
+ sql.bindLong(COL_DATE_ADDED + 1, dateAdded);
}
if (dateUpdated != 0) {
- sql.bindLong(colLAST_MODIFIED + 1, dateUpdated);
+ sql.bindLong(COL_LAST_MODIFIED + 1, dateUpdated);
}
sql.executeInsert();
}
@@ -602,10 +607,9 @@ private static ContentValues getContentValues(Cursor cursor, ContentValues desti
public static void clearMedaiCopy(SQLiteDatabase db) {
try {
- db.execSQL("DROP TABLE " + table);
+ db.execSQL("DROP TABLE " + DATABASE_TABLE_NAME);
} catch (Exception ex) {
// Log.e(LOG_TAG, "FotoSql.execGetFotoPaths() Cannot get path from: " + FotoSql.SQL_COL_PATH + " like '" + pathFilter +"'", ex);
- } finally {
}
}
@@ -665,13 +669,13 @@ public static int updateMediaCopy(
long maxDateUpdatedSecs = 0;
while (c.moveToNext()) {
- long curDateAddedSecs = getDateInSecs(c, colDATE_ADDED);
+ long curDateAddedSecs = getDateInSecs(c, COL_DATE_ADDED);
if (curDateAddedSecs > maxDateAddedSecs) {
maxDateAddedSecs = curDateAddedSecs;
}
isUpdate = (curDateAddedSecs <= filterLastUpdateMinInMillis / FotoSql.LAST_MODIFIED_FACTOR);
- long curDateUpdatedSecs = getDateInSecs(c, colLAST_MODIFIED);
+ long curDateUpdatedSecs = getDateInSecs(c, COL_LAST_MODIFIED);
if (curDateUpdatedSecs > maxDateUpdatedSecs) {
maxDateUpdatedSecs = curDateUpdatedSecs;
}
@@ -698,11 +702,10 @@ public static int updateMediaCopy(
lastSql = null;
- if ((progessListener != null) && (progress % 100) == 0) {
- if (!progessListener.onProgress(progress, itemCount, context.getString(R.string.scanner_update_result_format, progress))) {
- // canceled in gui thread
- return -progress;
- }
+ if ((progessListener != null) && (progress % 100) == 0 &&
+ !progessListener.onProgress(progress, itemCount, context.getString(R.string.scanner_update_result_format, progress))) {
+ // canceled in gui thread
+ return -progress;
}
progress++;
} // while over all old items
@@ -760,17 +763,5 @@ protected static long getDateInSecs(Cursor c, int colPosition) {
}
return dateInSecs;
}
-
- private static void save(SQLiteDatabase db, Cursor c, ContentValues contentValues, long lastUpdate) {
- boolean isNew = (c.getLong(colDATE_ADDED) > lastUpdate);
-
- if (isNew) {
- db.insert(table, null, contentValues);
- } else {
- String[] params = new String[]{"" + c.getLong(colID)};
- contentValues.remove(SQL_COL_PK);
- db.update(table, contentValues, FotoSql.FILTER_COL_PK, params);
- }
- }
}
}
diff --git a/app/src/main/java/de/k3b/android/util/PhotoPropertiesMediaFilesScanner.java b/app/src/main/java/de/k3b/android/util/PhotoPropertiesMediaFilesScanner.java
index 84050e54..e89fd845 100644
--- a/app/src/main/java/de/k3b/android/util/PhotoPropertiesMediaFilesScanner.java
+++ b/app/src/main/java/de/k3b/android/util/PhotoPropertiesMediaFilesScanner.java
@@ -29,7 +29,6 @@
import android.media.MediaScannerConnection;
import android.os.Build;
import android.provider.MediaStore;
-import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
@@ -45,9 +44,7 @@
import de.k3b.LibGlobal;
import de.k3b.android.androFotoFinder.Global;
import de.k3b.android.androFotoFinder.media.PhotoPropertiesMediaDBContentValues;
-import de.k3b.android.androFotoFinder.queries.FotoSql;
import de.k3b.android.androFotoFinder.queries.IMediaRepositoryApi;
-import de.k3b.android.androFotoFinder.tagDB.TagSql;
import de.k3b.database.QueryParameter;
import de.k3b.geo.api.GeoPointDto;
import de.k3b.geo.api.IGeoPointInfo;
@@ -60,13 +57,36 @@
import de.k3b.media.PhotoPropertiesXmpSegment;
import de.k3b.tagDB.TagRepository;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.EXT_LAST_EXT_SCAN_NO_XMP;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.SQL_COL_EXT_DESCRIPTION;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.SQL_COL_EXT_RATING;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.SQL_COL_EXT_TAGS;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.SQL_COL_EXT_TITLE;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.SQL_COL_LAST_MODIFIED;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.SQL_COL_LAT;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.SQL_COL_LON;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.SQL_COL_PATH;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.SQL_COL_PK;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.SQL_COL_SIZE;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.SQL_TABLE_EXTERNAL_CONTENT_URI_FILE;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.addDateAdded;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.execDeleteByPath;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.execGetPathIdMap;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.fixPrivate;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.getMediaDBApi;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.getWhereInFileNames;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.queryChangePath;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.setVisibility;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.setWhereFileNames;
+import static de.k3b.android.androFotoFinder.tagDB.TagSql.setXmpFileModifyDate;
+
/**
* Android Media Scanner for images/photos/jpg compatible with android-5.0 Media scanner.
* This Class handles standard Android-5.0 image fields.
- *
+ *
* Since android.media.MediaScannerConnection does not work on my android-4.2
* here is my own implementation.
- *
+ *
* Created by k3b on 14.09.2015.
*/
public abstract class PhotoPropertiesMediaFilesScanner {
@@ -78,15 +98,15 @@ public abstract class PhotoPropertiesMediaFilesScanner {
protected static final String DB_LATITUDE = MediaStore.Images.Media.LATITUDE;
*/
- protected static final String DB_TITLE = FotoSql.SQL_COL_EXT_TITLE;
+ protected static final String DB_TITLE = SQL_COL_EXT_TITLE;
private static final String DB_WIDTH = MediaStore.MediaColumns.WIDTH;
private static final String DB_HEIGHT = MediaStore.MediaColumns.HEIGHT;
private static final String DB_MIME_TYPE = MediaStore.MediaColumns.MIME_TYPE;
protected static final String DB_ORIENTATION = MediaStore.Images.Media.ORIENTATION;
- protected static final String DB_DATA = FotoSql.SQL_COL_PATH; // _data
+ protected static final String DB_DATA = SQL_COL_PATH; // _data
protected static final String DB_DISPLAY_NAME = MediaStore.MediaColumns.DISPLAY_NAME;
- private static final String DB_SIZE = FotoSql.SQL_COL_SIZE;
+ private static final String DB_SIZE = SQL_COL_SIZE;
public static final int DEFAULT_SCAN_DEPTH = 22;
public static final String MEDIA_IGNORE_FILENAME = FileUtils.MEDIA_IGNORE_FILENAME;
@@ -98,7 +118,7 @@ public abstract class PhotoPropertiesMediaFilesScanner {
public final Context mContext;
- private Map noMediaCache = new HashMap<>();
+ private final Map noMediaCache = new HashMap<>();
public PhotoPropertiesMediaFilesScanner(Context context) {
mContext = context.getApplicationContext();
@@ -108,9 +128,9 @@ public PhotoPropertiesMediaFilesScanner(Context context) {
public static void notifyChanges(Context context, String why) {
if (Global.debugEnabled) {
Log.i(Global.LOG_CONTEXT, CONTEXT + "notifyChanges(" + why + ") "
- + FotoSql.SQL_TABLE_EXTERNAL_CONTENT_URI_FILE);
+ + SQL_TABLE_EXTERNAL_CONTENT_URI_FILE);
}
- context.getContentResolver().notifyChange(FotoSql.SQL_TABLE_EXTERNAL_CONTENT_URI_FILE, null);
+ context.getContentResolver().notifyChange(SQL_TABLE_EXTERNAL_CONTENT_URI_FILE, null);
}
public static boolean isNoMedia(int maxLevel, IFile[] pathNames) {
@@ -125,10 +145,6 @@ public static boolean isNoMedia(int maxLevel, IFile[] pathNames) {
return false;
}
- public static boolean isNoMedia(IFile path) {
- return isNoMedia(path, PhotoPropertiesMediaFilesScanner.DEFAULT_SCAN_DEPTH);
- }
-
public static boolean isNoMedia(IFile path, int maxLevel) {
return isNoMedia(path, maxLevel, null);
}
@@ -172,7 +188,7 @@ public static int hideFolderMedia(Activity context, String path) {
if (Global.debugEnabled) {
Log.i(Global.LOG_CONTEXT, CONTEXT + " hideFolderMedia: delete from media db " + path + "/**");
}
- result = FotoSql.execDeleteByPath(CONTEXT + " hideFolderMedia", path, VISIBILITY.PRIVATE_PUBLIC);
+ result = execDeleteByPath(CONTEXT + " hideFolderMedia", path, VISIBILITY.PRIVATE_PUBLIC);
if (result > 0) {
PhotoPropertiesMediaFilesScanner.notifyChanges(context, "hide " + path + "/**");
}
@@ -181,8 +197,33 @@ public static int hideFolderMedia(Activity context, String path) {
return result;
}
+ /**
+ * in secs since 1970
+ */
+ protected static long getXmpFilelastModified(PhotoPropertiesXmpSegment xmpContent) {
+ long xmpFilelastModified = 0;
+ if (xmpContent != null) {
+ xmpFilelastModified = xmpContent.getFilelastModified();
+ }
+ if (xmpFilelastModified == 0) {
+ xmpFilelastModified = EXT_LAST_EXT_SCAN_NO_XMP;
+ }
+ return xmpFilelastModified;
+ }
+
+ /**
+ * sets the path related fields
+ */
+ public static String setFileFields(ContentValues values, File file) {
+ String newAbsolutePath = FileUtils.tryGetCanonicalPath(file, file.getAbsolutePath());
+ setPathRelatedFieldsIfNeccessary(values, newAbsolutePath, null);
+ values.put(SQL_COL_LAST_MODIFIED, file.lastModified() / 1000);
+ values.put(DB_SIZE, file.length());
+ return newAbsolutePath;
+ }
+
public int updateMediaDatabaseAndroid42(Context context, IFile[] oldPathNames, IFile... newPathNames) {
- IMediaRepositoryApi api = FotoSql.getMediaDBApi();
+ IMediaRepositoryApi api = getMediaDBApi();
try {
api.beginTransaction();
final boolean hasNew = excludeNomediaFiles(newPathNames) > 0;
@@ -195,9 +236,9 @@ public int updateMediaDatabaseAndroid42(Context context, IFile[] oldPathNames, I
result = deleteInMediaDatabase(oldPathNames);
}
if (hasNew) {
- result = insertIntoMediaDatabase(context, newPathNames);
+ result = insertIntoMediaDatabase(newPathNames);
}
- TagSql.fixPrivate();
+ fixPrivate();
api.setTransactionSuccessful();
return result;
} finally {
@@ -206,7 +247,7 @@ public int updateMediaDatabaseAndroid42(Context context, IFile[] oldPathNames, I
}
/**
- * Replace all files that either non-jpg or in ".nomedia" folder with null so they wont be
+ * Replace all files that either non-jpg or in ".nomedia" folder with null so they will not be
* processed by media scanner
*
* @return number of items left.
@@ -230,7 +271,7 @@ private int excludeNomediaFiles(IFile[] fullPathNames) {
return itemsLeft;
}
- private int insertIntoMediaDatabase(Context context, IFile[] newPathNames) {
+ private int insertIntoMediaDatabase(IFile[] newPathNames) {
int modifyCount = 0;
if ((newPathNames != null) && (newPathNames.length > 0)) {
@@ -238,7 +279,7 @@ private int insertIntoMediaDatabase(Context context, IFile[] newPathNames) {
Log.i(Global.LOG_CONTEXT, CONTEXT + "A42 scanner starting with " + newPathNames.length + " files " + newPathNames[0] + "...");
}
- Map inMediaDb = FotoSql.execGetPathIdMap(newPathNames);
+ Map inMediaDb = execGetPathIdMap(newPathNames);
for (IFile fileName : newPathNames) {
if (fileName != null) {
@@ -265,9 +306,9 @@ private int deleteInMediaDatabase(IFile[] oldPathNames) {
int modifyCount = 0;
if ((oldPathNames != null) && (oldPathNames.length > 0)) {
- String sqlWhere = FotoSql.getWhereInFileNames(oldPathNames);
+ String sqlWhere = getWhereInFileNames(oldPathNames);
try {
- modifyCount = FotoSql.getMediaDBApi().deleteMedia(CONTEXT + "deleteInMediaDatabase", sqlWhere, null, true);
+ modifyCount = getMediaDBApi().deleteMedia(CONTEXT + "deleteInMediaDatabase", sqlWhere, null, true);
if (Global.debugEnabled) {
Log.d(Global.LOG_CONTEXT, CONTEXT + "deleteInMediaDatabase(len=" + oldPathNames.length + ", files='" + oldPathNames[0] + "'...) result count=" + modifyCount);
}
@@ -279,6 +320,13 @@ private int deleteInMediaDatabase(IFile[] oldPathNames) {
return modifyCount;
}
+ /**
+ * updates values with current values of file
+ */
+ public PhotoPropertiesMediaDBContentValues getExifFromFile(IFile jpgFile) {
+ return getExifFromFile(createDefaultContentValues(), jpgFile);
+ }
+
/**
* change path and path dependant fields in media database
*/
@@ -310,26 +358,31 @@ private int renameInMediaDatabase(Context context, IFile[] oldPathNames, IFile..
int modifyCount =
deleteInMediaDatabase(deleteFileNames.toArray(new IFile[deleteFileNames.size()]))
+ renameInMediaDatabase(context, old2NewFileNames)
- + insertIntoMediaDatabase(context, insertFileNames.toArray(new IFile[insertFileNames.size()]));
+ + insertIntoMediaDatabase(insertFileNames.toArray(new IFile[insertFileNames.size()]));
return modifyCount;
}
return 0;
}
+ private void updateTagRepository(List tags) {
+ TagRepository tagRepository = TagRepository.getInstance();
+ tagRepository.includeTagNamesIfNotFound(tags);
+ }
+
private int renameInMediaDatabase(Context context, Map old2NewFileNames) {
int modifyCount = 0;
if (old2NewFileNames.size() > 0) {
- QueryParameter query = new QueryParameter(FotoSql.queryChangePath);
- FotoSql.setWhereFileNames(query, old2NewFileNames.keySet().toArray(new String[old2NewFileNames.size()]));
+ QueryParameter query = new QueryParameter(queryChangePath);
+ setWhereFileNames(query, old2NewFileNames.keySet().toArray(new String[old2NewFileNames.size()]));
Cursor c = null;
try {
- c = FotoSql.getMediaDBApi().createCursorForQuery(null, "renameInMediaDatabase", query, VISIBILITY.PRIVATE_PUBLIC, null);
- int pkColNo = c.getColumnIndex(FotoSql.SQL_COL_PK);
- int pathColNo = c.getColumnIndex(FotoSql.SQL_COL_PATH);
+ c = getMediaDBApi().createCursorForQuery(null, "renameInMediaDatabase", query, VISIBILITY.PRIVATE_PUBLIC, null);
+ int pkColNo = c.getColumnIndex(SQL_COL_PK);
+ int pathColNo = c.getColumnIndex(SQL_COL_PATH);
while (c.moveToNext()) {
String oldPath = c.getString(pathColNo);
- modifyCount += updatePathRelatedFields(context, c, old2NewFileNames.get(oldPath), pkColNo, pathColNo);
+ modifyCount += updatePathRelatedFields(c, old2NewFileNames.get(oldPath), pkColNo, pathColNo);
}
} catch (Exception ex) {
Log.e(Global.LOG_CONTEXT, CONTEXT + "execChangePaths() error :", ex);
@@ -344,12 +397,39 @@ private int renameInMediaDatabase(Context context, Map old2NewFi
return modifyCount;
}
- /** updates values with current values of file */
- public PhotoPropertiesMediaDBContentValues getExifFromFile(IFile jpgFile) {
- return getExifFromFile(createDefaultContentValues(), jpgFile);
+
+ protected IGeoPointInfo getPositionFromMeta(String absoluteJpgPath, String id, IPhotoProperties exif) {
+ if (exif != null) {
+ Double latitude = exif.getLatitude();
+ if (latitude != null) {
+ return new GeoPointDto(latitude, exif.getLongitude(), GeoPointDto.NO_ZOOM).setId(id);
+ }
+ PhotoPropertiesXmpSegment xmpContent = PhotoPropertiesXmpSegment.loadXmpSidecarContentOrNull(absoluteJpgPath, "getPositionFromFile");
+ if (xmpContent != null) {
+ latitude = xmpContent.getLatitude();
+ if (latitude != null) {
+ return new GeoPointDto(latitude, xmpContent.getLongitude(), GeoPointDto.NO_ZOOM).setId(id);
+ }
+ }
+ }
+
+ return null;
+ }
+
+ protected abstract IPhotoProperties loadNonMediaValues(ContentValues destinationValues, IFile jpgFile, IPhotoProperties xmpContent);
+
+ /**
+ * @return number of copied properties
+ */
+ protected int getExifValues(PhotoPropertiesMediaDBContentValues dest, IPhotoProperties src) {
+ return PhotoPropertiesUtil.copyNonEmpty(dest, src);
}
- /** updates values with current values of file. */
+ public abstract IGeoPointInfo getPositionFromFile(String absolutePath, String id);
+
+ /**
+ * updates values with current values of file.
+ */
protected PhotoPropertiesMediaDBContentValues getExifFromFile(ContentValues values, IFile jpgFile) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
@@ -362,7 +442,7 @@ protected PhotoPropertiesMediaDBContentValues getExifFromFile(ContentValues valu
PhotoPropertiesXmpSegment xmpContent = PhotoPropertiesXmpSegment.loadXmpSidecarContentOrNull(jpgFile, "getExifFromFile");
final long xmpFilelastModified = getXmpFilelastModified(xmpContent);
- values.put(FotoSql.SQL_COL_LAST_MODIFIED, jpgFile.lastModified() / 1000);
+ values.put(SQL_COL_LAST_MODIFIED, jpgFile.lastModified() / 1000);
values.put(DB_SIZE, jpgFile.length());
if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) && mWidth > 0 && mHeight > 0) {
@@ -371,7 +451,7 @@ protected PhotoPropertiesMediaDBContentValues getExifFromFile(ContentValues valu
}
values.put(DB_MIME_TYPE, imageType);
- TagSql.setXmpFileModifyDate(values, xmpFilelastModified);
+ setXmpFileModifyDate(values, xmpFilelastModified);
IPhotoProperties exif = loadNonMediaValues(values, jpgFile, xmpContent);
@@ -396,7 +476,7 @@ protected PhotoPropertiesMediaDBContentValues getExifFromFile(ContentValues valu
if (visibility == null) {
visibility = VISIBILITY.getVisibility(src);
}
- FotoSql.setVisibility(values, visibility);
+ setVisibility(values, visibility);
}
String absoluteJpgPath = jpgFile.getCanonicalPath();
@@ -409,79 +489,28 @@ protected PhotoPropertiesMediaDBContentValues getExifFromFile(ContentValues valu
return null;
}
- private void updateTagRepository(List tags) {
- TagRepository tagRepository = TagRepository.getInstance();
- tagRepository.includeTagNamesIfNotFound(tags);
- }
-
- /** in secs since 1970 */
- protected static long getXmpFilelastModified(PhotoPropertiesXmpSegment xmpContent) {
- long xmpFilelastModified = 0;
- if (xmpContent != null) {
- xmpFilelastModified = xmpContent.getFilelastModified();
- }
- if (xmpFilelastModified == 0) {
- xmpFilelastModified = TagSql.EXT_LAST_EXT_SCAN_NO_XMP;
- }
- return xmpFilelastModified;
- }
-
-
- protected IGeoPointInfo getPositionFromMeta(String absoluteJpgPath, String id, IPhotoProperties exif) {
- if (exif != null) {
- Double latitude = exif.getLatitude();
- if (latitude != null) {
- return new GeoPointDto(latitude, exif.getLongitude(), GeoPointDto.NO_ZOOM).setId(id);
- }
- PhotoPropertiesXmpSegment xmpContent = PhotoPropertiesXmpSegment.loadXmpSidecarContentOrNull(absoluteJpgPath, "getPositionFromFile");
- if (xmpContent != null) {
- latitude = xmpContent.getLatitude();
- if (latitude != null) {
- return new GeoPointDto(latitude, xmpContent.getLongitude(), GeoPointDto.NO_ZOOM).setId(id);
- }
- }
- }
-
- return null;
- }
-
- protected abstract IPhotoProperties loadNonMediaValues(ContentValues destinationValues, IFile jpgFile, IPhotoProperties xmpContent);
-
- /** @return number of copied properties */
- protected int getExifValues(PhotoPropertiesMediaDBContentValues dest, IPhotoProperties src) {
- return PhotoPropertiesUtil.copyNonEmpty(dest, src);
- }
-
- public abstract IGeoPointInfo getPositionFromFile(String absolutePath, String id);
public int updatePathRelatedFields(Context context, Cursor cursor, String newAbsolutePath) {
- int columnIndexPk = cursor.getColumnIndex(FotoSql.SQL_COL_PK);
- int columnIndexPath = cursor.getColumnIndex(FotoSql.SQL_COL_PATH);
- return updatePathRelatedFields(context, cursor, newAbsolutePath, columnIndexPk, columnIndexPath);
- }
-
- public int updatePathRelatedFields(Context context, Cursor cursor, String newAbsolutePath, int columnIndexPk, int columnIndexPath) {
- ContentValues values = new ContentValues();
- DatabaseUtils.cursorRowToContentValues(cursor, values);
- String oldAbsolutePath = cursor.getString(columnIndexPath);
- int id = cursor.getInt(columnIndexPk);
- setPathRelatedFieldsIfNeccessary(values, newAbsolutePath , oldAbsolutePath);
- return FotoSql.getMediaDBApi().execUpdate("updatePathRelatedFields", id, values);
+ int columnIndexPk = cursor.getColumnIndex(SQL_COL_PK);
+ int columnIndexPath = cursor.getColumnIndex(SQL_COL_PATH);
+ return updatePathRelatedFields(cursor, newAbsolutePath, columnIndexPk, columnIndexPath);
}
- /** sets the path related fields */
+ /**
+ * sets the path related fields
+ */
private static void setPathRelatedFieldsIfNeccessary(ContentValues values, String newAbsolutePath, String oldAbsolutePath) {
setFieldIfNeccessary(values, DB_TITLE, generateTitleFromFilePath(newAbsolutePath), generateTitleFromFilePath(oldAbsolutePath));
setFieldIfNeccessary(values, DB_DISPLAY_NAME, generateDisplayNameFromFilePath(newAbsolutePath), generateDisplayNameFromFilePath(oldAbsolutePath));
values.put(DB_DATA, newAbsolutePath);
}
- /** sets the path related fields */
- public static String setFileFields(ContentValues values, File file) {
- String newAbsolutePath = FileUtils.tryGetCanonicalPath(file, file.getAbsolutePath());
- setPathRelatedFieldsIfNeccessary(values, newAbsolutePath, null);
- values.put(FotoSql.SQL_COL_LAST_MODIFIED, file.lastModified() / 1000);
- values.put(DB_SIZE, file.length());
- return newAbsolutePath;
+ public int updatePathRelatedFields(Cursor cursor, String newAbsolutePath, int columnIndexPk, int columnIndexPath) {
+ ContentValues values = new ContentValues();
+ DatabaseUtils.cursorRowToContentValues(cursor, values);
+ String oldAbsolutePath = cursor.getString(columnIndexPath);
+ int id = cursor.getInt(columnIndexPk);
+ setPathRelatedFieldsIfNeccessary(values, newAbsolutePath, oldAbsolutePath);
+ return getMediaDBApi().execUpdate("updatePathRelatedFields", id, values);
}
@@ -497,9 +526,9 @@ private int updateAndroid42(String dbgContext, long id, IFile file) {
if ((file != null) && file.exists() && file.canRead()) {
ContentValues values = createDefaultContentValues();
getExifFromFile(values, file);
- return FotoSql.getMediaDBApi().execUpdate(dbgContext, id, values);
+ return getMediaDBApi().execUpdate(dbgContext, id, values);
}
- return 0;
+ return 0;
}
protected ContentValues createDefaultContentValues() {
@@ -507,21 +536,21 @@ protected ContentValues createDefaultContentValues() {
// to allow set null because copy does not setNull if already has null (not found)
contentValues.putNull(DB_TITLE);
- contentValues.putNull(FotoSql.SQL_COL_LON);
- contentValues.putNull(FotoSql.SQL_COL_LAT);
- contentValues.putNull(TagSql.SQL_COL_EXT_DESCRIPTION);
- contentValues.putNull(TagSql.SQL_COL_EXT_TAGS);
- contentValues.putNull(TagSql.SQL_COL_EXT_RATING);
+ contentValues.putNull(SQL_COL_LON);
+ contentValues.putNull(SQL_COL_LAT);
+ contentValues.putNull(SQL_COL_EXT_DESCRIPTION);
+ contentValues.putNull(SQL_COL_EXT_TAGS);
+ contentValues.putNull(SQL_COL_EXT_RATING);
return contentValues;
}
private int insertAndroid42(String dbgContext, IFile file) {
if ((file != null) && file.exists() && file.canRead()) {
ContentValues values = createDefaultContentValues();
- FotoSql.addDateAdded(values);
+ addDateAdded(values);
IPhotoProperties exif = getExifFromFile(values, file);
- return (null != FotoSql.getMediaDBApi().insertOrUpdateMediaDatabase(dbgContext, exif.getPath(), values, exif.getVisibility(), 1L)) ? 1 : 0;
+ return (null != getMediaDBApi().insertOrUpdateMediaDatabase(dbgContext, exif.getPath(), values, exif.getVisibility(), 1L)) ? 1 : 0;
}
return 0;
}
diff --git a/app/src/main/java/de/k3b/android/util/RecursivePhotoPropertiesMediaFilesScannerAsyncTask.java b/app/src/main/java/de/k3b/android/util/RecursivePhotoPropertiesMediaFilesScannerAsyncTask.java
index 37c7c6cb..e47b9a00 100644
--- a/app/src/main/java/de/k3b/android/util/RecursivePhotoPropertiesMediaFilesScannerAsyncTask.java
+++ b/app/src/main/java/de/k3b/android/util/RecursivePhotoPropertiesMediaFilesScannerAsyncTask.java
@@ -88,90 +88,96 @@ public RecursivePhotoPropertiesMediaFilesScannerAsyncTask(
protected Integer doInBackground(IFile[]... pathNames) {
// do not call super.doInBackground here because logic is different
int resultCount = 0;
+ FileDirectoryMediaCollector fileDirectoryMediaCollector = new FileDirectoryMediaCollector();
for (IFile[] pathArray : pathNames) {
if (pathArray != null) {
for (IFile pathName : pathArray) {
- resultCount += scanRoot(pathName);
+ resultCount += fileDirectoryMediaCollector.scanRootDir(pathName);
}
}
}
return resultCount;
}
- private int scanRoot(IFile rootPath) {
- int resultCount = 0;
- if ((rootPath != null) && (rootPath.length() > 0)) {
- if (this.rescanNeverScannedByAPM) {
- List pathsToUpdate = TagSql.getPhotosNeverScanned(rootPath.getAbsolutePath());
- for (String pathToUpdate : pathsToUpdate) {
- resultCount += scanDirOrFile(FileFacade.convert("scanRoot incremental paths never scanned ", pathToUpdate));
+ /**
+ * find media files by traversing File-(Sub-)Directories
+ */
+ private class FileDirectoryMediaCollector {
+ private int scanRootDir(IFile rootPath) {
+ int resultCount = 0;
+ if ((rootPath != null) && (rootPath.length() > 0)) {
+ if (rescanNeverScannedByAPM) {
+ List pathsToUpdate = TagSql.getPhotosNeverScanned(rootPath.getAbsolutePath());
+ for (String pathToUpdate : pathsToUpdate) {
+ resultCount += scanDirOrFile(FileFacade.convert("scanRoot incremental paths never scanned ", pathToUpdate));
+ }
}
- }
- resultCount += scanDirOrFile(rootPath);
+ resultCount += scanDirOrFile(rootPath);
+ }
+ return resultCount;
}
- return resultCount;
- }
- private int scanDirOrFile(IFile file) {
- int resultCount = 0;
- final String fullFilePath = file.getAbsolutePath();
- if (fullFilePath != null) {
- if (!isCancelled()) {
- if (file.isDirectory()) {
- resultCount += scanDir(file, fullFilePath);
- } else if (PhotoPropertiesUtil.isImage(file.getName(), PhotoPropertiesUtil.IMG_TYPE_ALL)) {
- resultCount += runScanner(fullFilePath, file);
+ private int scanDirOrFile(IFile file) {
+ int resultCount = 0;
+ final String fullFilePath = file.getAbsolutePath();
+ if (fullFilePath != null) {
+ if (!isCancelled()) {
+ if (file.isDirectory()) {
+ resultCount += scanDir(file, fullFilePath);
+ } else if (PhotoPropertiesUtil.isImage(file.getName(), PhotoPropertiesUtil.IMG_TYPE_ALL)) {
+ resultCount += runScanner(fullFilePath, file);
+ }
+ } else if (mPaused != null) {
+ mPaused.add(file);
}
- } else if (mPaused != null) {
- mPaused.add(file);
}
+ return resultCount;
}
- return resultCount;
- }
- private int scanDir(IFile file, String fullFilePath) {
- int resultCount = 0;
- if (this.scanForDeleted) {
- List deletedPaths = null;
- List existing = FotoSql.getPathsOfFolderWithoutSubfolders(file.getAbsolutePath());
- for (String candidatePath : existing) {
- IFile camdidateFile = FileFacade.convert(
- "RecursivePhotoPropertiesMediaFilesScannerAsyncTask.scanDir find deleted", candidatePath);
- // delete in db for existing but not found as file
- if (!camdidateFile.exists()) {
- if (deletedPaths == null) deletedPaths = new ArrayList<>();
- deletedPaths.add(candidatePath);
+ private int scanDir(IFile file, String fullFilePath) {
+ int resultCount = 0;
+ if (scanForDeleted) {
+ List deletedPaths = null;
+ List existing = FotoSql.getPathsOfFolderWithoutSubfolders(file.getAbsolutePath());
+ for (String candidatePath : existing) {
+ IFile camdidateFile = FileFacade.convert(
+ "RecursivePhotoPropertiesMediaFilesScannerAsyncTask.scanDir find deleted", candidatePath);
+ // delete in db for existing but not found as file
+ if (!camdidateFile.exists()) {
+ if (deletedPaths == null) deletedPaths = new ArrayList<>();
+ deletedPaths.add(candidatePath);
+ }
+ }
+ if (deletedPaths != null) {
+ FotoSql.deleteMedia("del photos that did not exist any more ",
+ deletedPaths, true);
+ resultCount += deletedPaths.size();
}
}
- if (deletedPaths != null) {
- FotoSql.deleteMedia("del photos that did not exist any more ",
- deletedPaths, true);
- resultCount += deletedPaths.size();
- }
- }
- if (this.fullScan) {
- IFile[] childFileNames = file.listFiles();
+ if (fullScan) {
+ IFile[] childFileNames = file.listFiles();
- if (childFileNames != null) {
- resultCount += runScanner(fullFilePath, childFileNames);
+ if (childFileNames != null) {
+ resultCount += runScanner(fullFilePath, childFileNames);
+ }
}
- }
- if (this.fullScan || this.scanForDeleted) {
- IFile[] subDirs = file.listFiles();
+ if (fullScan || scanForDeleted) {
+ IFile[] subDirs = file.listFiles();
- if (subDirs != null) {
- // #33
- for (IFile subDir : subDirs) {
- if ((subDir != null) && (subDir.isDirectory()) && (!subDir.getName().startsWith("."))) {
- resultCount += scanDirOrFile(subDir);
+ if (subDirs != null) {
+ // #33
+ for (IFile subDir : subDirs) {
+ if ((subDir != null) && (subDir.isDirectory()) && (!subDir.getName().startsWith("."))) {
+ resultCount += scanDirOrFile(subDir);
+ }
}
}
}
+ return resultCount;
}
- return resultCount;
}
/** @return true if scanner was resumable and started resume operation. */