Fix crashes when files where not listed in the media store
This commit is contained in:
parent
b1a086eaf2
commit
7d562070f5
3 changed files with 57 additions and 33 deletions
|
|
@ -54,7 +54,6 @@ import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileFilter;
|
import java.io.FileFilter;
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
@ -141,7 +140,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
|
||||||
public void onActivityCreated(Bundle savedInstanceState) {
|
public void onActivityCreated(Bundle savedInstanceState) {
|
||||||
super.onActivityCreated(savedInstanceState);
|
super.onActivityCreated(savedInstanceState);
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
setCrumb(new BreadCrumbLayout.Crumb(tryGetCanonicalFile((File) getArguments().getSerializable(PATH))), true);
|
setCrumb(new BreadCrumbLayout.Crumb(FileUtil.safeGetCanonicalFile((File) getArguments().getSerializable(PATH))), true);
|
||||||
} else {
|
} else {
|
||||||
breadCrumbs.restoreFromStateWrapper(savedInstanceState.getParcelable(CRUMBS));
|
breadCrumbs.restoreFromStateWrapper(savedInstanceState.getParcelable(CRUMBS));
|
||||||
getLoaderManager().initLoader(LOADER_ID, null, this);
|
getLoaderManager().initLoader(LOADER_ID, null, this);
|
||||||
|
|
@ -289,7 +288,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
|
||||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.action_go_to_start_directory:
|
case R.id.action_go_to_start_directory:
|
||||||
setCrumb(new BreadCrumbLayout.Crumb(tryGetCanonicalFile(PreferenceUtil.getInstance(getActivity()).getStartDirectory())), true);
|
setCrumb(new BreadCrumbLayout.Crumb(FileUtil.safeGetCanonicalFile(PreferenceUtil.getInstance(getActivity()).getStartDirectory())), true);
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_scan:
|
case R.id.action_scan:
|
||||||
BreadCrumbLayout.Crumb crumb = getActiveCrumb();
|
BreadCrumbLayout.Crumb crumb = getActiveCrumb();
|
||||||
|
|
@ -303,16 +302,15 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFileSelected(File file) {
|
public void onFileSelected(File file) {
|
||||||
file = tryGetCanonicalFile(file); // important as we compare the path value later
|
final File canonicalFile = FileUtil.safeGetCanonicalFile(file); // important as we compare the path value later
|
||||||
if (file.isDirectory()) {
|
if (canonicalFile.isDirectory()) {
|
||||||
setCrumb(new BreadCrumbLayout.Crumb(file), true);
|
setCrumb(new BreadCrumbLayout.Crumb(canonicalFile), true);
|
||||||
} else {
|
} else {
|
||||||
FileFilter fileFilter = pathname -> !pathname.isDirectory() && AUDIO_FILE_FILTER.accept(pathname);
|
FileFilter fileFilter = pathname -> !pathname.isDirectory() && AUDIO_FILE_FILTER.accept(pathname);
|
||||||
new ListSongsAsyncTask(getActivity(), file, (songs, extra) -> {
|
new ListSongsAsyncTask(getActivity(), null, (songs, extra) -> {
|
||||||
File file1 = (File) extra;
|
|
||||||
int startIndex = -1;
|
int startIndex = -1;
|
||||||
for (int i = 0; i < songs.size(); i++) {
|
for (int i = 0; i < songs.size(); i++) {
|
||||||
if (file1.getPath().equals(songs.get(i).data)) { // path is already canonical here
|
if (canonicalFile.getPath().equals(songs.get(i).data)) {
|
||||||
startIndex = i;
|
startIndex = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -320,20 +318,35 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
|
||||||
if (startIndex > -1) {
|
if (startIndex > -1) {
|
||||||
MusicPlayerRemote.openQueue(songs, startIndex, true);
|
MusicPlayerRemote.openQueue(songs, startIndex, true);
|
||||||
} else {
|
} else {
|
||||||
final File finalFile = file1;
|
Snackbar.make(coordinatorLayout, Html.fromHtml(String.format(getString(R.string.not_listed_in_media_store), canonicalFile.getName())), Snackbar.LENGTH_LONG)
|
||||||
Snackbar.make(coordinatorLayout, Html.fromHtml(String.format(getString(R.string.not_listed_in_media_store), file1.getName())), Snackbar.LENGTH_LONG)
|
.setAction(R.string.action_scan, v -> scanPaths(new String[]{canonicalFile.getPath()}))
|
||||||
.setAction(R.string.action_scan, v -> new ListPathsAsyncTask(getActivity(), paths -> scanPaths(paths)).execute(new ListPathsAsyncTask.LoadingInfo(finalFile, AUDIO_FILE_FILTER)))
|
|
||||||
.setActionTextColor(ThemeStore.accentColor(getActivity()))
|
.setActionTextColor(ThemeStore.accentColor(getActivity()))
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
}).execute(new ListSongsAsyncTask.LoadingInfo(toList(file.getParentFile()), fileFilter, getFileComparator()));
|
}).execute(new ListSongsAsyncTask.LoadingInfo(toList(canonicalFile.getParentFile()), fileFilter, getFileComparator()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMultipleItemAction(MenuItem item, ArrayList<File> files) {
|
public void onMultipleItemAction(MenuItem item, ArrayList<File> files) {
|
||||||
final int itemId = item.getItemId();
|
final int itemId = item.getItemId();
|
||||||
new ListSongsAsyncTask(getActivity(), null, (songs, extra) -> SongsMenuHelper.handleMenuClick(getActivity(), songs, itemId)).execute(new ListSongsAsyncTask.LoadingInfo(files, AUDIO_FILE_FILTER, getFileComparator()));
|
new ListSongsAsyncTask(getActivity(), null, (songs, extra) -> {
|
||||||
|
if (!songs.isEmpty()) {
|
||||||
|
SongsMenuHelper.handleMenuClick(getActivity(), songs, itemId);
|
||||||
|
}
|
||||||
|
if (songs.size() != files.size()) {
|
||||||
|
Snackbar.make(coordinatorLayout, R.string.some_files_are_not_listed_in_the_media_store, Snackbar.LENGTH_LONG)
|
||||||
|
.setAction(R.string.action_scan, v -> {
|
||||||
|
String[] paths = new String[files.size()];
|
||||||
|
for (int i = 0; i < files.size(); i++) {
|
||||||
|
paths[i] = FileUtil.safeGetCanonicalPath(files.get(i));
|
||||||
|
}
|
||||||
|
scanPaths(paths);
|
||||||
|
})
|
||||||
|
.setActionTextColor(ThemeStore.accentColor(getActivity()))
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
}).execute(new ListSongsAsyncTask.LoadingInfo(files, AUDIO_FILE_FILTER, getFileComparator()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<File> toList(File file) {
|
private ArrayList<File> toList(File file) {
|
||||||
|
|
@ -369,7 +382,11 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
|
||||||
case R.id.action_add_to_current_playing:
|
case R.id.action_add_to_current_playing:
|
||||||
case R.id.action_add_to_playlist:
|
case R.id.action_add_to_playlist:
|
||||||
case R.id.action_delete_from_device:
|
case R.id.action_delete_from_device:
|
||||||
new ListSongsAsyncTask(getActivity(), null, (songs, extra) -> SongsMenuHelper.handleMenuClick(getActivity(), songs, itemId)).execute(new ListSongsAsyncTask.LoadingInfo(toList(file), AUDIO_FILE_FILTER, getFileComparator()));
|
new ListSongsAsyncTask(getActivity(), null, (songs, extra) -> {
|
||||||
|
if (!songs.isEmpty()) {
|
||||||
|
SongsMenuHelper.handleMenuClick(getActivity(), songs, itemId);
|
||||||
|
}
|
||||||
|
}).execute(new ListSongsAsyncTask.LoadingInfo(toList(file), AUDIO_FILE_FILTER, getFileComparator()));
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_set_as_start_directory:
|
case R.id.action_set_as_start_directory:
|
||||||
PreferenceUtil.getInstance(getActivity()).setStartDirectory(file);
|
PreferenceUtil.getInstance(getActivity()).setStartDirectory(file);
|
||||||
|
|
@ -396,10 +413,19 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
|
||||||
case R.id.action_details:
|
case R.id.action_details:
|
||||||
case R.id.action_set_as_ringtone:
|
case R.id.action_set_as_ringtone:
|
||||||
case R.id.action_delete_from_device:
|
case R.id.action_delete_from_device:
|
||||||
new ListSongsAsyncTask(getActivity(), null, (songs, extra) -> SongMenuHelper.handleMenuClick(getActivity(), songs.get(0), itemId)).execute(new ListSongsAsyncTask.LoadingInfo(toList(file), AUDIO_FILE_FILTER, getFileComparator()));
|
new ListSongsAsyncTask(getActivity(), null, (songs, extra) -> {
|
||||||
|
if (!songs.isEmpty()) {
|
||||||
|
SongMenuHelper.handleMenuClick(getActivity(), songs.get(0), itemId);
|
||||||
|
} else {
|
||||||
|
Snackbar.make(coordinatorLayout, Html.fromHtml(String.format(getString(R.string.not_listed_in_media_store), file.getName())), Snackbar.LENGTH_LONG)
|
||||||
|
.setAction(R.string.action_scan, v -> scanPaths(new String[]{FileUtil.safeGetCanonicalPath(file)}))
|
||||||
|
.setActionTextColor(ThemeStore.accentColor(getActivity()))
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
}).execute(new ListSongsAsyncTask.LoadingInfo(toList(file), AUDIO_FILE_FILTER, getFileComparator()));
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_scan:
|
case R.id.action_scan:
|
||||||
new ListPathsAsyncTask(getActivity(), paths -> scanPaths(paths)).execute(new ListPathsAsyncTask.LoadingInfo(file, AUDIO_FILE_FILTER));
|
scanPaths(new String[]{FileUtil.safeGetCanonicalPath(file)});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -419,15 +445,6 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static File tryGetCanonicalFile(File file) {
|
|
||||||
try {
|
|
||||||
return file.getCanonicalFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void scanPaths(@Nullable String[] toBeScanned) {
|
private void scanPaths(@Nullable String[] toBeScanned) {
|
||||||
if (getActivity() == null) return;
|
if (getActivity() == null) return;
|
||||||
if (toBeScanned == null || toBeScanned.length < 1) {
|
if (toBeScanned == null || toBeScanned.length < 1) {
|
||||||
|
|
@ -494,7 +511,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
|
||||||
private final Object extra;
|
private final Object extra;
|
||||||
|
|
||||||
public ListSongsAsyncTask(Context context, Object extra, OnSongsListedCallback callback) {
|
public ListSongsAsyncTask(Context context, Object extra, OnSongsListedCallback callback) {
|
||||||
super(context);
|
super(context, 500);
|
||||||
this.extra = extra;
|
this.extra = extra;
|
||||||
contextWeakReference = new WeakReference<>(context);
|
contextWeakReference = new WeakReference<>(context);
|
||||||
callbackWeakReference = new WeakReference<>(callback);
|
callbackWeakReference = new WeakReference<>(callback);
|
||||||
|
|
@ -575,7 +592,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
|
||||||
private WeakReference<OnPathsListedCallback> onPathsListedCallbackWeakReference;
|
private WeakReference<OnPathsListedCallback> onPathsListedCallbackWeakReference;
|
||||||
|
|
||||||
public ListPathsAsyncTask(Context context, OnPathsListedCallback callback) {
|
public ListPathsAsyncTask(Context context, OnPathsListedCallback callback) {
|
||||||
super(context);
|
super(context, 500);
|
||||||
onPathsListedCallbackWeakReference = new WeakReference<>(callback);
|
onPathsListedCallbackWeakReference = new WeakReference<>(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -608,7 +625,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
paths = new String[1];
|
paths = new String[1];
|
||||||
paths[0] = info.file.getPath();
|
paths[0] = FileUtil.safeGetCanonicalPath(info.file);
|
||||||
}
|
}
|
||||||
|
|
||||||
return paths;
|
return paths;
|
||||||
|
|
|
||||||
|
|
@ -153,12 +153,9 @@ public final class FileUtil {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
String fileTypeMainType = fileType.substring(0, fileTypeDelimiter);
|
String fileTypeMainType = fileType.substring(0, fileTypeDelimiter);
|
||||||
if (fileTypeMainType.equals(mimeTypeMainType)) {
|
return fileTypeMainType.equals(mimeTypeMainType);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String stripExtension(String str) {
|
public static String stripExtension(String str) {
|
||||||
if (str == null) return null;
|
if (str == null) return null;
|
||||||
|
|
@ -194,4 +191,13 @@ public final class FileUtil {
|
||||||
return file.getAbsolutePath();
|
return file.getAbsolutePath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static File safeGetCanonicalFile(File file) {
|
||||||
|
try {
|
||||||
|
return file.getCanonicalFile();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return file.getAbsoluteFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -234,6 +234,7 @@
|
||||||
<string name="saved_playlist_to">Saved playlist to %s.</string>
|
<string name="saved_playlist_to">Saved playlist to %s.</string>
|
||||||
<string name="failed_to_save_playlist">Failed to save playlist (%s).</string>
|
<string name="failed_to_save_playlist">Failed to save playlist (%s).</string>
|
||||||
<string name="not_listed_in_media_store"><![CDATA[<b>%s</b> is not listed in the media store.]]></string>
|
<string name="not_listed_in_media_store"><![CDATA[<b>%s</b> is not listed in the media store.]]></string>
|
||||||
|
<string name="some_files_are_not_listed_in_the_media_store">Some files are not listed in the media store.</string>
|
||||||
<string name="nothing_to_scan">Nothing to scan.</string>
|
<string name="nothing_to_scan">Nothing to scan.</string>
|
||||||
<string name="scanned_files">Scanned %1$d of %2$d files.</string>
|
<string name="scanned_files">Scanned %1$d of %2$d files.</string>
|
||||||
<string name="could_not_scan_files">Could not scan %d files.</string>
|
<string name="could_not_scan_files">Could not scan %d files.</string>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue