From 738534e7b48a32e9b973897a366abc7842601181 Mon Sep 17 00:00:00 2001 From: tibbi Date: Sun, 27 Sep 2020 11:52:37 +0200 Subject: [PATCH] improve the performance of loading items at FilePickerDialog --- .../commons/dialogs/FilePickerDialog.kt | 14 ++++++-- .../commons/extensions/Context-storage.kt | 34 +++++++++++++++++-- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/commons/src/main/kotlin/com/simplemobiletools/commons/dialogs/FilePickerDialog.kt b/commons/src/main/kotlin/com/simplemobiletools/commons/dialogs/FilePickerDialog.kt index a9568b0c9..655c2dc4b 100644 --- a/commons/src/main/kotlin/com/simplemobiletools/commons/dialogs/FilePickerDialog.kt +++ b/commons/src/main/kotlin/com/simplemobiletools/commons/dialogs/FilePickerDialog.kt @@ -223,11 +223,12 @@ class FilePickerDialog(val activity: BaseSimpleActivity, if (activity.isPathOnOTG(path)) { activity.getOTGItems(path, showHidden, false, callback) } else { - getRegularItems(path, callback) + val lastModifieds = activity.getFolderLastModifieds(path) + getRegularItems(path, lastModifieds, callback) } } - private fun getRegularItems(path: String, callback: (List) -> Unit) { + private fun getRegularItems(path: String, lastModifieds: HashMap, callback: (List) -> Unit) { val items = ArrayList() val base = File(path) val files = base.listFiles() @@ -244,7 +245,14 @@ class FilePickerDialog(val activity: BaseSimpleActivity, val curPath = file.absolutePath val curName = curPath.getFilenameFromPath() val size = file.length() - items.add(FileDirItem(curPath, curName, file.isDirectory, file.getDirectChildrenCount(showHidden), size, file.lastModified())) + var lastModified = lastModifieds.remove(curPath) + val isDirectory = if (lastModified != null) false else file.isDirectory + if (lastModified == null) { + lastModified = file.lastModified() + } + + val children = if (isDirectory) file.getDirectChildrenCount(showHidden) else 0 + items.add(FileDirItem(curPath, curName, isDirectory, children, size, lastModified)) } callback(items) } diff --git a/commons/src/main/kotlin/com/simplemobiletools/commons/extensions/Context-storage.kt b/commons/src/main/kotlin/com/simplemobiletools/commons/extensions/Context-storage.kt index 00924aac6..8c400af15 100644 --- a/commons/src/main/kotlin/com/simplemobiletools/commons/extensions/Context-storage.kt +++ b/commons/src/main/kotlin/com/simplemobiletools/commons/extensions/Context-storage.kt @@ -31,7 +31,7 @@ fun Context.getSDCardPath(): String { val fullSDpattern = Pattern.compile(SD_OTG_PATTERN) var sdCardPath = directories.firstOrNull { fullSDpattern.matcher(it).matches() } - ?: directories.firstOrNull { !physicalPaths.contains(it.toLowerCase()) } ?: "" + ?: directories.firstOrNull { !physicalPaths.contains(it.toLowerCase()) } ?: "" // on some devices no method retrieved any SD card path, so test if its not sdcard1 by any chance. It happened on an Android 5.1 if (sdCardPath.trimEnd('/').isEmpty()) { @@ -80,7 +80,7 @@ fun Context.getStorageDirectories(): Array { if (TextUtils.isEmpty(rawEmulatedStorageTarget)) { if (isMarshmallowPlus()) { getExternalFilesDirs(null).filterNotNull().map { it.absolutePath } - .mapTo(paths) { it.substring(0, it.indexOf("Android/data")) } + .mapTo(paths) { it.substring(0, it.indexOf("Android/data")) } } else { if (TextUtils.isEmpty(rawExternalStorage)) { paths.addAll(physicalPaths) @@ -468,6 +468,36 @@ fun Context.getIsPathDirectory(path: String): Boolean { } } +fun Context.getFolderLastModifieds(folder: String): HashMap { + val lastModifieds = HashMap() + val projection = arrayOf( + Images.Media.DISPLAY_NAME, + Images.Media.DATE_MODIFIED + ) + + val uri = Files.getContentUri("external") + val selection = "${Images.Media.DATA} LIKE ? AND ${Images.Media.DATA} NOT LIKE ?" + val selectionArgs = arrayOf("$folder/%", "$folder/%/%") + + val cursor = contentResolver.query(uri, projection, selection, selectionArgs, null) + cursor?.use { + if (cursor.moveToFirst()) { + do { + try { + val lastModified = cursor.getLongValue(Images.Media.DATE_MODIFIED) * 1000 + if (lastModified != 0L) { + val name = cursor.getStringValue(Images.Media.DISPLAY_NAME) + lastModifieds["$folder/$name"] = lastModified + } + } catch (e: Exception) { + } + } while (cursor.moveToNext()) + } + } + + return lastModifieds +} + // avoid these being set as SD card paths private val physicalPaths = arrayListOf( "/storage/sdcard1", // Motorola Xoom