Scan files async.
This commit is contained in:
parent
a4943b2b68
commit
c3bc6ea707
1 changed files with 142 additions and 60 deletions
|
|
@ -2,6 +2,7 @@ package com.kabouzeid.gramophone.ui.fragments.mainactivity.folders;
|
||||||
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.Activity;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
|
@ -68,7 +69,6 @@ import java.util.List;
|
||||||
|
|
||||||
import butterknife.Bind;
|
import butterknife.Bind;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import hugo.weaving.DebugLog;
|
|
||||||
|
|
||||||
public class FoldersFragment extends AbsMainActivityFragment implements MainActivity.MainActivityFragmentCallbacks, CabHolder, BreadCrumbLayout.SelectionCallback, SongFileAdapter.Callbacks, AppBarLayout.OnOffsetChangedListener, LoaderManager.LoaderCallbacks<List<File>> {
|
public class FoldersFragment extends AbsMainActivityFragment implements MainActivity.MainActivityFragmentCallbacks, CabHolder, BreadCrumbLayout.SelectionCallback, SongFileAdapter.Callbacks, AppBarLayout.OnOffsetChangedListener, LoaderManager.LoaderCallbacks<List<File>> {
|
||||||
public static final String TAG = FoldersFragment.class.getSimpleName();
|
public static final String TAG = FoldersFragment.class.getSimpleName();
|
||||||
|
|
@ -352,54 +352,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scan(File file) {
|
private void scan(File file) {
|
||||||
final String[] toBeScanned;
|
new ScanFilesAsyncTask(this, file).execute(getFileFilter());
|
||||||
|
|
||||||
if (file.isDirectory()) {
|
|
||||||
// TODO load async
|
|
||||||
List<File> files = FileUtil.listFilesDeep(file, getFileFilter());
|
|
||||||
toBeScanned = new String[files.size()];
|
|
||||||
for (int i = 0; i < files.size(); i++) {
|
|
||||||
File f = files.get(i);
|
|
||||||
try {
|
|
||||||
toBeScanned[i] = f.getCanonicalPath(); // canonical path is important here because we want to compare the path with the media store entry later
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
toBeScanned[i] = f.getPath();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
toBeScanned = new String[1];
|
|
||||||
toBeScanned[0] = file.getPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (toBeScanned.length < 1) {
|
|
||||||
Toast.makeText(getActivity(), R.string.nothing_to_scan, Toast.LENGTH_SHORT).show();
|
|
||||||
} else {
|
|
||||||
final Toast toast = Toast.makeText(getActivity(), String.format(getString(R.string.scanning), file), Toast.LENGTH_SHORT);
|
|
||||||
toast.show();
|
|
||||||
|
|
||||||
MediaScannerConnection.scanFile(getActivity(), toBeScanned, null, new MediaScannerConnection.OnScanCompletedListener() {
|
|
||||||
int scanned = 0;
|
|
||||||
int failed = 0;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onScanCompleted(final String path, final Uri uri) {
|
|
||||||
getActivity().runOnUiThread(new Runnable() {
|
|
||||||
@SuppressLint("DefaultLocale")
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (uri == null) {
|
|
||||||
failed++;
|
|
||||||
} else {
|
|
||||||
scanned++;
|
|
||||||
}
|
|
||||||
toast.setText(" " + String.format(getString(R.string.scanned_files), scanned, toBeScanned.length) + (failed > 0 ? " " + String.format(getString(R.string.could_not_scan_files), failed) : ""));
|
|
||||||
toast.show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -578,10 +531,15 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
|
||||||
try {
|
try {
|
||||||
LoadingInfo info = params[0];
|
LoadingInfo info = params[0];
|
||||||
List<File> files = FileUtil.listFilesDeep(info.files, info.fileFilter);
|
List<File> files = FileUtil.listFilesDeep(info.files, info.fileFilter);
|
||||||
if (isCancelled() || checkFragmentReference()) return null;
|
|
||||||
|
if (isCancelled() || checkFragmentReference() == null) return null;
|
||||||
|
|
||||||
Collections.sort(files, info.fileComparator);
|
Collections.sort(files, info.fileComparator);
|
||||||
if (isCancelled() || checkFragmentReference()) return null;
|
|
||||||
return FileUtil.matchFilesWithMediaStore(fragmentWeakReference.get().getActivity(), files);
|
FoldersFragment fragment = checkFragmentReference();
|
||||||
|
if (isCancelled() || fragment == null) return null;
|
||||||
|
|
||||||
|
return FileUtil.matchFilesWithMediaStore(fragment.getActivity(), files);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
cancel(false);
|
cancel(false);
|
||||||
|
|
@ -592,8 +550,9 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(ArrayList<Song> songs) {
|
protected void onPostExecute(ArrayList<Song> songs) {
|
||||||
super.onPostExecute(songs);
|
super.onPostExecute(songs);
|
||||||
if (!songs.isEmpty() && !checkFragmentReference())
|
FoldersFragment fragment = checkFragmentReference();
|
||||||
fragmentWeakReference.get().onSongsListed(requestCode, songs, extra);
|
if (!songs.isEmpty() && fragment != null)
|
||||||
|
fragment.onSongsListed(requestCode, songs, extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class LoadingInfo {
|
public static class LoadingInfo {
|
||||||
|
|
@ -611,12 +570,137 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
|
||||||
/**
|
/**
|
||||||
* @return true if the task was canceled
|
* @return true if the task was canceled
|
||||||
*/
|
*/
|
||||||
private boolean checkFragmentReference() {
|
private FoldersFragment checkFragmentReference() {
|
||||||
if (fragmentWeakReference.get() == null) {
|
FoldersFragment fragment = fragmentWeakReference.get();
|
||||||
|
if (fragment == null) {
|
||||||
cancel(false);
|
cancel(false);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return fragment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onScanPaths(final String[] toBeScanned) {
|
||||||
|
if (getActivity() == null) return;
|
||||||
|
if (toBeScanned == null || toBeScanned.length < 1) {
|
||||||
|
Toast.makeText(getActivity(), R.string.nothing_to_scan, Toast.LENGTH_SHORT).show();
|
||||||
|
} else {
|
||||||
|
MediaScannerConnection.scanFile(getActivity().getApplicationContext(), toBeScanned, null, new UpdateToastCompletionListener(getActivity(), toBeScanned));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class UpdateToastCompletionListener implements MediaScannerConnection.OnScanCompletedListener {
|
||||||
|
int scanned = 0;
|
||||||
|
int failed = 0;
|
||||||
|
|
||||||
|
private final String[] toBeScanned;
|
||||||
|
|
||||||
|
private final String scannedFiles;
|
||||||
|
private final String couldNotScanFiles;
|
||||||
|
|
||||||
|
private final WeakReference<Toast> toastWeakReference;
|
||||||
|
private final WeakReference<Activity> activityWeakReference;
|
||||||
|
|
||||||
|
@SuppressLint("ShowToast")
|
||||||
|
public UpdateToastCompletionListener(Activity activity, String[] toBeScanned) {
|
||||||
|
this.toBeScanned = toBeScanned;
|
||||||
|
scannedFiles = activity.getString(R.string.scanned_files);
|
||||||
|
couldNotScanFiles = activity.getString(R.string.could_not_scan_files);
|
||||||
|
toastWeakReference = new WeakReference<>(Toast.makeText(activity, "", Toast.LENGTH_SHORT));
|
||||||
|
activityWeakReference = new WeakReference<>(activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onScanCompleted(final String path, final Uri uri) {
|
||||||
|
Activity activity = activityWeakReference.get();
|
||||||
|
if (activity != null) {
|
||||||
|
activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Toast toast = toastWeakReference.get();
|
||||||
|
if (toast != null) {
|
||||||
|
if (uri == null) {
|
||||||
|
failed++;
|
||||||
|
} else {
|
||||||
|
scanned++;
|
||||||
|
}
|
||||||
|
String text = " " + String.format(scannedFiles, scanned, toBeScanned.length) + (failed > 0 ? " " + String.format(couldNotScanFiles, failed) : "");
|
||||||
|
toast.setText(text);
|
||||||
|
toast.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ScanFilesAsyncTask extends DialogAsyncTask<FileFilter, String, String[]> {
|
||||||
|
private final File file;
|
||||||
|
private WeakReference<FoldersFragment> fragmentWeakReference;
|
||||||
|
|
||||||
|
public ScanFilesAsyncTask(FoldersFragment foldersFragment, File file) {
|
||||||
|
super(foldersFragment.getActivity(), R.string.listing_files);
|
||||||
|
this.file = file;
|
||||||
|
fragmentWeakReference = new WeakReference<>(foldersFragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPreExecute() {
|
||||||
|
super.onPreExecute();
|
||||||
|
checkFragmentReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] doInBackground(FileFilter... params) {
|
||||||
|
try {
|
||||||
|
if (isCancelled() || checkFragmentReference() == null) return null;
|
||||||
|
|
||||||
|
final String[] toBeScanned;
|
||||||
|
|
||||||
|
if (file.isDirectory()) {
|
||||||
|
List<File> files = FileUtil.listFilesDeep(file, params[0]);
|
||||||
|
|
||||||
|
if (isCancelled() || checkFragmentReference() == null) return null;
|
||||||
|
|
||||||
|
toBeScanned = new String[files.size()];
|
||||||
|
for (int i = 0; i < files.size(); i++) {
|
||||||
|
File f = files.get(i);
|
||||||
|
try {
|
||||||
|
toBeScanned[i] = f.getCanonicalPath(); // canonical path is important here because we want to compare the path with the media store entry later
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
toBeScanned[i] = f.getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCancelled() || checkFragmentReference() == null) return toBeScanned;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
toBeScanned = new String[1];
|
||||||
|
toBeScanned[0] = file.getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
return toBeScanned;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
cancel(false);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(String[] toBeScanned) {
|
||||||
|
super.onPostExecute(toBeScanned);
|
||||||
|
FoldersFragment fragment = checkFragmentReference();
|
||||||
|
if (fragment != null) {
|
||||||
|
fragment.onScanPaths(toBeScanned);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private FoldersFragment checkFragmentReference() {
|
||||||
|
FoldersFragment fragment = fragmentWeakReference.get();
|
||||||
|
if (fragment == null) {
|
||||||
|
cancel(false);
|
||||||
|
}
|
||||||
|
return fragment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -670,14 +754,12 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
|
||||||
}, 200);
|
}, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DebugLog
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCancelled(Result result) {
|
protected void onCancelled(Result result) {
|
||||||
super.onCancelled(result);
|
super.onCancelled(result);
|
||||||
tryToDismiss();
|
tryToDismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
@DebugLog
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(Result result) {
|
protected void onPostExecute(Result result) {
|
||||||
super.onPostExecute(result);
|
super.onPostExecute(result);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue