Fix scaning and updateing error

main
Hemanth S 2020-10-12 22:52:53 +05:30
parent 9dc2da66e1
commit 52dc1d9f22
11 changed files with 215 additions and 260 deletions

View File

@ -25,7 +25,7 @@ android {
}
signingConfigs {
release {
Properties properties = getProperties('/Users/apple/Documents/Github/retro.properties ')
Properties properties = getProperties('E:/Documents/GitHub/retro.properties')
storeFile file(getProperty(properties, 'storeFile'))
keyAlias getProperty(properties, 'keyAlias')
storePassword getProperty(properties, 'storePassword')

View File

@ -17,11 +17,9 @@ package code.name.monkey.retromusic.activities.tageditor
import android.app.Activity
import android.app.SearchManager
import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.MenuItem
@ -30,25 +28,26 @@ import android.view.animation.OvershootInterpolator
import androidx.appcompat.app.AlertDialog
import code.name.monkey.appthemehelper.ThemeStore
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.retromusic.R
import code.name.monkey.retromusic.R.drawable
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
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.util.RetroUtil
import code.name.monkey.retromusic.util.SAFUtil
import com.google.android.material.button.MaterialButton
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.io.File
import java.util.*
import kotlinx.android.synthetic.main.activity_album_tag_editor.*
import org.jaudiotagger.audio.AudioFile
import org.jaudiotagger.audio.AudioFileIO
import org.jaudiotagger.tag.FieldKey
import org.koin.android.ext.android.inject
import java.io.File
import java.util.*
abstract class AbsTagEditorActivity : AbsBaseActivity() {
val repository by inject<Repository>()
@ -63,6 +62,8 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
private val currentSongPath: String? = null
private var savedTags: Map<FieldKey, String>? = null
private var savedArtworkInfo: ArtworkInfo? = null
protected abstract val contentViewLayout: Int
protected abstract fun loadImageFromFile(selectedFile: Uri?)
protected val show: AlertDialog
get() =
@ -76,7 +77,6 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
}
}
.show()
protected abstract val contentViewLayout: Int
internal val albumArtist: String?
get() {
@ -196,6 +196,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
getIntentExtras()
songPaths = getSongPaths()
println(songPaths?.size)
if (songPaths!!.isEmpty()) {
finish()
}
@ -212,9 +213,9 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
private fun setUpImageView() {
loadCurrentImage()
items = listOf(
getString(code.name.monkey.retromusic.R.string.pick_from_local_storage),
getString(code.name.monkey.retromusic.R.string.web_search),
getString(code.name.monkey.retromusic.R.string.remove_cover)
getString(R.string.pick_from_local_storage),
getString(R.string.web_search),
getString(R.string.remove_cover)
)
editorImage?.setOnClickListener { show }
}
@ -225,7 +226,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
startActivityForResult(
Intent.createChooser(
intent,
getString(code.name.monkey.retromusic.R.string.pick_from_local_storage)
getString(R.string.pick_from_local_storage)
), REQUEST_CODE_SELECT_IMAGE
)
}
@ -237,20 +238,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
protected abstract fun deleteImage()
private fun setUpFab() {
saveFab.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this))
ColorStateList.valueOf(
MaterialValueHelper.getPrimaryTextColor(
this,
ColorUtil.isColorLight(
ThemeStore.accentColor(
this
)
)
)
).apply {
saveFab.setTextColor(this)
saveFab.iconTint = this
}
saveFab.accentColor()
saveFab.apply {
scaleX = 0f
scaleY = 0f
@ -344,30 +332,19 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
RetroUtil.hideSoftKeyboard(this)
hideFab()
savedSongPaths = songPaths
savedTags = fieldKeyValueMap
savedArtworkInfo = artworkInfo
if (!SAFUtil.isSAFRequired(savedSongPaths)) {
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
)
}
}
}
println(fieldKeyValueMap)
WriteTagsAsyncTask(this).execute(
LoadingInfo(
songPaths,
fieldKeyValueMap,
artworkInfo
)
)
}
private fun writeTags(paths: List<String>?) {
WriteTagsAsyncTask(this).execute(
WriteTagsAsyncTask.LoadingInfo(
LoadingInfo(
paths,
savedTags,
savedArtworkInfo
@ -375,6 +352,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
super.onActivityResult(requestCode, resultCode, intent)
when (requestCode) {
@ -400,7 +378,6 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
}
}
protected abstract fun loadImageFromFile(selectedFile: Uri?)
private fun getAudioFile(path: String): AudioFile {
return try {
@ -411,7 +388,6 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
}
}
class ArtworkInfo constructor(val albumId: Long, val artwork: Bitmap?)
companion object {

View File

@ -32,6 +32,7 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.appHandleColor
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder
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.util.ImageUtil
import code.name.monkey.retromusic.util.RetroColorUtil.generatePalette
@ -177,8 +178,11 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
writeValuesToFiles(
fieldKeyValueMap,
if (deleteAlbumArt) ArtworkInfo(id, null)
else if (albumArtBitmap == null) null else ArtworkInfo(id, albumArtBitmap!!)
when {
deleteAlbumArt -> ArtworkInfo(id, null)
albumArtBitmap == null -> null
else -> ArtworkInfo(id, albumArtBitmap!!)
}
)
}

View File

@ -23,10 +23,10 @@ import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.appHandleColor
import code.name.monkey.retromusic.repository.SongRepository
import java.util.*
import kotlinx.android.synthetic.main.activity_song_tag_editor.*
import org.jaudiotagger.tag.FieldKey
import org.koin.android.ext.android.inject
import java.util.*
class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
@ -102,11 +102,7 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
writeValuesToFiles(fieldKeyValueMap, null)
}
override fun getSongPaths(): List<String> {
val paths = ArrayList<String>(1)
paths.add(songRepository.song(id).data)
return paths
}
override fun getSongPaths(): List<String> = listOf(songRepository.song(id).data)
override fun loadImageFromFile(selectedFile: Uri?) {
}

View File

@ -5,188 +5,147 @@ import android.app.Dialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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.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 com.afollestad.materialdialogs.MaterialDialog;
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;
public class WriteTagsAsyncTask
extends DialogAsyncTask<WriteTagsAsyncTask.LoadingInfo, Integer, String[]> {
import java.io.File;
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) {
super(activity);
this.activity = new WeakReference<>(activity);
}
public class WriteTagsAsyncTask extends DialogAsyncTask<LoadingInfo, Integer, List<String>> {
@NonNull
@Override
protected Dialog createDialog(@NonNull Context context) {
public WriteTagsAsyncTask(Context context) {
super(context);
}
return new MaterialAlertDialogBuilder(context)
.setTitle(R.string.saving_changes)
.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) {
@Override
protected List<String> doInBackground(LoadingInfo... params) {
try {
albumArtFile = MusicUtil.INSTANCE.createAlbumArtFile().getCanonicalFile();
info.artworkInfo
.getArtwork()
.compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(albumArtFile));
artwork = ArtworkFactory.createArtworkFromFile(albumArtFile);
} catch (IOException e) {
e.printStackTrace();
}
}
LoadingInfo info = params[0];
int counter = 0;
boolean wroteArtwork = false;
boolean deletedArtwork = false;
for (String filePath : info.filePaths) {
publishProgress(++counter, info.filePaths.size());
try {
Uri safUri = null;
if (filePath.contains(SAFUtil.SEPARATOR)) {
String[] fragments = filePath.split(SAFUtil.SEPARATOR);
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();
}
Artwork artwork = null;
File albumArtFile = null;
if (info.getArtworkInfo() != null && info.getArtworkInfo().getArtwork() != null) {
try {
albumArtFile = MusicUtil.INSTANCE.createAlbumArtFile().getCanonicalFile();
info.getArtworkInfo().getArtwork().compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(albumArtFile));
artwork = ArtworkFactory.createArtworkFromFile(albumArtFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
if (info.artworkInfo != null) {
if (info.artworkInfo.getArtwork() == null) {
tag.deleteArtworkField();
deletedArtwork = true;
} else if (artwork != null) {
tag.deleteArtworkField();
tag.setField(artwork);
wroteArtwork = true;
int counter = 0;
boolean wroteArtwork = false;
boolean deletedArtwork = false;
for (String filePath : info.getFilePaths()) {
publishProgress(++counter, info.getFilePaths().size());
try {
AudioFile audioFile = AudioFileIO.read(new File(filePath));
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();
SAFUtil.write(activity, audioFile, safUri);
Context context = getContext();
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) {
e.printStackTrace();
return info.getFilePaths();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Context context = getContext();
if (context != null) {
if (wroteArtwork) {
MusicUtil.INSTANCE.insertAlbumArt(
context, info.artworkInfo.getAlbumId(), albumArtFile.getPath());
} else if (deletedArtwork) {
MusicUtil.INSTANCE.deleteAlbumArt(context, info.artworkInfo.getAlbumId());
@Override
protected void onPostExecute(List<String> toBeScanned) {
super.onPostExecute(toBeScanned);
scan(toBeScanned);
}
@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;
}
}
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;
MediaScannerConnection.scanFile(context, toBeScanned.toArray(new String[0]), null, context instanceof Activity ? new UpdateToastMediaScannerCompletionListener((Activity) context, toBeScanned) : null);
}
}
@Override
protected void onCancelled(String[] toBeScanned) {
super.onCancelled(toBeScanned);
scan(toBeScanned);
}
@Override
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));
@Override
protected Dialog createDialog(@NonNull Context context) {
return new MaterialDialog.Builder(context)
.title(R.string.saving_changes)
.cancelable(false)
.progress(false, 0)
.build();
}
}
public static class LoadingInfo {
@Nullable final Map<FieldKey, String> fieldKeyValueMap;
final Collection<String> filePaths;
@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;
@Override
protected void onProgressUpdate(@NonNull Dialog dialog, Integer... values) {
super.onProgressUpdate(dialog, values);
((MaterialDialog) dialog).setMaxProgress(values[1]);
((MaterialDialog) dialog).setProgress(values[0]);
}
}
}

View File

@ -154,6 +154,10 @@ fun MaterialButton.applyColor(color: Int) {
iconTint = textColorColorStateList
}
fun MaterialButton.accentColor(){
this.applyColor(ThemeStore.accentColor(context))
}
fun MaterialButton.applyOutlineColor(color: Int) {
val textColorColorStateList = ColorStateList.valueOf(color)
setTextColor(textColorColorStateList)

View File

@ -54,6 +54,7 @@ import java.io.FileFilter;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
@ -520,7 +521,7 @@ public class FoldersFragment extends AbsMainActivityFragment
getActivity().getApplicationContext(),
toBeScanned,
null,
new UpdateToastMediaScannerCompletionListener(getActivity(), toBeScanned));
new UpdateToastMediaScannerCompletionListener(getActivity(), Arrays.asList(toBeScanned)));
}
}

View File

@ -22,7 +22,6 @@ import android.widget.FrameLayout
import android.widget.TextView
import androidx.appcompat.widget.Toolbar
import androidx.core.os.bundleOf
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.EXTRA_ARTIST_ID
@ -163,13 +162,10 @@ class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full),
private fun setupArtist() {
artistImage.setOnClickListener {
mainActivity.collapsePanel()
findNavController()
.navigate(
R.id.artistDetailsFragment,
bundleOf(EXTRA_ARTIST_ID to MusicPlayerRemote.currentSong.artistId),
null,
FragmentNavigatorExtras(it to "artist")
)
findNavController().navigate(
R.id.artistDetailsFragment,
bundleOf(EXTRA_ARTIST_ID to MusicPlayerRemote.currentSong.artistId),
)
}
}

View File

@ -19,49 +19,54 @@ import android.app.Activity;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.widget.Toast;
import code.name.monkey.retromusic.R;
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
implements MediaScannerConnection.OnScanCompletedListener {
implements MediaScannerConnection.OnScanCompletedListener {
private final WeakReference<Activity> activityWeakReference;
private final WeakReference<Activity> activityWeakReference;
private final String couldNotScanFiles;
private final String scannedFiles;
private final String[] toBeScanned;
private int failed = 0;
private int scanned = 0;
private Toast toast;
private final String couldNotScanFiles;
private final String scannedFiles;
private final List<String> toBeScanned;
private int failed = 0;
private int scanned = 0;
private Toast toast;
@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);
toast = Toast.makeText(activity.getApplicationContext(), "", 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(
() -> {
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();
});
@SuppressLint("ShowToast")
public UpdateToastMediaScannerCompletionListener(Activity activity, List<String> toBeScanned) {
this.toBeScanned = toBeScanned;
scannedFiles = activity.getString(R.string.scanned_files);
couldNotScanFiles = activity.getString(R.string.could_not_scan_files);
toast = Toast.makeText(activity.getApplicationContext(), "", 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(
() -> {
if (uri == null) {
failed++;
} else {
scanned++;
}
String text =
" "
+ String.format(scannedFiles, scanned, toBeScanned.size())
+ (failed > 0 ? " " + String.format(couldNotScanFiles, failed) : "");
toast.setText(text);
toast.show();
});
}
}
}
}

View File

@ -0,0 +1,5 @@
package code.name.monkey.retromusic.model
import android.graphics.Bitmap
class ArtworkInfo constructor(val albumId: Long, val artwork: Bitmap?)

View File

@ -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?
)