Made the TagEditor more reliable.

This commit is contained in:
Karim Abou Zeid 2016-03-27 23:51:51 +02:00
commit ffa329d978
7 changed files with 324 additions and 250 deletions

View file

@ -0,0 +1,104 @@
package com.kabouzeid.gramophone.misc;
import android.app.Dialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.lang.ref.WeakReference;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public abstract class DialogAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {
private final int delay;
private WeakReference<Context> contextWeakReference;
private WeakReference<Dialog> dialogWeakReference;
private boolean supposedToBeDismissed;
public DialogAsyncTask(Context context) {
this(context, 0);
}
public DialogAsyncTask(Context context, int showDelay) {
this.delay = showDelay;
contextWeakReference = new WeakReference<>(context);
dialogWeakReference = new WeakReference<>(null);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
if (delay > 0) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
initAndShowDialog();
}
}, delay);
} else {
initAndShowDialog();
}
}
private void initAndShowDialog() {
Context context = getContext();
if (!supposedToBeDismissed && context != null) {
Dialog dialog = createDialog(context);
dialogWeakReference = new WeakReference<>(dialog);
dialog.show();
}
}
@SuppressWarnings("unchecked")
@Override
protected void onProgressUpdate(Progress... values) {
super.onProgressUpdate(values);
Dialog dialog = getDialog();
if (dialog != null) {
onProgressUpdate(dialog, values);
}
}
@SuppressWarnings("unchecked")
protected void onProgressUpdate(@NonNull Dialog dialog, Progress... values) {
}
@Nullable
protected Context getContext() {
return contextWeakReference.get();
}
@Nullable
protected Dialog getDialog() {
return dialogWeakReference.get();
}
@Override
protected void onCancelled(Result result) {
super.onCancelled(result);
tryToDismiss();
}
@Override
protected void onPostExecute(Result result) {
super.onPostExecute(result);
tryToDismiss();
}
private void tryToDismiss() {
supposedToBeDismissed = true;
try {
Dialog dialog = getDialog();
if (dialog != null)
dialog.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
}
protected abstract Dialog createDialog(@NonNull Context context);
}

View file

@ -0,0 +1,59 @@
package com.kabouzeid.gramophone.misc;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.widget.Toast;
import com.kabouzeid.gramophone.R;
import java.lang.ref.WeakReference;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class UpdateToastMediaScannerCompletionListener 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 UpdateToastMediaScannerCompletionListener(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();
}
}
});
}
}
}

View file

@ -1,13 +1,14 @@
package com.kabouzeid.gramophone.ui.activities.tageditor;
import android.app.Activity;
import android.app.Dialog;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@ -26,7 +27,9 @@ import com.kabouzeid.appthemehelper.ThemeStore;
import com.kabouzeid.appthemehelper.util.ColorUtil;
import com.kabouzeid.appthemehelper.util.TintHelper;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.misc.DialogAsyncTask;
import com.kabouzeid.gramophone.misc.SimpleObservableScrollViewCallbacks;
import com.kabouzeid.gramophone.misc.UpdateToastMediaScannerCompletionListener;
import com.kabouzeid.gramophone.ui.activities.base.AbsBaseActivity;
import com.kabouzeid.gramophone.util.MusicUtil;
import com.kabouzeid.gramophone.util.Util;
@ -41,10 +44,12 @@ import org.jaudiotagger.tag.FieldKey;
import org.jaudiotagger.tag.Tag;
import org.jaudiotagger.tag.TagException;
import org.jaudiotagger.tag.images.Artwork;
import org.jaudiotagger.tag.images.ArtworkFactory;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -89,7 +94,6 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity {
}
};
private List<String> songPaths;
private MaterialDialog progressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -271,133 +275,145 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity {
setTaskDescriptionColor(paletteColorPrimary);
}
protected void writeValuesToFiles(@NonNull final Map<FieldKey, String> fieldKeyValueMap) {
writeValuesToFiles(fieldKeyValueMap, null, false);
protected void writeValuesToFiles(@NonNull final Map<FieldKey, String> fieldKeyValueMap, @Nullable final ArtworkInfo artworkInfo) {
Util.hideSoftKeyboard(this);
new WriteTagsAsyncTask(this).execute(new WriteTagsAsyncTask.LoadingInfo(getSongPaths(), fieldKeyValueMap, artworkInfo));
}
protected void writeValuesToFiles(@NonNull final Map<FieldKey, String> fieldKeyValueMap, @Nullable final Artwork artwork, final boolean deleteArtwork) {
Util.hideSoftKeyboard(this);
final String writingFileStr = getResources().getString(R.string.writing_file_number);
progressDialog = new MaterialDialog.Builder(AbsTagEditorActivity.this)
.title(R.string.saving_changes)
.cancelable(false)
.progress(true, 0)
.build();
if (Build.VERSION.SDK_INT >= 18)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
progressDialog.show();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < songPaths.size(); i++) {
String songPath = songPaths.get(i);
final int finalI = i;
runOnUiThread(new Runnable() {
@Override
public void run() {
progressDialog.setContent(writingFileStr + " " + ((finalI + 1) + "/" + songPaths.size()));
}
});
private static class WriteTagsAsyncTask extends DialogAsyncTask<WriteTagsAsyncTask.LoadingInfo, Integer, String[]> {
Context applicationContext;
public WriteTagsAsyncTask(Context context) {
super(context);
applicationContext = context;
}
@Override
protected String[] doInBackground(LoadingInfo... params) {
try {
LoadingInfo info = params[0];
Artwork artwork = null;
File albumArtFile = null;
if (info.artworkInfo != null && info.artworkInfo.artwork != null) {
try {
AudioFile audioFile = AudioFileIO.read(new File(songPath));
albumArtFile = MusicUtil.createAlbumArtFile(String.valueOf(info.artworkInfo.albumId)).getCanonicalFile();
info.artworkInfo.artwork.compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(albumArtFile));
artwork = ArtworkFactory.createArtworkFromFile(albumArtFile);
} catch (IOException e) {
e.printStackTrace();
}
}
int counter = 0;
boolean wroteArtwork = false;
boolean deletedArtwork = false;
for (String filePath : info.filePaths) {
publishProgress(++counter, info.filePaths.size());
try {
AudioFile audioFile = AudioFileIO.read(new File(filePath));
Tag tag = audioFile.getTagOrCreateAndSetDefault();
for (Map.Entry<FieldKey, String> entry : fieldKeyValueMap.entrySet()) {
try {
tag.setField(entry.getKey(), entry.getValue());
} catch (NumberFormatException e) {
tag.deleteField(entry.getKey());
if (info.fieldKeyValueMap != null) {
for (Map.Entry<FieldKey, String> entry : info.fieldKeyValueMap.entrySet()) {
try {
tag.setField(entry.getKey(), entry.getValue());
} catch (Exception e) {
e.printStackTrace();
}
}
}
if (deleteArtwork) {
tag.deleteArtworkField();
} else if (artwork != null) {
tag.deleteArtworkField();
tag.setField(artwork);
if (info.artworkInfo != null) {
if (info.artworkInfo.artwork == null) {
tag.deleteArtworkField();
deletedArtwork = true;
} else if (artwork != null) {
tag.deleteArtworkField();
tag.setField(artwork);
wroteArtwork = true;
}
}
audioFile.commit();
} catch (@NonNull CannotReadException | IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
Log.e(TAG, "Error while reading audio file.", e);
} catch (CannotWriteException e) {
Log.e(TAG, "Error while writing audio file.", e);
} catch (@NonNull CannotReadException | IOException | CannotWriteException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
e.printStackTrace();
}
}
runOnUiThread(new Runnable() {
@Override
public void run() {
progressDialog.setContent(getString(R.string.rescanning_media));
Context context = getContext();
if (context != null) {
if (wroteArtwork) {
MusicUtil.insertAlbumArt(context, info.artworkInfo.albumId, albumArtFile.getPath());
} else if (deletedArtwork) {
MusicUtil.deleteAlbumArt(context, info.artworkInfo.albumId);
}
});
if (deleteArtwork) {
MusicUtil.deleteAlbumArt(AbsTagEditorActivity.this, getId());
} else if (artwork != null) {
// AlbumTagEditorActivity already inserts the album cover for us
}
rescanMediaAndQuitOnFinish();
return info.filePaths.toArray(new String[info.filePaths.size()]);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}).start();
}
private static class FinishOnCompletedMediaScanner implements MediaScannerConnection.MediaScannerConnectionClient {
private WeakReference<AbsTagEditorActivity> activityWeakReference;
private MediaScannerConnection connection;
private String[] toBeScanned;
private int position;
private FinishOnCompletedMediaScanner(AbsTagEditorActivity activity, String[] toBeScanned) {
activityWeakReference = new WeakReference<>(activity);
this.toBeScanned = toBeScanned;
connection = new MediaScannerConnection(activity.getApplicationContext(), this);
}
public void scan() {
connection.connect();
}
@Override
public void onMediaScannerConnected() {
scanNextPath();
protected void onPostExecute(String[] toBeScanned) {
super.onPostExecute(toBeScanned);
scan(toBeScanned);
}
@Override
public void onScanCompleted(String path, Uri uri) {
scanNextPath();
protected void onCancelled(String[] toBeScanned) {
super.onCancelled(toBeScanned);
scan(toBeScanned);
}
private void scanNextPath() {
if (position < toBeScanned.length) {
connection.scanFile(toBeScanned[position], null);
}
checkIsDone();
position++;
private void scan(String[] toBeScanned) {
Context context = getContext();
MediaScannerConnection.scanFile(applicationContext, toBeScanned, null, context instanceof Activity ? new UpdateToastMediaScannerCompletionListener((Activity) context, toBeScanned) : null);
}
private void checkIsDone() {
if (position >= toBeScanned.length - 1) {
connection.disconnect();
AbsTagEditorActivity activity = activityWeakReference.get();
if (activity != null) {
activity.dismissDialogAndFinish();
}
@Override
protected Dialog createDialog(@NonNull Context context) {
return new MaterialDialog.Builder(context)
.title(R.string.writing_files)
.cancelable(false)
.progress(false, 0)
.build();
}
@Override
protected void onProgressUpdate(@NonNull Dialog dialog, Integer... values) {
super.onProgressUpdate(dialog, values);
((MaterialDialog) dialog).setMaxProgress(values[1]);
((MaterialDialog) dialog).setProgress(values[0]);
}
public static class LoadingInfo {
public final Collection<String> filePaths;
@Nullable
public final Map<FieldKey, String> fieldKeyValueMap;
@Nullable
private ArtworkInfo artworkInfo;
private LoadingInfo(Collection<String> filePaths, @Nullable Map<FieldKey, String> fieldKeyValueMap, @Nullable ArtworkInfo artworkInfo) {
this.filePaths = filePaths;
this.fieldKeyValueMap = fieldKeyValueMap;
this.artworkInfo = artworkInfo;
}
}
}
public void dismissDialogAndFinish() {
runOnUiThread(new Runnable() {
@Override
public void run() {
progressDialog.dismiss();
finish();
}
});
}
public static class ArtworkInfo {
public final int albumId;
public final Bitmap artwork;
private void rescanMediaAndQuitOnFinish() {
String[] toBeScanned = new String[songPaths.size()];
toBeScanned = songPaths.toArray(toBeScanned);
new FinishOnCompletedMediaScanner(this, toBeScanned).scan();
public ArtworkInfo(int albumId, Bitmap artwork) {
this.albumId = albumId;
this.artwork = artwork;
}
}
protected int getId() {

View file

@ -10,7 +10,6 @@ import android.support.annotation.NonNull;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.EditText;
import android.widget.Toast;
@ -28,16 +27,10 @@ import com.kabouzeid.gramophone.lastfm.rest.model.LastFmAlbum;
import com.kabouzeid.gramophone.loader.AlbumLoader;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.util.LastFMUtil;
import com.kabouzeid.gramophone.util.MusicUtil;
import com.kabouzeid.gramophone.util.PhonographColorUtil;
import org.jaudiotagger.tag.FieldKey;
import org.jaudiotagger.tag.images.Artwork;
import org.jaudiotagger.tag.images.ArtworkFactory;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
@ -45,6 +38,7 @@ import java.util.Map;
import butterknife.Bind;
import butterknife.ButterKnife;
import hugo.weaving.DebugLog;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
@ -169,7 +163,6 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text
@Override
protected void save() {
Artwork artwork = null;
Map<FieldKey, String> fieldKeyValueMap = new EnumMap<>(FieldKey.class);
fieldKeyValueMap.put(FieldKey.ALBUM, albumTitle.getText().toString());
//android seems not to recognize album_artist field so we additionally write the normal artist field
@ -178,18 +171,7 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text
fieldKeyValueMap.put(FieldKey.GENRE, genre.getText().toString());
fieldKeyValueMap.put(FieldKey.YEAR, year.getText().toString());
File albumArtFile = MusicUtil.createAlbumArtFile(String.valueOf(getId()));
if (albumArtBitmap != null) {
try {
albumArtBitmap.compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(albumArtFile));
artwork = ArtworkFactory.createArtworkFromFile(albumArtFile);
MusicUtil.insertAlbumArt(this, getId(), albumArtFile.getAbsolutePath());
} catch (IOException e) {
Log.e(TAG, "error while trying to create the artwork from file", e);
}
}
writeValuesToFiles(fieldKeyValueMap, artwork, deleteAlbumArt);
writeValuesToFiles(fieldKeyValueMap, deleteAlbumArt ? new ArtworkInfo(getId(), null) : albumArtBitmap == null ? null : new ArtworkInfo(getId(), albumArtBitmap));
}
@Override
@ -216,7 +198,7 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text
.transcode(new BitmapPaletteTranscoder(AlbumTagEditorActivity.this), BitmapPaletteWrapper.class)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(new SimpleTarget<BitmapPaletteWrapper>(4097, 4097) {
.into(new SimpleTarget<BitmapPaletteWrapper>() {
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
super.onLoadFailed(e, errorDrawable);
@ -251,6 +233,7 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text
dataChanged();
}
@DebugLog
private static Bitmap getResizedAlbumCover(@NonNull Bitmap src, int maxForSmallerSize) {
int width = src.getWidth();
int height = src.getHeight();
@ -274,11 +257,7 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text
dstHeight = maxForSmallerSize;
}
Bitmap scaledBitmap = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, false);
if (scaledBitmap != src) {
src.recycle();
}
return scaledBitmap;
return Bitmap.createScaledBitmap(src, dstWidth, dstHeight, false);
}
@Override

View file

@ -98,7 +98,7 @@ public class SongTagEditorActivity extends AbsTagEditorActivity implements TextW
fieldKeyValueMap.put(FieldKey.GENRE, genre.getText().toString());
fieldKeyValueMap.put(FieldKey.YEAR, year.getText().toString());
fieldKeyValueMap.put(FieldKey.TRACK, trackNumber.getText().toString());
writeValuesToFiles(fieldKeyValueMap);
writeValuesToFiles(fieldKeyValueMap, null);
}
@Override

View file

@ -1,20 +1,14 @@
package com.kabouzeid.gramophone.ui.fragments.mainactivity.folders;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
@ -46,6 +40,8 @@ import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.helper.menu.SongMenuHelper;
import com.kabouzeid.gramophone.helper.menu.SongsMenuHelper;
import com.kabouzeid.gramophone.interfaces.CabHolder;
import com.kabouzeid.gramophone.misc.DialogAsyncTask;
import com.kabouzeid.gramophone.misc.UpdateToastMediaScannerCompletionListener;
import com.kabouzeid.gramophone.misc.WrappedAsyncTaskLoader;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.ui.activities.MainActivity;
@ -485,52 +481,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
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();
}
}
});
}
MediaScannerConnection.scanFile(getActivity().getApplicationContext(), toBeScanned, null, new UpdateToastMediaScannerCompletionListener(getActivity(), toBeScanned));
}
}
@ -585,13 +536,13 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
}
}
private static class ListSongsAsyncTask extends DialogAsyncTask<ListSongsAsyncTask.LoadingInfo, Void, ArrayList<Song>> {
private static class ListSongsAsyncTask extends ListingFilesDialogAsyncTask<ListSongsAsyncTask.LoadingInfo, Void, ArrayList<Song>> {
private WeakReference<Context> contextWeakReference;
private WeakReference<OnSongsListedCallback> callbackWeakReference;
private final Object extra;
public ListSongsAsyncTask(Context context, Object extra, OnSongsListedCallback callback) {
super(context, R.string.listing_files);
super(context);
this.extra = extra;
contextWeakReference = new WeakReference<>(context);
callbackWeakReference = new WeakReference<>(callback);
@ -668,11 +619,11 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
}
}
private static class ListPathsAsyncTask extends DialogAsyncTask<ListPathsAsyncTask.LoadingInfo, String, String[]> {
private static class ListPathsAsyncTask extends ListingFilesDialogAsyncTask<ListPathsAsyncTask.LoadingInfo, String, String[]> {
private WeakReference<OnPathsListedCallback> onPathsListedCallbackWeakReference;
public ListPathsAsyncTask(Context context, OnPathsListedCallback callback) {
super(context, R.string.listing_files);
super(context);
onPathsListedCallbackWeakReference = new WeakReference<>(callback);
}
@ -753,76 +704,41 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
}
}
private static abstract class DialogAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {
private final int title;
private WeakReference<Context> contextWeakReference;
private WeakReference<Dialog> dialogWeakReference;
private static abstract class ListingFilesDialogAsyncTask<Params, Progress, Result> extends DialogAsyncTask<Params, Progress, Result> {
public ListingFilesDialogAsyncTask(Context context) {
super(context);
}
private boolean supposedToBeDismissed;
public DialogAsyncTask(Context context, @StringRes int title) {
contextWeakReference = new WeakReference<>(context);
dialogWeakReference = new WeakReference<>(null);
this.title = title;
public ListingFilesDialogAsyncTask(Context context, int showDelay) {
super(context, showDelay);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (!supposedToBeDismissed && contextWeakReference.get() != null) {
Dialog dialog = new MaterialDialog.Builder(contextWeakReference.get())
.title(title)
.progress(true, 0)
.progressIndeterminateStyle(true)
.cancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
cancel(false);
}
})
.dismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
cancel(false);
}
})
.negativeText(android.R.string.cancel)
.onNegative(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
cancel(false);
}
})
.show();
dialogWeakReference = new WeakReference<>(dialog);
}
}
}, 200);
}
@Override
protected void onCancelled(Result result) {
super.onCancelled(result);
tryToDismiss();
}
@Override
protected void onPostExecute(Result result) {
super.onPostExecute(result);
tryToDismiss();
}
private void tryToDismiss() {
supposedToBeDismissed = true;
try {
if (dialogWeakReference.get() != null)
dialogWeakReference.get().dismiss();
} catch (Exception e) {
e.printStackTrace();
}
protected Dialog createDialog(@NonNull Context context) {
return new MaterialDialog.Builder(context)
.title(R.string.listing_files)
.progress(true, 0)
.progressIndeterminateStyle(true)
.cancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
cancel(false);
}
})
.dismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
cancel(false);
}
})
.negativeText(android.R.string.cancel)
.onNegative(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
cancel(false);
}
})
.show();
}
}
}

View file

@ -46,7 +46,7 @@
<string name="track">Track</string>
<string name="track_hint">"Track (2 for track 2 or 3004 for CD3 track 4)"</string>
<string name="album_or_artist_empty">The title or artist is empty.</string>
<string name="writing_file_number">Writing file</string>
<string name="writing_files">Writing files</string>
<string name="saving_changes">Saving changes…</string>
<string name="saving_to_file">Saving to file…</string>
<string name="label_details">Details</string>