From 9081d1a579fb9cf3ef5473a5a7b175aa45294d7c Mon Sep 17 00:00:00 2001 From: tibbi Date: Tue, 25 Oct 2016 22:28:25 +0200 Subject: [PATCH] load the directories asynchronously --- .../gallery/activities/MainActivity.java | 179 ++++-------------- .../gallery/activities/MediaActivity.java | 2 +- .../gallery/dialogs/ChangeSorting.java | 4 +- .../asynctasks/GetDirectoriesAsynctask.kt | 143 ++++++++++++++ 4 files changed, 182 insertions(+), 146 deletions(-) create mode 100644 app/src/main/kotlin/com/simplemobiletools/gallery/asynctasks/GetDirectoriesAsynctask.kt diff --git a/app/src/main/java/com/simplemobiletools/gallery/activities/MainActivity.java b/app/src/main/java/com/simplemobiletools/gallery/activities/MainActivity.java index 0c7a8e634..a3b3c2fe4 100644 --- a/app/src/main/java/com/simplemobiletools/gallery/activities/MainActivity.java +++ b/app/src/main/java/com/simplemobiletools/gallery/activities/MainActivity.java @@ -4,7 +4,6 @@ import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Resources; -import android.database.Cursor; import android.graphics.Color; import android.media.MediaScannerConnection; import android.net.Uri; @@ -16,6 +15,7 @@ import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.AlertDialog; +import android.util.Log; import android.util.SparseBooleanArray; import android.view.ActionMode; import android.view.Menu; @@ -33,17 +33,16 @@ import com.simplemobiletools.gallery.Constants; import com.simplemobiletools.gallery.R; import com.simplemobiletools.gallery.Utils; import com.simplemobiletools.gallery.adapters.DirectoryAdapter; +import com.simplemobiletools.gallery.asynctasks.GetDirectoriesAsynctask; import com.simplemobiletools.gallery.dialogs.ChangeSorting; import com.simplemobiletools.gallery.models.Directory; +import org.jetbrains.annotations.NotNull; + import java.io.File; -import java.io.FilenameFilter; import java.util.ArrayList; -import java.util.Collections; import java.util.HashSet; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import java.util.Set; import butterknife.BindView; @@ -51,7 +50,7 @@ import butterknife.ButterKnife; public class MainActivity extends SimpleActivity implements AdapterView.OnItemClickListener, GridView.MultiChoiceModeListener, GridView.OnTouchListener, - SwipeRefreshLayout.OnRefreshListener, ChangeSorting.ChangeDialogListener { + SwipeRefreshLayout.OnRefreshListener, ChangeSorting.ChangeDialogListener, GetDirectoriesAsynctask.GetDirectoriesListener { @BindView(R.id.directories_grid) GridView mGridView; @BindView(R.id.directories_holder) SwipeRefreshLayout mSwipeRefreshLayout; @@ -73,6 +72,7 @@ public class MainActivity extends SimpleActivity private static boolean mIsGetAnyContentIntent; private static boolean mIsSetWallpaperIntent; private static boolean mIsThirdPartyIntent; + private static boolean mIsGettingDirs; private static int mSelectedItemsCnt; @Override @@ -149,7 +149,7 @@ public class MainActivity extends SimpleActivity private void tryloadGallery() { if (Utils.hasStoragePermission(getApplicationContext())) { - initializeGallery(); + getDirectories(); } else { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION); } @@ -161,7 +161,7 @@ public class MainActivity extends SimpleActivity if (requestCode == STORAGE_PERMISSION) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - initializeGallery(); + getDirectories(); } else { Utils.showToast(getApplicationContext(), R.string.no_permissions); finish(); @@ -169,131 +169,13 @@ public class MainActivity extends SimpleActivity } } - private void initializeGallery() { - final List newDirs = getDirectories(); - if (newDirs.toString().equals(mDirs.toString())) { + private void getDirectories() { + if (mIsGettingDirs) return; - } - mDirs = newDirs; - final DirectoryAdapter adapter = new DirectoryAdapter(this, mDirs); - mGridView.setAdapter(adapter); - mGridView.setOnItemClickListener(this); - mGridView.setMultiChoiceModeListener(this); - mGridView.setOnTouchListener(this); - } - - private List getDirectories() { - final Map directories = new LinkedHashMap<>(); - final List invalidFiles = new ArrayList<>(); - for (int i = 0; i < 2; i++) { - if ((mIsPickVideoIntent || mIsGetVideoContentIntent) && i == 0) - continue; - - Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; - if (i == 1) { - if (mIsPickImageIntent || mIsGetImageContentIntent) - continue; - - uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; - } - final String[] columns = {MediaStore.Images.Media.DATA, MediaStore.Images.Media.DATE_TAKEN}; - final String order = getSortOrder(); - final Cursor cursor = getContentResolver().query(uri, columns, null, null, order); - - if (cursor != null && cursor.moveToFirst()) { - final int pathIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA); - do { - final String fullPath = cursor.getString(pathIndex); - final File file = new File(fullPath); - final String parentDir = file.getParent(); - - if (!file.exists()) { - invalidFiles.add(file.getAbsolutePath()); - continue; - } - - final int dateIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATE_TAKEN); - final long timestamp = cursor.getLong(dateIndex); - if (directories.containsKey(parentDir)) { - final Directory directory = directories.get(parentDir); - final int newImageCnt = directory.getMediaCnt() + 1; - directory.setMediaCnt(newImageCnt); - directory.addSize(file.length()); - } else if (!mToBeDeleted.contains(parentDir)) { - String dirName = Utils.getFilename(parentDir); - if (mConfig.getIsFolderHidden(parentDir)) { - dirName += " " + getResources().getString(R.string.hidden); - } - - directories.put(parentDir, new Directory(parentDir, fullPath, dirName, 1, timestamp, file.length())); - } - } while (cursor.moveToNext()); - cursor.close(); - } - } - - final List dirs = new ArrayList<>(directories.values()); - filterDirectories(dirs); - Directory.mSorting = mConfig.getDirectorySorting(); - Collections.sort(dirs); - - final String[] invalids = invalidFiles.toArray(new String[invalidFiles.size()]); - MediaScannerConnection.scanFile(getApplicationContext(), invalids, null, null); - - return dirs; - } - - private void filterDirectories(List dirs) { - if (!mConfig.getShowHiddenFolders()) - removeHiddenFolders(dirs); - - removeNoMediaFolders(dirs); - } - - private void removeHiddenFolders(List dirs) { - final Set hiddenDirs = mConfig.getHiddenFolders(); - final List ignoreDirs = new ArrayList<>(); - for (Directory d : dirs) { - if (hiddenDirs.contains(d.getPath())) - ignoreDirs.add(d); - } - - dirs.removeAll(ignoreDirs); - } - - private void removeNoMediaFolders(List dirs) { - final List ignoreDirs = new ArrayList<>(); - for (final Directory d : dirs) { - final File dir = new File(d.getPath()); - if (dir.exists() && dir.isDirectory()) { - final String[] res = dir.list(new FilenameFilter() { - @Override - public boolean accept(File file, String filename) { - return filename.equals(".nomedia"); - } - }); - - if (res.length > 0) - ignoreDirs.add(d); - } - } - - dirs.removeAll(ignoreDirs); - } - - // sort the files at querying too, just to get the correct thumbnail - private String getSortOrder() { - final int sorting = mConfig.getDirectorySorting(); - String sortBy = MediaStore.Images.Media.DATE_TAKEN; - if ((sorting & Constants.SORT_BY_NAME) != 0) { - sortBy = MediaStore.Images.Media.DATA; - } - - if ((sorting & Constants.SORT_DESCENDING) != 0) { - sortBy += " DESC"; - } - return sortBy; + mIsGettingDirs = true; + new GetDirectoriesAsynctask(getApplicationContext(), mIsPickVideoIntent || mIsGetVideoContentIntent, mIsPickImageIntent || mIsGetImageContentIntent, + mToBeDeleted, this).execute(); } private void showSortingDialog() { @@ -318,7 +200,7 @@ public class MainActivity extends SimpleActivity } private void notifyDeletion(int cnt) { - mDirs = getDirectories(); + getDirectories(); final CoordinatorLayout coordinator = (CoordinatorLayout) findViewById(R.id.coordinator_layout); final Resources res = getResources(); @@ -328,7 +210,6 @@ public class MainActivity extends SimpleActivity mSnackbar.setActionTextColor(Color.WHITE); mSnackbar.show(); mIsSnackbarShown = true; - updateGridView(); } private void deleteDirs() { @@ -366,8 +247,7 @@ public class MainActivity extends SimpleActivity mSnackbar.dismiss(); mIsSnackbarShown = false; mToBeDeleted.clear(); - mDirs = getDirectories(); - updateGridView(); + getDirectories(); } }; @@ -631,12 +511,12 @@ public class MainActivity extends SimpleActivity private void hideFolders() { mConfig.addHiddenDirectories(getSelectedPaths()); - initializeGallery(); + getDirectories(); } private void unhideFolders() { mConfig.removeHiddenDirectories(getSelectedPaths()); - initializeGallery(); + getDirectories(); } private Set getSelectedPaths() { @@ -655,13 +535,11 @@ public class MainActivity extends SimpleActivity private void scanCompleted(final String path) { final File dir = new File(path); if (dir.isDirectory()) { - mDirs = getDirectories(); + getDirectories(); runOnUiThread(new Runnable() { @Override public void run() { - updateGridView(); - mGridView.requestLayout(); Utils.showToast(getApplicationContext(), R.string.rename_folder_ok); } }); @@ -670,12 +548,27 @@ public class MainActivity extends SimpleActivity @Override public void onRefresh() { - initializeGallery(); + getDirectories(); mSwipeRefreshLayout.setRefreshing(false); } @Override - public void dialogClosed() { - initializeGallery(); + public void sortingDialogClosed() { + getDirectories(); + } + + @Override + public void gotDirectories(@NotNull ArrayList dirs) { + mIsGettingDirs = false; + if (dirs.toString().equals(mDirs.toString())) { + return; + } + mDirs = dirs; + + final DirectoryAdapter adapter = new DirectoryAdapter(this, mDirs); + mGridView.setAdapter(adapter); + mGridView.setOnItemClickListener(this); + mGridView.setMultiChoiceModeListener(this); + mGridView.setOnTouchListener(this); } } diff --git a/app/src/main/java/com/simplemobiletools/gallery/activities/MediaActivity.java b/app/src/main/java/com/simplemobiletools/gallery/activities/MediaActivity.java index 1e44f19af..f8925caf8 100644 --- a/app/src/main/java/com/simplemobiletools/gallery/activities/MediaActivity.java +++ b/app/src/main/java/com/simplemobiletools/gallery/activities/MediaActivity.java @@ -476,7 +476,7 @@ public class MediaActivity extends SimpleActivity } @Override - public void dialogClosed() { + public void sortingDialogClosed() { initializeGallery(); } } diff --git a/app/src/main/java/com/simplemobiletools/gallery/dialogs/ChangeSorting.java b/app/src/main/java/com/simplemobiletools/gallery/dialogs/ChangeSorting.java index 6312a1077..4fce26755 100644 --- a/app/src/main/java/com/simplemobiletools/gallery/dialogs/ChangeSorting.java +++ b/app/src/main/java/com/simplemobiletools/gallery/dialogs/ChangeSorting.java @@ -90,10 +90,10 @@ public class ChangeSorting extends AlertDialog.Builder implements DialogInterfac mConfig.setSorting(sorting); } } - mListener.dialogClosed(); + mListener.sortingDialogClosed(); } public interface ChangeDialogListener { - void dialogClosed(); + void sortingDialogClosed(); } } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/asynctasks/GetDirectoriesAsynctask.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/asynctasks/GetDirectoriesAsynctask.kt new file mode 100644 index 000000000..aeaf3e447 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/asynctasks/GetDirectoriesAsynctask.kt @@ -0,0 +1,143 @@ +package com.simplemobiletools.gallery.asynctasks + +import android.content.Context +import android.media.MediaScannerConnection +import android.os.AsyncTask +import android.provider.MediaStore +import com.simplemobiletools.gallery.Config +import com.simplemobiletools.gallery.Constants +import com.simplemobiletools.gallery.R +import com.simplemobiletools.gallery.Utils +import com.simplemobiletools.gallery.models.Directory +import java.io.File +import java.lang.ref.WeakReference +import java.util.* + +class GetDirectoriesAsynctask(val context: Context, val isPickVideo: Boolean, val isPickImage: Boolean, + val mToBeDeleted: List, val listener: GetDirectoriesListener) : AsyncTask>() { + lateinit var mConfig: Config + lateinit var mListener: WeakReference + + override fun onPreExecute() { + super.onPreExecute() + mConfig = Config.newInstance(context) + mListener = WeakReference(listener) + } + + override fun doInBackground(vararg params: Void): ArrayList { + val directories = LinkedHashMap() + val invalidFiles = ArrayList() + for (i in 0..1) { + if ((isPickVideo) && i == 0) + continue + + var uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI + if (i == 1) { + if (isPickImage) + continue + + uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI + } + val columns = arrayOf(MediaStore.Images.Media.DATA, MediaStore.Images.Media.DATE_TAKEN) + val order = getSortOrder() + val cursor = context.contentResolver.query(uri, columns, null, null, order) + + if (cursor != null && cursor.moveToFirst()) { + val pathIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA) + do { + val fullPath = cursor.getString(pathIndex) + val file = File(fullPath) + val parentDir = file.parent + + if (!file.exists()) { + invalidFiles.add(file.absolutePath) + continue + } + + val dateIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATE_TAKEN) + val timestamp = cursor.getLong(dateIndex) + if (directories.containsKey(parentDir)) { + val directory: Directory = directories[parentDir]!! + val newImageCnt = directory.mediaCnt + 1 + directory.mediaCnt = newImageCnt + directory.addSize(file.length()) + } else if (!mToBeDeleted.contains(parentDir)) { + var dirName = Utils.getFilename(parentDir) + if (mConfig.getIsFolderHidden(parentDir)) { + dirName += " ${context.resources.getString(R.string.hidden)}" + } + + directories.put(parentDir, Directory(parentDir, fullPath, dirName, 1, timestamp, file.length())) + } + } while (cursor.moveToNext()) + cursor.close() + } + } + + val dirs = ArrayList(directories.values) + filterDirectories(dirs) + Directory.mSorting = mConfig.directorySorting + //Collections.sort(dirs) + + val invalids = invalidFiles.toTypedArray() + MediaScannerConnection.scanFile(context, invalids, null, null) + return dirs + } + + override fun onPostExecute(dirs: ArrayList) { + super.onPostExecute(dirs) + val listener = mListener.get() + listener?.gotDirectories(dirs) + } + + interface GetDirectoriesListener { + fun gotDirectories(dirs: ArrayList) + } + + // sort the files at querying too, just to get the correct thumbnail + private fun getSortOrder(): String { + val sorting = mConfig.directorySorting + var sortBy = MediaStore.Images.Media.DATE_TAKEN + if (sorting and Constants.SORT_BY_NAME != 0) { + sortBy = MediaStore.Images.Media.DATA + } + + if (sorting and Constants.SORT_DESCENDING != 0) { + sortBy += " DESC" + } + return sortBy + } + + private fun filterDirectories(dirs: MutableList) { + if (!mConfig.showHiddenFolders) + removeHiddenFolders(dirs) + + removeNoMediaFolders(dirs) + } + + private fun removeHiddenFolders(dirs: MutableList) { + val hiddenDirs = mConfig.hiddenFolders + val ignoreDirs = ArrayList() + for (dir in dirs) { + if (hiddenDirs.contains(dir.path)) + ignoreDirs.add(dir) + } + + dirs.removeAll(ignoreDirs) + } + + private fun removeNoMediaFolders(dirs: MutableList) { + val ignoreDirs = ArrayList() + for (d in dirs) { + val dir = File(d.path) + if (dir.exists() && dir.isDirectory) { + val res = dir.list { file, filename -> filename == ".nomedia" } + + if (res.size > 0) + ignoreDirs.add(d) + } + } + + dirs.removeAll(ignoreDirs) + } +}