Fix scaning and updateing error
This commit is contained in:
parent
9dc2da66e1
commit
52dc1d9f22
11 changed files with 215 additions and 260 deletions
|
@ -25,7 +25,7 @@ android {
|
||||||
}
|
}
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
release {
|
release {
|
||||||
Properties properties = getProperties('/Users/apple/Documents/Github/retro.properties ')
|
Properties properties = getProperties('E:/Documents/GitHub/retro.properties')
|
||||||
storeFile file(getProperty(properties, 'storeFile'))
|
storeFile file(getProperty(properties, 'storeFile'))
|
||||||
keyAlias getProperty(properties, 'keyAlias')
|
keyAlias getProperty(properties, 'keyAlias')
|
||||||
storePassword getProperty(properties, 'storePassword')
|
storePassword getProperty(properties, 'storePassword')
|
||||||
|
|
|
@ -17,11 +17,9 @@ package code.name.monkey.retromusic.activities.tageditor
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.SearchManager
|
import android.app.SearchManager
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.res.ColorStateList
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
@ -30,25 +28,26 @@ import android.view.animation.OvershootInterpolator
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
|
||||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
|
||||||
import code.name.monkey.appthemehelper.util.TintHelper
|
import code.name.monkey.appthemehelper.util.TintHelper
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.R.drawable
|
import code.name.monkey.retromusic.R.drawable
|
||||||
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
||||||
import code.name.monkey.retromusic.activities.saf.SAFGuideActivity
|
import code.name.monkey.retromusic.activities.saf.SAFGuideActivity
|
||||||
|
import code.name.monkey.retromusic.extensions.accentColor
|
||||||
|
import code.name.monkey.retromusic.model.ArtworkInfo
|
||||||
|
import code.name.monkey.retromusic.model.LoadingInfo
|
||||||
import code.name.monkey.retromusic.repository.Repository
|
import code.name.monkey.retromusic.repository.Repository
|
||||||
import code.name.monkey.retromusic.util.RetroUtil
|
import code.name.monkey.retromusic.util.RetroUtil
|
||||||
import code.name.monkey.retromusic.util.SAFUtil
|
import code.name.monkey.retromusic.util.SAFUtil
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import java.io.File
|
|
||||||
import java.util.*
|
|
||||||
import kotlinx.android.synthetic.main.activity_album_tag_editor.*
|
import kotlinx.android.synthetic.main.activity_album_tag_editor.*
|
||||||
import org.jaudiotagger.audio.AudioFile
|
import org.jaudiotagger.audio.AudioFile
|
||||||
import org.jaudiotagger.audio.AudioFileIO
|
import org.jaudiotagger.audio.AudioFileIO
|
||||||
import org.jaudiotagger.tag.FieldKey
|
import org.jaudiotagger.tag.FieldKey
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
|
import java.io.File
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
val repository by inject<Repository>()
|
val repository by inject<Repository>()
|
||||||
|
@ -63,6 +62,8 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
private val currentSongPath: String? = null
|
private val currentSongPath: String? = null
|
||||||
private var savedTags: Map<FieldKey, String>? = null
|
private var savedTags: Map<FieldKey, String>? = null
|
||||||
private var savedArtworkInfo: ArtworkInfo? = null
|
private var savedArtworkInfo: ArtworkInfo? = null
|
||||||
|
protected abstract val contentViewLayout: Int
|
||||||
|
protected abstract fun loadImageFromFile(selectedFile: Uri?)
|
||||||
|
|
||||||
protected val show: AlertDialog
|
protected val show: AlertDialog
|
||||||
get() =
|
get() =
|
||||||
|
@ -76,7 +77,6 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.show()
|
.show()
|
||||||
protected abstract val contentViewLayout: Int
|
|
||||||
|
|
||||||
internal val albumArtist: String?
|
internal val albumArtist: String?
|
||||||
get() {
|
get() {
|
||||||
|
@ -196,6 +196,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
getIntentExtras()
|
getIntentExtras()
|
||||||
|
|
||||||
songPaths = getSongPaths()
|
songPaths = getSongPaths()
|
||||||
|
println(songPaths?.size)
|
||||||
if (songPaths!!.isEmpty()) {
|
if (songPaths!!.isEmpty()) {
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
@ -212,9 +213,9 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
private fun setUpImageView() {
|
private fun setUpImageView() {
|
||||||
loadCurrentImage()
|
loadCurrentImage()
|
||||||
items = listOf(
|
items = listOf(
|
||||||
getString(code.name.monkey.retromusic.R.string.pick_from_local_storage),
|
getString(R.string.pick_from_local_storage),
|
||||||
getString(code.name.monkey.retromusic.R.string.web_search),
|
getString(R.string.web_search),
|
||||||
getString(code.name.monkey.retromusic.R.string.remove_cover)
|
getString(R.string.remove_cover)
|
||||||
)
|
)
|
||||||
editorImage?.setOnClickListener { show }
|
editorImage?.setOnClickListener { show }
|
||||||
}
|
}
|
||||||
|
@ -225,7 +226,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
startActivityForResult(
|
startActivityForResult(
|
||||||
Intent.createChooser(
|
Intent.createChooser(
|
||||||
intent,
|
intent,
|
||||||
getString(code.name.monkey.retromusic.R.string.pick_from_local_storage)
|
getString(R.string.pick_from_local_storage)
|
||||||
), REQUEST_CODE_SELECT_IMAGE
|
), REQUEST_CODE_SELECT_IMAGE
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -237,20 +238,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
protected abstract fun deleteImage()
|
protected abstract fun deleteImage()
|
||||||
|
|
||||||
private fun setUpFab() {
|
private fun setUpFab() {
|
||||||
saveFab.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this))
|
saveFab.accentColor()
|
||||||
ColorStateList.valueOf(
|
|
||||||
MaterialValueHelper.getPrimaryTextColor(
|
|
||||||
this,
|
|
||||||
ColorUtil.isColorLight(
|
|
||||||
ThemeStore.accentColor(
|
|
||||||
this
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
).apply {
|
|
||||||
saveFab.setTextColor(this)
|
|
||||||
saveFab.iconTint = this
|
|
||||||
}
|
|
||||||
saveFab.apply {
|
saveFab.apply {
|
||||||
scaleX = 0f
|
scaleX = 0f
|
||||||
scaleY = 0f
|
scaleY = 0f
|
||||||
|
@ -344,30 +332,19 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
RetroUtil.hideSoftKeyboard(this)
|
RetroUtil.hideSoftKeyboard(this)
|
||||||
|
|
||||||
hideFab()
|
hideFab()
|
||||||
|
println(fieldKeyValueMap)
|
||||||
savedSongPaths = songPaths
|
WriteTagsAsyncTask(this).execute(
|
||||||
savedTags = fieldKeyValueMap
|
LoadingInfo(
|
||||||
savedArtworkInfo = artworkInfo
|
songPaths,
|
||||||
|
fieldKeyValueMap,
|
||||||
if (!SAFUtil.isSAFRequired(savedSongPaths)) {
|
artworkInfo
|
||||||
writeTags(savedSongPaths)
|
)
|
||||||
} else {
|
)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
if (SAFUtil.isSDCardAccessGranted(this)) {
|
|
||||||
writeTags(savedSongPaths)
|
|
||||||
} else {
|
|
||||||
startActivityForResult(
|
|
||||||
Intent(this, SAFGuideActivity::class.java),
|
|
||||||
SAFGuideActivity.REQUEST_CODE_SAF_GUIDE
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun writeTags(paths: List<String>?) {
|
private fun writeTags(paths: List<String>?) {
|
||||||
WriteTagsAsyncTask(this).execute(
|
WriteTagsAsyncTask(this).execute(
|
||||||
WriteTagsAsyncTask.LoadingInfo(
|
LoadingInfo(
|
||||||
paths,
|
paths,
|
||||||
savedTags,
|
savedTags,
|
||||||
savedArtworkInfo
|
savedArtworkInfo
|
||||||
|
@ -375,6 +352,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
|
||||||
super.onActivityResult(requestCode, resultCode, intent)
|
super.onActivityResult(requestCode, resultCode, intent)
|
||||||
when (requestCode) {
|
when (requestCode) {
|
||||||
|
@ -400,7 +378,6 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun loadImageFromFile(selectedFile: Uri?)
|
|
||||||
|
|
||||||
private fun getAudioFile(path: String): AudioFile {
|
private fun getAudioFile(path: String): AudioFile {
|
||||||
return try {
|
return try {
|
||||||
|
@ -411,7 +388,6 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ArtworkInfo constructor(val albumId: Long, val artwork: Bitmap?)
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.extensions.appHandleColor
|
import code.name.monkey.retromusic.extensions.appHandleColor
|
||||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder
|
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder
|
||||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
|
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
|
||||||
|
import code.name.monkey.retromusic.model.ArtworkInfo
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.util.ImageUtil
|
import code.name.monkey.retromusic.util.ImageUtil
|
||||||
import code.name.monkey.retromusic.util.RetroColorUtil.generatePalette
|
import code.name.monkey.retromusic.util.RetroColorUtil.generatePalette
|
||||||
|
@ -177,8 +178,11 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
|
|
||||||
writeValuesToFiles(
|
writeValuesToFiles(
|
||||||
fieldKeyValueMap,
|
fieldKeyValueMap,
|
||||||
if (deleteAlbumArt) ArtworkInfo(id, null)
|
when {
|
||||||
else if (albumArtBitmap == null) null else ArtworkInfo(id, albumArtBitmap!!)
|
deleteAlbumArt -> ArtworkInfo(id, null)
|
||||||
|
albumArtBitmap == null -> null
|
||||||
|
else -> ArtworkInfo(id, albumArtBitmap!!)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,10 +23,10 @@ import code.name.monkey.appthemehelper.util.MaterialUtil
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.extensions.appHandleColor
|
import code.name.monkey.retromusic.extensions.appHandleColor
|
||||||
import code.name.monkey.retromusic.repository.SongRepository
|
import code.name.monkey.retromusic.repository.SongRepository
|
||||||
import java.util.*
|
|
||||||
import kotlinx.android.synthetic.main.activity_song_tag_editor.*
|
import kotlinx.android.synthetic.main.activity_song_tag_editor.*
|
||||||
import org.jaudiotagger.tag.FieldKey
|
import org.jaudiotagger.tag.FieldKey
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
|
|
||||||
|
@ -102,11 +102,7 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
writeValuesToFiles(fieldKeyValueMap, null)
|
writeValuesToFiles(fieldKeyValueMap, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSongPaths(): List<String> {
|
override fun getSongPaths(): List<String> = listOf(songRepository.song(id).data)
|
||||||
val paths = ArrayList<String>(1)
|
|
||||||
paths.add(songRepository.song(id).data)
|
|
||||||
return paths
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun loadImageFromFile(selectedFile: Uri?) {
|
override fun loadImageFromFile(selectedFile: Uri?) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,188 +5,147 @@ import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.media.MediaScannerConnection;
|
import android.media.MediaScannerConnection;
|
||||||
import android.net.Uri;
|
import android.util.Log;
|
||||||
import android.os.Build;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import code.name.monkey.retromusic.R;
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
import code.name.monkey.retromusic.misc.DialogAsyncTask;
|
|
||||||
import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener;
|
|
||||||
import code.name.monkey.retromusic.util.MusicUtil;
|
|
||||||
import code.name.monkey.retromusic.util.SAFUtil;
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Map;
|
|
||||||
import org.jaudiotagger.audio.AudioFile;
|
import org.jaudiotagger.audio.AudioFile;
|
||||||
import org.jaudiotagger.audio.AudioFileIO;
|
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.FieldKey;
|
||||||
import org.jaudiotagger.tag.Tag;
|
import org.jaudiotagger.tag.Tag;
|
||||||
|
import org.jaudiotagger.tag.TagException;
|
||||||
import org.jaudiotagger.tag.images.Artwork;
|
import org.jaudiotagger.tag.images.Artwork;
|
||||||
import org.jaudiotagger.tag.images.ArtworkFactory;
|
import org.jaudiotagger.tag.images.ArtworkFactory;
|
||||||
|
|
||||||
public class WriteTagsAsyncTask
|
import java.io.File;
|
||||||
extends DialogAsyncTask<WriteTagsAsyncTask.LoadingInfo, Integer, String[]> {
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
private WeakReference<Activity> activity;
|
import code.name.monkey.retromusic.R;
|
||||||
|
import code.name.monkey.retromusic.misc.DialogAsyncTask;
|
||||||
|
import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener;
|
||||||
|
import code.name.monkey.retromusic.model.LoadingInfo;
|
||||||
|
import code.name.monkey.retromusic.util.MusicUtil;
|
||||||
|
|
||||||
public WriteTagsAsyncTask(@NonNull Activity activity) {
|
public class WriteTagsAsyncTask extends DialogAsyncTask<LoadingInfo, Integer, List<String>> {
|
||||||
super(activity);
|
|
||||||
this.activity = new WeakReference<>(activity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
public WriteTagsAsyncTask(Context context) {
|
||||||
@Override
|
super(context);
|
||||||
protected Dialog createDialog(@NonNull Context context) {
|
}
|
||||||
|
|
||||||
return new MaterialAlertDialogBuilder(context)
|
@Override
|
||||||
.setTitle(R.string.saving_changes)
|
protected List<String> doInBackground(LoadingInfo... params) {
|
||||||
.setCancelable(false)
|
|
||||||
.setView(R.layout.loading)
|
|
||||||
.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String[] doInBackground(LoadingInfo... params) {
|
|
||||||
try {
|
|
||||||
LoadingInfo info = params[0];
|
|
||||||
|
|
||||||
Artwork artwork = null;
|
|
||||||
File albumArtFile = null;
|
|
||||||
if (info.artworkInfo != null && info.artworkInfo.getArtwork() != null) {
|
|
||||||
try {
|
try {
|
||||||
albumArtFile = MusicUtil.INSTANCE.createAlbumArtFile().getCanonicalFile();
|
LoadingInfo info = params[0];
|
||||||
info.artworkInfo
|
|
||||||
.getArtwork()
|
|
||||||
.compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(albumArtFile));
|
|
||||||
artwork = ArtworkFactory.createArtworkFromFile(albumArtFile);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int counter = 0;
|
Artwork artwork = null;
|
||||||
boolean wroteArtwork = false;
|
File albumArtFile = null;
|
||||||
boolean deletedArtwork = false;
|
if (info.getArtworkInfo() != null && info.getArtworkInfo().getArtwork() != null) {
|
||||||
for (String filePath : info.filePaths) {
|
try {
|
||||||
publishProgress(++counter, info.filePaths.size());
|
albumArtFile = MusicUtil.INSTANCE.createAlbumArtFile().getCanonicalFile();
|
||||||
try {
|
info.getArtworkInfo().getArtwork().compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(albumArtFile));
|
||||||
Uri safUri = null;
|
artwork = ArtworkFactory.createArtworkFromFile(albumArtFile);
|
||||||
if (filePath.contains(SAFUtil.SEPARATOR)) {
|
} catch (IOException e) {
|
||||||
String[] fragments = filePath.split(SAFUtil.SEPARATOR);
|
e.printStackTrace();
|
||||||
filePath = fragments[0];
|
}
|
||||||
safUri = Uri.parse(fragments[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
int counter = 0;
|
||||||
if (info.artworkInfo.getArtwork() == null) {
|
boolean wroteArtwork = false;
|
||||||
tag.deleteArtworkField();
|
boolean deletedArtwork = false;
|
||||||
deletedArtwork = true;
|
for (String filePath : info.getFilePaths()) {
|
||||||
} else if (artwork != null) {
|
publishProgress(++counter, info.getFilePaths().size());
|
||||||
tag.deleteArtworkField();
|
try {
|
||||||
tag.setField(artwork);
|
AudioFile audioFile = AudioFileIO.read(new File(filePath));
|
||||||
wroteArtwork = true;
|
Tag tag = audioFile.getTagOrCreateAndSetDefault();
|
||||||
|
|
||||||
|
if (info.getFieldKeyValueMap() != null) {
|
||||||
|
for (Map.Entry<FieldKey, String> entry : info.getFieldKeyValueMap().entrySet()) {
|
||||||
|
try {
|
||||||
|
tag.setField(entry.getKey(), entry.getValue());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.getArtworkInfo() != null) {
|
||||||
|
if (info.getArtworkInfo().getArtwork() == 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Activity activity = this.activity.get();
|
Context context = getContext();
|
||||||
SAFUtil.write(activity, audioFile, safUri);
|
if (context != null) {
|
||||||
|
if (wroteArtwork) {
|
||||||
|
MusicUtil.INSTANCE.insertAlbumArt(context, info.getArtworkInfo().getAlbumId(), albumArtFile.getPath());
|
||||||
|
} else if (deletedArtwork) {
|
||||||
|
MusicUtil.INSTANCE.deleteAlbumArt(context, info.getArtworkInfo().getAlbumId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} catch (@NonNull Exception e) {
|
return info.getFilePaths();
|
||||||
e.printStackTrace();
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Context context = getContext();
|
@Override
|
||||||
if (context != null) {
|
protected void onPostExecute(List<String> toBeScanned) {
|
||||||
if (wroteArtwork) {
|
super.onPostExecute(toBeScanned);
|
||||||
MusicUtil.INSTANCE.insertAlbumArt(
|
scan(toBeScanned);
|
||||||
context, info.artworkInfo.getAlbumId(), albumArtFile.getPath());
|
}
|
||||||
} else if (deletedArtwork) {
|
|
||||||
MusicUtil.INSTANCE.deleteAlbumArt(context, info.artworkInfo.getAlbumId());
|
@Override
|
||||||
|
protected void onCancelled(List<String> toBeScanned) {
|
||||||
|
super.onCancelled(toBeScanned);
|
||||||
|
scan(toBeScanned);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scan(List<String> toBeScanned) {
|
||||||
|
Context context = getContext();
|
||||||
|
if (toBeScanned == null || toBeScanned.isEmpty()) {
|
||||||
|
Log.i("scan", "scan: Empty");
|
||||||
|
Toast.makeText(context, "Scan file from folder", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
MediaScannerConnection.scanFile(context, toBeScanned.toArray(new String[0]), null, context instanceof Activity ? new UpdateToastMediaScannerCompletionListener((Activity) context, toBeScanned) : null);
|
||||||
|
|
||||||
Collection<String> paths = info.filePaths;
|
|
||||||
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
|
|
||||||
paths = new ArrayList<>(info.filePaths.size());
|
|
||||||
for (String path : info.filePaths) {
|
|
||||||
if (path.contains(SAFUtil.SEPARATOR)) {
|
|
||||||
path = path.split(SAFUtil.SEPARATOR)[0];
|
|
||||||
}
|
|
||||||
paths.add(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return paths.toArray(new String[paths.size()]);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCancelled(String[] toBeScanned) {
|
protected Dialog createDialog(@NonNull Context context) {
|
||||||
super.onCancelled(toBeScanned);
|
return new MaterialDialog.Builder(context)
|
||||||
scan(toBeScanned);
|
.title(R.string.saving_changes)
|
||||||
}
|
.cancelable(false)
|
||||||
|
.progress(false, 0)
|
||||||
@Override
|
.build();
|
||||||
protected void onPostExecute(String[] toBeScanned) {
|
|
||||||
super.onPostExecute(toBeScanned);
|
|
||||||
scan(toBeScanned);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onProgressUpdate(@NonNull Dialog dialog, Integer... values) {
|
|
||||||
super.onProgressUpdate(dialog, values);
|
|
||||||
// ((MaterialDialog) dialog).setMaxProgress(values[1]);
|
|
||||||
// ((MaterialDialog) dialog).setProgress(values[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void scan(String[] toBeScanned) {
|
|
||||||
Activity activity = this.activity.get();
|
|
||||||
if (activity != null) {
|
|
||||||
MediaScannerConnection.scanFile(
|
|
||||||
activity,
|
|
||||||
toBeScanned,
|
|
||||||
null,
|
|
||||||
new UpdateToastMediaScannerCompletionListener(activity, toBeScanned));
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static class LoadingInfo {
|
@Override
|
||||||
|
protected void onProgressUpdate(@NonNull Dialog dialog, Integer... values) {
|
||||||
@Nullable final Map<FieldKey, String> fieldKeyValueMap;
|
super.onProgressUpdate(dialog, values);
|
||||||
|
((MaterialDialog) dialog).setMaxProgress(values[1]);
|
||||||
final Collection<String> filePaths;
|
((MaterialDialog) dialog).setProgress(values[0]);
|
||||||
|
|
||||||
@Nullable private AbsTagEditorActivity.ArtworkInfo artworkInfo;
|
|
||||||
|
|
||||||
public LoadingInfo(
|
|
||||||
Collection<String> filePaths,
|
|
||||||
@Nullable Map<FieldKey, String> fieldKeyValueMap,
|
|
||||||
@Nullable AbsTagEditorActivity.ArtworkInfo artworkInfo) {
|
|
||||||
this.filePaths = filePaths;
|
|
||||||
this.fieldKeyValueMap = fieldKeyValueMap;
|
|
||||||
this.artworkInfo = artworkInfo;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,6 +154,10 @@ fun MaterialButton.applyColor(color: Int) {
|
||||||
iconTint = textColorColorStateList
|
iconTint = textColorColorStateList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun MaterialButton.accentColor(){
|
||||||
|
this.applyColor(ThemeStore.accentColor(context))
|
||||||
|
}
|
||||||
|
|
||||||
fun MaterialButton.applyOutlineColor(color: Int) {
|
fun MaterialButton.applyOutlineColor(color: Int) {
|
||||||
val textColorColorStateList = ColorStateList.valueOf(color)
|
val textColorColorStateList = ColorStateList.valueOf(color)
|
||||||
setTextColor(textColorColorStateList)
|
setTextColor(textColorColorStateList)
|
||||||
|
|
|
@ -54,6 +54,7 @@ import java.io.FileFilter;
|
||||||
import java.io.IOException;
|
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.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
@ -520,7 +521,7 @@ public class FoldersFragment extends AbsMainActivityFragment
|
||||||
getActivity().getApplicationContext(),
|
getActivity().getApplicationContext(),
|
||||||
toBeScanned,
|
toBeScanned,
|
||||||
null,
|
null,
|
||||||
new UpdateToastMediaScannerCompletionListener(getActivity(), toBeScanned));
|
new UpdateToastMediaScannerCompletionListener(getActivity(), Arrays.asList(toBeScanned)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ import android.widget.FrameLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.core.os.bundleOf
|
import androidx.core.os.bundleOf
|
||||||
import androidx.navigation.fragment.FragmentNavigatorExtras
|
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||||
import code.name.monkey.retromusic.EXTRA_ARTIST_ID
|
import code.name.monkey.retromusic.EXTRA_ARTIST_ID
|
||||||
|
@ -163,13 +162,10 @@ class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full),
|
||||||
private fun setupArtist() {
|
private fun setupArtist() {
|
||||||
artistImage.setOnClickListener {
|
artistImage.setOnClickListener {
|
||||||
mainActivity.collapsePanel()
|
mainActivity.collapsePanel()
|
||||||
findNavController()
|
findNavController().navigate(
|
||||||
.navigate(
|
R.id.artistDetailsFragment,
|
||||||
R.id.artistDetailsFragment,
|
bundleOf(EXTRA_ARTIST_ID to MusicPlayerRemote.currentSong.artistId),
|
||||||
bundleOf(EXTRA_ARTIST_ID to MusicPlayerRemote.currentSong.artistId),
|
)
|
||||||
null,
|
|
||||||
FragmentNavigatorExtras(it to "artist")
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,49 +19,54 @@ import android.app.Activity;
|
||||||
import android.media.MediaScannerConnection;
|
import android.media.MediaScannerConnection;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import code.name.monkey.retromusic.R;
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/** @author Karim Abou Zeid (kabouzeid) */
|
import code.name.monkey.retromusic.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
|
*/
|
||||||
public class UpdateToastMediaScannerCompletionListener
|
public class UpdateToastMediaScannerCompletionListener
|
||||||
implements MediaScannerConnection.OnScanCompletedListener {
|
implements MediaScannerConnection.OnScanCompletedListener {
|
||||||
|
|
||||||
private final WeakReference<Activity> activityWeakReference;
|
private final WeakReference<Activity> activityWeakReference;
|
||||||
|
|
||||||
private final String couldNotScanFiles;
|
private final String couldNotScanFiles;
|
||||||
private final String scannedFiles;
|
private final String scannedFiles;
|
||||||
private final String[] toBeScanned;
|
private final List<String> toBeScanned;
|
||||||
private int failed = 0;
|
private int failed = 0;
|
||||||
private int scanned = 0;
|
private int scanned = 0;
|
||||||
private Toast toast;
|
private Toast toast;
|
||||||
|
|
||||||
@SuppressLint("ShowToast")
|
@SuppressLint("ShowToast")
|
||||||
public UpdateToastMediaScannerCompletionListener(Activity activity, String[] toBeScanned) {
|
public UpdateToastMediaScannerCompletionListener(Activity activity, List<String> toBeScanned) {
|
||||||
this.toBeScanned = toBeScanned;
|
this.toBeScanned = toBeScanned;
|
||||||
scannedFiles = activity.getString(R.string.scanned_files);
|
scannedFiles = activity.getString(R.string.scanned_files);
|
||||||
couldNotScanFiles = activity.getString(R.string.could_not_scan_files);
|
couldNotScanFiles = activity.getString(R.string.could_not_scan_files);
|
||||||
toast = Toast.makeText(activity.getApplicationContext(), "", Toast.LENGTH_SHORT);
|
toast = Toast.makeText(activity.getApplicationContext(), "", Toast.LENGTH_SHORT);
|
||||||
activityWeakReference = new WeakReference<>(activity);
|
activityWeakReference = new WeakReference<>(activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onScanCompleted(final String path, final Uri uri) {
|
public void onScanCompleted(final String path, final Uri uri) {
|
||||||
Activity activity = activityWeakReference.get();
|
Activity activity = activityWeakReference.get();
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
activity.runOnUiThread(
|
activity.runOnUiThread(
|
||||||
() -> {
|
() -> {
|
||||||
if (uri == null) {
|
if (uri == null) {
|
||||||
failed++;
|
failed++;
|
||||||
} else {
|
} else {
|
||||||
scanned++;
|
scanned++;
|
||||||
}
|
}
|
||||||
String text =
|
String text =
|
||||||
" "
|
" "
|
||||||
+ String.format(scannedFiles, scanned, toBeScanned.length)
|
+ String.format(scannedFiles, scanned, toBeScanned.size())
|
||||||
+ (failed > 0 ? " " + String.format(couldNotScanFiles, failed) : "");
|
+ (failed > 0 ? " " + String.format(couldNotScanFiles, failed) : "");
|
||||||
toast.setText(text);
|
toast.setText(text);
|
||||||
toast.show();
|
toast.show();
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package code.name.monkey.retromusic.model
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
|
||||||
|
class ArtworkInfo constructor(val albumId: Long, val artwork: Bitmap?)
|
|
@ -0,0 +1,9 @@
|
||||||
|
package code.name.monkey.retromusic.model
|
||||||
|
|
||||||
|
import org.jaudiotagger.tag.FieldKey
|
||||||
|
|
||||||
|
class LoadingInfo(
|
||||||
|
val filePaths: List<String>?,
|
||||||
|
val fieldKeyValueMap: Map<FieldKey, String>?,
|
||||||
|
val artworkInfo: ArtworkInfo?
|
||||||
|
)
|
Loading…
Reference in a new issue