diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/artists/AbsArtistDetailsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/artists/AbsArtistDetailsFragment.kt index 17ddfd0d4..eaa4a621b 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/artists/AbsArtistDetailsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/artists/AbsArtistDetailsFragment.kt @@ -173,7 +173,7 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm private fun loadBiography( name: String, - lang: String? = Locale.getDefault().language + lang: String? = Locale.getDefault().language, ) { biography = null this.lang = lang @@ -274,12 +274,16 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm R.id.action_set_artist_image -> { val intent = Intent(Intent.ACTION_GET_CONTENT) intent.type = "image/*" - selectImageLauncher.launch(Intent.createChooser(intent, getString(R.string.pick_from_local_storage))) + selectImageLauncher.launch(Intent.createChooser(intent, + getString(R.string.pick_from_local_storage))) return true } R.id.action_reset_artist_image -> { showToast(resources.getString(R.string.updating)) - CustomArtistImageUtil.getInstance(requireContext()).resetCustomArtistImage(artist) + lifecycleScope.launch { + CustomArtistImageUtil.getInstance(requireContext()) + .resetCustomArtistImage(artist) + } forceDownload = true return true } @@ -335,14 +339,18 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm } } - private val selectImageLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {result-> - if (result.resultCode == Activity.RESULT_OK) { - result.data?.data?.let { - CustomArtistImageUtil.getInstance(requireContext()) - .setCustomArtistImage(artist, it) + private val selectImageLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> + if (result.resultCode == Activity.RESULT_OK) { + result.data?.data?.let { + lifecycleScope.launch { + CustomArtistImageUtil.getInstance(requireContext()) + .setCustomArtistImage(artist, it) + } + + } } } - } override fun onCreateMenu(menu: Menu, inflater: MenuInflater) { inflater.inflate(R.menu.menu_artist_detail, menu) diff --git a/app/src/main/java/code/name/monkey/retromusic/misc/DialogAsyncTask.java b/app/src/main/java/code/name/monkey/retromusic/misc/DialogAsyncTask.java deleted file mode 100644 index 38e41539b..000000000 --- a/app/src/main/java/code/name/monkey/retromusic/misc/DialogAsyncTask.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2019 Hemanth Savarala. - * - * Licensed under the GNU General Public License v3 - * - * This is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by - * the Free Software Foundation either version 3 of the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - */ - -package code.name.monkey.retromusic.misc; - -import android.app.Dialog; -import android.content.Context; -import android.os.Handler; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import java.lang.ref.WeakReference; - -public abstract class DialogAsyncTask - extends WeakContextAsyncTask { - private final int delay; - - private WeakReference dialogWeakReference; - - private boolean supposedToBeDismissed; - - public DialogAsyncTask(Context context) { - this(context, 0); - } - - public DialogAsyncTask(Context context, int showDelay) { - super(context); - this.delay = showDelay; - dialogWeakReference = new WeakReference<>(null); - } - - @Override - protected void onPreExecute() { - super.onPreExecute(); - if (delay > 0) { - new Handler().postDelayed(this::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 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); -} diff --git a/app/src/main/java/code/name/monkey/retromusic/misc/WeakContextAsyncTask.kt b/app/src/main/java/code/name/monkey/retromusic/misc/WeakContextAsyncTask.kt deleted file mode 100644 index 9b9b4896b..000000000 --- a/app/src/main/java/code/name/monkey/retromusic/misc/WeakContextAsyncTask.kt +++ /dev/null @@ -1 +0,0 @@ -/* * Copyright (c) 2019 Hemanth Savarala. * * Licensed under the GNU General Public License v3 * * This is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by * the Free Software Foundation either version 3 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. */ package code.name.monkey.retromusic.misc import android.content.Context import android.os.AsyncTask import java.lang.ref.WeakReference abstract class WeakContextAsyncTask(context: Context) : AsyncTask() { private val contextWeakReference: WeakReference = WeakReference(context) protected val context: Context? get() = contextWeakReference.get() } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/util/CustomArtistImageUtil.kt b/app/src/main/java/code/name/monkey/retromusic/util/CustomArtistImageUtil.kt index fa6e52fd3..39994818f 100644 --- a/app/src/main/java/code/name/monkey/retromusic/util/CustomArtistImageUtil.kt +++ b/app/src/main/java/code/name/monkey/retromusic/util/CustomArtistImageUtil.kt @@ -14,23 +14,20 @@ package code.name.monkey.retromusic.util -import android.annotation.SuppressLint import android.content.Context import android.content.SharedPreferences import android.graphics.Bitmap -import android.graphics.drawable.Drawable import android.net.Uri -import android.os.AsyncTask import android.provider.MediaStore import android.widget.Toast import androidx.core.content.edit import code.name.monkey.retromusic.App import code.name.monkey.retromusic.extensions.showToast +import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.model.Artist -import com.bumptech.glide.Glide import com.bumptech.glide.load.engine.DiskCacheStrategy -import com.bumptech.glide.request.target.SimpleTarget -import com.bumptech.glide.request.transition.Transition +import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.withContext import java.io.File import java.io.IOException import java.util.* @@ -43,77 +40,71 @@ class CustomArtistImageUtil private constructor(context: Context) { Context.MODE_PRIVATE ) - fun setCustomArtistImage(artist: Artist, uri: Uri) { - Glide.with(App.getContext()) - .asBitmap() - .load(uri) - .diskCacheStrategy(DiskCacheStrategy.NONE) - .skipMemoryCache(true) - .into(object : SimpleTarget() { - override fun onLoadFailed(errorDrawable: Drawable?) { - super.onLoadFailed(errorDrawable) - App.getContext().showToast("Load Failed") + suspend fun setCustomArtistImage(artist: Artist, uri: Uri) { + val context = App.getContext() + withContext(IO) { + runCatching { + GlideApp.with(context) + .asBitmap() + .load(uri) + .diskCacheStrategy(DiskCacheStrategy.NONE) + .skipMemoryCache(true) + .submit() + .get() + } + .onSuccess { + saveImage(context, artist, it) } - - @SuppressLint("StaticFieldLeak") - override fun onResourceReady(resource: Bitmap, transition: Transition?) { - object : AsyncTask() { - override fun doInBackground(vararg params: Void): Void? { - val dir = File(App.getContext().filesDir, FOLDER_NAME) - if (!dir.exists()) { - if (!dir.mkdirs()) { // create the folder - return null - } - } - val file = File(dir, getFileName(artist)) - - var succesful = false - try { - file.outputStream().buffered().use { bos -> - succesful = ImageUtil.resizeBitmap(resource, 2048) - .compress(Bitmap.CompressFormat.JPEG, 100, bos) - } - } catch (e: IOException) { - App.getContext().showToast(e.toString(), Toast.LENGTH_LONG) - } - - if (succesful) { - mPreferences.edit { putBoolean(getFileName(artist), true) } - ArtistSignatureUtil.getInstance(App.getContext()) - .updateArtistSignature(artist.name) - App.getContext().contentResolver.notifyChange( - MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI, - null - ) // trigger media store changed to force artist image reload - } - return null - } - }.execute() + .onFailure { + context.showToast("Load Failed") } - }) + } } - @SuppressLint("StaticFieldLeak") - fun resetCustomArtistImage(artist: Artist) { - object : AsyncTask() { - @SuppressLint("ApplySharedPref") - override fun doInBackground(vararg params: Void): Void? { - mPreferences.edit(commit = true) { putBoolean(getFileName(artist), false) } - ArtistSignatureUtil.getInstance(App.getContext()).updateArtistSignature(artist.name) - App.getContext().contentResolver.notifyChange( - MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI, - null - ) // trigger media store changed to force artist image reload - - val file = getFile(artist) - if (!file.exists()) { - return null - } else { - file.delete() - } - return null + private fun saveImage(context: Context, artist: Artist, bitmap: Bitmap) { + val dir = File(context.filesDir, FOLDER_NAME) + if (!dir.exists()) { + if (!dir.mkdirs()) { // create the folder + return } - }.execute() + } + val file = File(dir, getFileName(artist)) + + var successful = false + try { + file.outputStream().buffered().use { bos -> + successful = ImageUtil.resizeBitmap(bitmap, 2048) + .compress(Bitmap.CompressFormat.JPEG, 100, bos) + } + } catch (e: IOException) { + context.showToast(e.toString(), Toast.LENGTH_LONG) + } + + if (successful) { + mPreferences.edit { putBoolean(getFileName(artist), true) } + ArtistSignatureUtil.getInstance(context) + .updateArtistSignature(artist.name) + context.contentResolver.notifyChange( + MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI, + null + ) // trigger media store changed to force artist image reload + } + } + + suspend fun resetCustomArtistImage(artist: Artist) { + withContext(IO) { + mPreferences.edit { putBoolean(getFileName(artist), false) } + ArtistSignatureUtil.getInstance(App.getContext()).updateArtistSignature(artist.name) + App.getContext().contentResolver.notifyChange( + MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI, + null + ) // trigger media store changed to force artist image reload + + val file = getFile(artist) + if (file.exists()) { + file.delete() + } + } } // shared prefs saves us many IO operations