remove tag editors and lastfm client
This commit is contained in:
parent
75429d3376
commit
734e6a08fa
55 changed files with 0 additions and 1927 deletions
|
|
@ -1,7 +1,6 @@
|
|||
package com.kabouzeid.gramophone.ui.activities;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
|
|
@ -39,8 +38,6 @@ import com.kabouzeid.gramophone.misc.WrappedAsyncTaskLoader;
|
|||
import com.kabouzeid.gramophone.model.Album;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsSlidingMusicPanelActivity;
|
||||
import com.kabouzeid.gramophone.ui.activities.tageditor.AbsTagEditorActivity;
|
||||
import com.kabouzeid.gramophone.ui.activities.tageditor.AlbumTagEditorActivity;
|
||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||
import com.kabouzeid.gramophone.util.PhonographColorUtil;
|
||||
|
|
@ -52,7 +49,6 @@ import butterknife.ButterKnife;
|
|||
|
||||
public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements PaletteColorHolder, CabHolder, LoaderManager.LoaderCallbacks<Album> {
|
||||
|
||||
private static final int TAG_EDITOR_REQUEST = 2001;
|
||||
private static final int LOADER_ID = LoaderIds.ALBUM_DETAIL_ACTIVITY;
|
||||
|
||||
public static final String EXTRA_ALBUM_ID = "extra_album_id";
|
||||
|
|
@ -252,11 +248,6 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
|
|||
case android.R.id.home:
|
||||
super.onBackPressed();
|
||||
return true;
|
||||
case R.id.action_tag_editor:
|
||||
Intent intent = new Intent(this, AlbumTagEditorActivity.class);
|
||||
intent.putExtra(AbsTagEditorActivity.EXTRA_ID, getAlbum().getId());
|
||||
startActivityForResult(intent, TAG_EDITOR_REQUEST);
|
||||
return true;
|
||||
case R.id.action_go_to_artist:
|
||||
NavigationUtil.goToArtist(this, getAlbum().getArtistId());
|
||||
return true;
|
||||
|
|
@ -264,15 +255,6 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
|
|||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (requestCode == TAG_EDITOR_REQUEST) {
|
||||
reload();
|
||||
setResult(RESULT_OK);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MaterialCab openCab(int menuRes, @NonNull final MaterialCab.Callback callback) {
|
||||
|
|
|
|||
|
|
@ -1,520 +0,0 @@
|
|||
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.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollView;
|
||||
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;
|
||||
|
||||
import org.jaudiotagger.audio.AudioFile;
|
||||
import org.jaudiotagger.audio.AudioFileIO;
|
||||
import org.jaudiotagger.audio.exceptions.CannotReadException;
|
||||
import org.jaudiotagger.audio.exceptions.CannotWriteException;
|
||||
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
|
||||
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
|
||||
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.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
/**
|
||||
* @author Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
public abstract class AbsTagEditorActivity extends AbsBaseActivity {
|
||||
|
||||
public static final String EXTRA_ID = "extra_id";
|
||||
public static final String EXTRA_PALETTE = "extra_palette";
|
||||
private static final String TAG = AbsTagEditorActivity.class.getSimpleName();
|
||||
private static final int REQUEST_CODE_SELECT_IMAGE = 1000;
|
||||
@BindView(R.id.play_pause_fab)
|
||||
FloatingActionButton fab;
|
||||
@BindView(R.id.observableScrollView)
|
||||
ObservableScrollView observableScrollView;
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.image)
|
||||
ImageView image;
|
||||
@BindView(R.id.header)
|
||||
LinearLayout header;
|
||||
private int id;
|
||||
private int headerVariableSpace;
|
||||
private int paletteColorPrimary;
|
||||
private boolean isInNoImageMode;
|
||||
private final SimpleObservableScrollViewCallbacks observableScrollViewCallbacks = new SimpleObservableScrollViewCallbacks() {
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean b, boolean b2) {
|
||||
float alpha;
|
||||
if (!isInNoImageMode) {
|
||||
alpha = 1 - (float) Math.max(0, headerVariableSpace - scrollY) / headerVariableSpace;
|
||||
} else {
|
||||
header.setTranslationY(scrollY);
|
||||
alpha = 1;
|
||||
}
|
||||
toolbar.setBackgroundColor(ColorUtil.withAlpha(paletteColorPrimary, alpha));
|
||||
image.setTranslationY(scrollY / 2);
|
||||
}
|
||||
};
|
||||
private List<String> songPaths;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(getContentViewLayout());
|
||||
ButterKnife.bind(this);
|
||||
|
||||
getIntentExtras();
|
||||
|
||||
songPaths = getSongPaths();
|
||||
if (songPaths.isEmpty()) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
headerVariableSpace = getResources().getDimensionPixelSize(R.dimen.tagEditorHeaderVariableSpace);
|
||||
|
||||
setUpViews();
|
||||
|
||||
setSupportActionBar(toolbar);
|
||||
//noinspection ConstantConditions
|
||||
getSupportActionBar().setTitle(null);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
private void setUpViews() {
|
||||
setUpScrollView();
|
||||
setUpFab();
|
||||
setUpImageView();
|
||||
}
|
||||
|
||||
private void setUpScrollView() {
|
||||
observableScrollView.setScrollViewCallbacks(observableScrollViewCallbacks);
|
||||
}
|
||||
|
||||
private void setUpImageView() {
|
||||
loadCurrentImage();
|
||||
final CharSequence[] items = new CharSequence[]{
|
||||
getString(R.string.download_from_last_fm),
|
||||
getString(R.string.pick_from_local_storage),
|
||||
getString(R.string.web_search),
|
||||
getString(R.string.remove_cover)
|
||||
};
|
||||
image.setOnClickListener(v -> new MaterialDialog.Builder(AbsTagEditorActivity.this)
|
||||
.title(R.string.update_image)
|
||||
.items(items)
|
||||
.itemsCallback((dialog, view, which, text) -> {
|
||||
switch (which) {
|
||||
case 0:
|
||||
getImageFromLastFM();
|
||||
break;
|
||||
case 1:
|
||||
startImagePicker();
|
||||
break;
|
||||
case 2:
|
||||
searchImageOnWeb();
|
||||
break;
|
||||
case 3:
|
||||
deleteImage();
|
||||
break;
|
||||
}
|
||||
}).show());
|
||||
}
|
||||
|
||||
private void startImagePicker() {
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.setType("image/*");
|
||||
startActivityForResult(Intent.createChooser(intent, getString(R.string.pick_from_local_storage)), REQUEST_CODE_SELECT_IMAGE);
|
||||
}
|
||||
|
||||
protected abstract void loadCurrentImage();
|
||||
|
||||
protected abstract void getImageFromLastFM();
|
||||
|
||||
protected abstract void searchImageOnWeb();
|
||||
|
||||
protected abstract void deleteImage();
|
||||
|
||||
private void setUpFab() {
|
||||
fab.setScaleX(0);
|
||||
fab.setScaleY(0);
|
||||
fab.setEnabled(false);
|
||||
fab.setOnClickListener(v -> save());
|
||||
|
||||
TintHelper.setTintAuto(fab, ThemeStore.accentColor(this), true);
|
||||
}
|
||||
|
||||
protected abstract void save();
|
||||
|
||||
private void getIntentExtras() {
|
||||
Bundle intentExtras = getIntent().getExtras();
|
||||
if (intentExtras != null) {
|
||||
id = intentExtras.getInt(EXTRA_ID);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract int getContentViewLayout();
|
||||
|
||||
@NonNull
|
||||
protected abstract List<String> getSongPaths();
|
||||
|
||||
protected void searchWebFor(String... keys) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (String key : keys) {
|
||||
stringBuilder.append(key);
|
||||
stringBuilder.append(" ");
|
||||
}
|
||||
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
|
||||
intent.putExtra(SearchManager.QUERY, stringBuilder.toString());
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case android.R.id.home:
|
||||
super.onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
protected void setNoImageMode() {
|
||||
isInNoImageMode = true;
|
||||
image.setVisibility(View.GONE);
|
||||
image.setEnabled(false);
|
||||
observableScrollView.setPadding(0, Util.getActionBarSize(this), 0, 0);
|
||||
observableScrollViewCallbacks.onScrollChanged(observableScrollView.getCurrentScrollY(), false, false);
|
||||
|
||||
setColors(getIntent().getIntExtra(EXTRA_PALETTE, ThemeStore.primaryColor(this)));
|
||||
toolbar.setBackgroundColor(paletteColorPrimary);
|
||||
}
|
||||
|
||||
protected void dataChanged() {
|
||||
showFab();
|
||||
}
|
||||
|
||||
private void showFab() {
|
||||
fab.animate()
|
||||
.setDuration(500)
|
||||
.setInterpolator(new OvershootInterpolator())
|
||||
.scaleX(1)
|
||||
.scaleY(1)
|
||||
.start();
|
||||
fab.setEnabled(true);
|
||||
}
|
||||
|
||||
protected void setImageBitmap(@Nullable final Bitmap bitmap, int bgColor) {
|
||||
if (bitmap == null) {
|
||||
image.setImageResource(R.drawable.default_album_art);
|
||||
} else {
|
||||
image.setImageBitmap(bitmap);
|
||||
}
|
||||
setColors(bgColor);
|
||||
}
|
||||
|
||||
protected void setColors(int color) {
|
||||
paletteColorPrimary = color;
|
||||
observableScrollViewCallbacks.onScrollChanged(observableScrollView.getCurrentScrollY(), false, false);
|
||||
header.setBackgroundColor(paletteColorPrimary);
|
||||
setStatusbarColor(paletteColorPrimary);
|
||||
setNavigationbarColor(paletteColorPrimary);
|
||||
setTaskDescriptionColor(paletteColorPrimary);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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 {
|
||||
albumArtFile = MusicUtil.createAlbumArtFile().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();
|
||||
|
||||
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 (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 | CannotWriteException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return info.filePaths.toArray(new String[info.filePaths.size()]);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String[] toBeScanned) {
|
||||
super.onPostExecute(toBeScanned);
|
||||
scan(toBeScanned);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancelled(String[] toBeScanned) {
|
||||
super.onCancelled(toBeScanned);
|
||||
scan(toBeScanned);
|
||||
}
|
||||
|
||||
private void scan(String[] toBeScanned) {
|
||||
Context context = getContext();
|
||||
MediaScannerConnection.scanFile(applicationContext, toBeScanned, null, context instanceof Activity ? new UpdateToastMediaScannerCompletionListener((Activity) context, toBeScanned) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog createDialog(@NonNull Context context) {
|
||||
return new MaterialDialog.Builder(context)
|
||||
.title(R.string.saving_changes)
|
||||
.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 static class ArtworkInfo {
|
||||
public final int albumId;
|
||||
public final Bitmap artwork;
|
||||
|
||||
public ArtworkInfo(int albumId, Bitmap artwork) {
|
||||
this.albumId = albumId;
|
||||
this.artwork = artwork;
|
||||
}
|
||||
}
|
||||
|
||||
protected int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, @NonNull Intent imageReturnedIntent) {
|
||||
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
|
||||
switch (requestCode) {
|
||||
case REQUEST_CODE_SELECT_IMAGE:
|
||||
if (resultCode == RESULT_OK) {
|
||||
Uri selectedImage = imageReturnedIntent.getData();
|
||||
loadImageFromFile(selectedImage);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void loadImageFromFile(Uri selectedFile);
|
||||
|
||||
@NonNull
|
||||
private AudioFile getAudioFile(@NonNull String path) {
|
||||
try {
|
||||
return AudioFileIO.read(new File(path));
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Could not read audio file " + path, e);
|
||||
return new AudioFile();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getSongTitle() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.TITLE);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getAlbumTitle() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.ALBUM);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getArtistName() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.ARTIST);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getAlbumArtistName() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.ALBUM_ARTIST);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getGenreName() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.GENRE);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getSongYear() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.YEAR);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getTrackNumber() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.TRACK);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getLyrics() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.LYRICS);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Bitmap getAlbumArt() {
|
||||
try {
|
||||
Artwork artworkTag = getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirstArtwork();
|
||||
if (artworkTag != null) {
|
||||
byte[] artworkBinaryData = artworkTag.getBinaryData();
|
||||
return BitmapFactory.decodeByteArray(artworkBinaryData, 0, artworkBinaryData.length);
|
||||
}
|
||||
return null;
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,239 +0,0 @@
|
|||
package com.kabouzeid.gramophone.ui.activities.tageditor;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.request.animation.GlideAnimation;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.kabouzeid.appthemehelper.util.ATHUtil;
|
||||
import com.kabouzeid.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.glide.palette.BitmapPaletteTranscoder;
|
||||
import com.kabouzeid.gramophone.glide.palette.BitmapPaletteWrapper;
|
||||
import com.kabouzeid.gramophone.lastfm.rest.LastFMRestClient;
|
||||
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.ImageUtil;
|
||||
import com.kabouzeid.gramophone.util.LastFMUtil;
|
||||
import com.kabouzeid.gramophone.util.PhonographColorUtil;
|
||||
|
||||
import org.jaudiotagger.tag.FieldKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class AlbumTagEditorActivity extends AbsTagEditorActivity implements TextWatcher {
|
||||
|
||||
@BindView(R.id.title)
|
||||
EditText albumTitle;
|
||||
@BindView(R.id.album_artist)
|
||||
EditText albumArtist;
|
||||
@BindView(R.id.genre)
|
||||
EditText genre;
|
||||
@BindView(R.id.year)
|
||||
EditText year;
|
||||
|
||||
private Bitmap albumArtBitmap;
|
||||
private boolean deleteAlbumArt;
|
||||
private LastFMRestClient lastFMRestClient;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
lastFMRestClient = new LastFMRestClient(this);
|
||||
|
||||
setUpViews();
|
||||
}
|
||||
|
||||
private void setUpViews() {
|
||||
fillViewsWithFileTags();
|
||||
albumTitle.addTextChangedListener(this);
|
||||
albumArtist.addTextChangedListener(this);
|
||||
genre.addTextChangedListener(this);
|
||||
year.addTextChangedListener(this);
|
||||
}
|
||||
|
||||
|
||||
private void fillViewsWithFileTags() {
|
||||
albumTitle.setText(getAlbumTitle());
|
||||
albumArtist.setText(getAlbumArtistName());
|
||||
genre.setText(getGenreName());
|
||||
year.setText(getSongYear());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadCurrentImage() {
|
||||
Bitmap bitmap = getAlbumArt();
|
||||
setImageBitmap(bitmap, PhonographColorUtil.getColor(PhonographColorUtil.generatePalette(bitmap), ATHUtil.resolveColor(this, R.attr.defaultFooterColor)));
|
||||
deleteAlbumArt = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getImageFromLastFM() {
|
||||
String albumTitleStr = albumTitle.getText().toString();
|
||||
String albumArtistNameStr = albumArtist.getText().toString();
|
||||
if (albumArtistNameStr.trim().equals("") || albumTitleStr.trim().equals("")) {
|
||||
Toast.makeText(this, getResources().getString(R.string.album_or_artist_empty), Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
lastFMRestClient.getApiService().getAlbumInfo(albumTitleStr, albumArtistNameStr, null).enqueue(new Callback<LastFmAlbum>() {
|
||||
@Override
|
||||
public void onResponse(Call<LastFmAlbum> call, Response<LastFmAlbum> response) {
|
||||
LastFmAlbum lastFmAlbum = response.body();
|
||||
if (lastFmAlbum.getAlbum() != null) {
|
||||
String url = LastFMUtil.getLargestAlbumImageUrl(lastFmAlbum.getAlbum().getImage());
|
||||
if (!TextUtils.isEmpty(url) && url.trim().length() > 0) {
|
||||
Glide.with(AlbumTagEditorActivity.this)
|
||||
.load(url)
|
||||
.asBitmap()
|
||||
.transcode(new BitmapPaletteTranscoder(AlbumTagEditorActivity.this), BitmapPaletteWrapper.class)
|
||||
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
|
||||
.error(R.drawable.default_album_art)
|
||||
.into(new SimpleTarget<BitmapPaletteWrapper>() {
|
||||
@Override
|
||||
public void onLoadFailed(Exception e, Drawable errorDrawable) {
|
||||
super.onLoadFailed(e, errorDrawable);
|
||||
e.printStackTrace();
|
||||
Toast.makeText(AlbumTagEditorActivity.this, e.toString(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceReady(BitmapPaletteWrapper resource, GlideAnimation<? super BitmapPaletteWrapper> glideAnimation) {
|
||||
albumArtBitmap = ImageUtil.resizeBitmap(resource.getBitmap(), 2048);
|
||||
setImageBitmap(albumArtBitmap, PhonographColorUtil.getColor(resource.getPalette(), ATHUtil.resolveColor(AlbumTagEditorActivity.this, R.attr.defaultFooterColor)));
|
||||
deleteAlbumArt = false;
|
||||
dataChanged();
|
||||
setResult(RESULT_OK);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
toastLoadingFailed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<LastFmAlbum> call, Throwable t) {
|
||||
toastLoadingFailed();
|
||||
}
|
||||
|
||||
private void toastLoadingFailed() {
|
||||
Toast.makeText(AlbumTagEditorActivity.this,
|
||||
R.string.could_not_download_album_cover, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void searchImageOnWeb() {
|
||||
searchWebFor(albumTitle.getText().toString(), albumArtist.getText().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deleteImage() {
|
||||
setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.default_album_art), ATHUtil.resolveColor(this, R.attr.defaultFooterColor));
|
||||
deleteAlbumArt = true;
|
||||
dataChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void save() {
|
||||
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
|
||||
fieldKeyValueMap.put(FieldKey.ARTIST, albumArtist.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.ALBUM_ARTIST, albumArtist.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.GENRE, genre.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.YEAR, year.getText().toString());
|
||||
|
||||
writeValuesToFiles(fieldKeyValueMap, deleteAlbumArt ? new ArtworkInfo(getId(), null) : albumArtBitmap == null ? null : new ArtworkInfo(getId(), albumArtBitmap));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getContentViewLayout() {
|
||||
return R.layout.activity_album_tag_editor;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected List<String> getSongPaths() {
|
||||
List<Song> songs = AlbumLoader.getAlbum(this, getId()).songs;
|
||||
List<String> paths = new ArrayList<>(songs.size());
|
||||
for (Song song : songs) {
|
||||
paths.add(song.data);
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadImageFromFile(@NonNull final Uri selectedFileUri) {
|
||||
Glide.with(AlbumTagEditorActivity.this)
|
||||
.load(selectedFileUri)
|
||||
.asBitmap()
|
||||
.transcode(new BitmapPaletteTranscoder(AlbumTagEditorActivity.this), BitmapPaletteWrapper.class)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.skipMemoryCache(true)
|
||||
.into(new SimpleTarget<BitmapPaletteWrapper>() {
|
||||
@Override
|
||||
public void onLoadFailed(Exception e, Drawable errorDrawable) {
|
||||
super.onLoadFailed(e, errorDrawable);
|
||||
e.printStackTrace();
|
||||
Toast.makeText(AlbumTagEditorActivity.this, e.toString(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceReady(BitmapPaletteWrapper resource, GlideAnimation<? super BitmapPaletteWrapper> glideAnimation) {
|
||||
PhonographColorUtil.getColor(resource.getPalette(), Color.TRANSPARENT);
|
||||
albumArtBitmap = ImageUtil.resizeBitmap(resource.getBitmap(), 2048);
|
||||
setImageBitmap(albumArtBitmap, PhonographColorUtil.getColor(resource.getPalette(), ATHUtil.resolveColor(AlbumTagEditorActivity.this, R.attr.defaultFooterColor)));
|
||||
deleteAlbumArt = false;
|
||||
dataChanged();
|
||||
setResult(RESULT_OK);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
dataChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setColors(int color) {
|
||||
super.setColors(color);
|
||||
albumTitle.setTextColor(ToolbarContentTintHelper.toolbarTitleColor(this, color));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
package com.kabouzeid.gramophone.ui.activities.tageditor;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.widget.EditText;
|
||||
|
||||
import com.kabouzeid.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.loader.SongLoader;
|
||||
|
||||
import org.jaudiotagger.tag.FieldKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class SongTagEditorActivity extends AbsTagEditorActivity implements TextWatcher {
|
||||
|
||||
@BindView(R.id.title1)
|
||||
EditText songTitle;
|
||||
@BindView(R.id.title2)
|
||||
EditText albumTitle;
|
||||
@BindView(R.id.artist)
|
||||
EditText artist;
|
||||
@BindView(R.id.genre)
|
||||
EditText genre;
|
||||
@BindView(R.id.year)
|
||||
EditText year;
|
||||
@BindView(R.id.image_text)
|
||||
EditText trackNumber;
|
||||
@BindView(R.id.lyrics)
|
||||
EditText lyrics;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
setNoImageMode();
|
||||
setUpViews();
|
||||
|
||||
//noinspection ConstantConditions
|
||||
getSupportActionBar().setTitle(R.string.action_tag_editor);
|
||||
}
|
||||
|
||||
private void setUpViews() {
|
||||
fillViewsWithFileTags();
|
||||
songTitle.addTextChangedListener(this);
|
||||
albumTitle.addTextChangedListener(this);
|
||||
artist.addTextChangedListener(this);
|
||||
genre.addTextChangedListener(this);
|
||||
year.addTextChangedListener(this);
|
||||
trackNumber.addTextChangedListener(this);
|
||||
lyrics.addTextChangedListener(this);
|
||||
}
|
||||
|
||||
private void fillViewsWithFileTags() {
|
||||
songTitle.setText(getSongTitle());
|
||||
albumTitle.setText(getAlbumTitle());
|
||||
artist.setText(getArtistName());
|
||||
genre.setText(getGenreName());
|
||||
year.setText(getSongYear());
|
||||
trackNumber.setText(getTrackNumber());
|
||||
lyrics.setText(getLyrics());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadCurrentImage() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getImageFromLastFM() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void searchImageOnWeb() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deleteImage() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void save() {
|
||||
Map<FieldKey, String> fieldKeyValueMap = new EnumMap<>(FieldKey.class);
|
||||
fieldKeyValueMap.put(FieldKey.TITLE, songTitle.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.ALBUM, albumTitle.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.ARTIST, artist.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.GENRE, genre.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.YEAR, year.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.TRACK, trackNumber.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.LYRICS, lyrics.getText().toString());
|
||||
writeValuesToFiles(fieldKeyValueMap, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getContentViewLayout() {
|
||||
return R.layout.activity_song_tag_editor;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected List<String> getSongPaths() {
|
||||
List<String> paths = new ArrayList<>(1);
|
||||
paths.add(SongLoader.getSong(this, getId()).data);
|
||||
return paths;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadImageFromFile(Uri imageFilePath) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
dataChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setColors(int color) {
|
||||
super.setColors(color);
|
||||
int toolbarTitleColor = ToolbarContentTintHelper.toolbarTitleColor(this, color);
|
||||
songTitle.setTextColor(toolbarTitleColor);
|
||||
albumTitle.setTextColor(toolbarTitleColor);
|
||||
}
|
||||
}
|
||||
|
|
@ -408,7 +408,6 @@ public class FoldersFragment extends AbsMainActivityFragment implements MainActi
|
|||
case R.id.action_go_to_album:
|
||||
case R.id.action_go_to_artist:
|
||||
case R.id.action_share:
|
||||
case R.id.action_tag_editor:
|
||||
case R.id.action_details:
|
||||
case R.id.action_set_as_ringtone:
|
||||
case R.id.action_delete_from_device:
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@ import com.kabouzeid.gramophone.dialogs.SongShareDialog;
|
|||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||
import com.kabouzeid.gramophone.interfaces.PaletteColorHolder;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.ui.activities.tageditor.AbsTagEditorActivity;
|
||||
import com.kabouzeid.gramophone.ui.activities.tageditor.SongTagEditorActivity;
|
||||
import com.kabouzeid.gramophone.ui.fragments.AbsMusicServiceFragment;
|
||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||
|
|
@ -68,11 +66,6 @@ public abstract class AbsPlayerFragment extends AbsMusicServiceFragment implemen
|
|||
case R.id.action_save_playing_queue:
|
||||
CreatePlaylistDialog.create(MusicPlayerRemote.getPlayingQueue()).show(getActivity().getSupportFragmentManager(), "ADD_TO_PLAYLIST");
|
||||
return true;
|
||||
case R.id.action_tag_editor:
|
||||
Intent intent = new Intent(getActivity(), SongTagEditorActivity.class);
|
||||
intent.putExtra(AbsTagEditorActivity.EXTRA_ID, song.id);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case R.id.action_details:
|
||||
SongDetailDialog.create(song).show(getFragmentManager(), "SONG_DETAIL");
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue