Replaced AsyncTasks of Folders tab with coroutines
This commit is contained in:
parent
0604307b88
commit
c570be349d
1 changed files with 111 additions and 239 deletions
|
@ -13,12 +13,10 @@
|
||||||
*/
|
*/
|
||||||
package code.name.monkey.retromusic.fragments.folder
|
package code.name.monkey.retromusic.fragments.folder
|
||||||
|
|
||||||
import android.app.Dialog
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.media.MediaScannerConnection
|
import android.media.MediaScannerConnection
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.text.Html
|
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
@ -26,7 +24,9 @@ import android.view.View
|
||||||
import android.webkit.MimeTypeMap
|
import android.webkit.MimeTypeMap
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
|
import androidx.core.text.parseAsHtml
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.loader.app.LoaderManager
|
import androidx.loader.app.LoaderManager
|
||||||
import androidx.loader.content.Loader
|
import androidx.loader.content.Loader
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
|
@ -35,7 +35,6 @@ import androidx.recyclerview.widget.RecyclerView
|
||||||
import code.name.monkey.appthemehelper.ThemeStore.Companion.accentColor
|
import code.name.monkey.appthemehelper.ThemeStore.Companion.accentColor
|
||||||
import code.name.monkey.appthemehelper.common.ATHToolbarActivity
|
import code.name.monkey.appthemehelper.common.ATHToolbarActivity
|
||||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||||
import code.name.monkey.retromusic.App
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.adapter.SongFileAdapter
|
import code.name.monkey.retromusic.adapter.SongFileAdapter
|
||||||
import code.name.monkey.retromusic.adapter.Storage
|
import code.name.monkey.retromusic.adapter.Storage
|
||||||
|
@ -44,17 +43,13 @@ import code.name.monkey.retromusic.adapter.StorageClickListener
|
||||||
import code.name.monkey.retromusic.databinding.FragmentFolderBinding
|
import code.name.monkey.retromusic.databinding.FragmentFolderBinding
|
||||||
import code.name.monkey.retromusic.extensions.*
|
import code.name.monkey.retromusic.extensions.*
|
||||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||||
import code.name.monkey.retromusic.fragments.folder.FoldersFragment.ListPathsAsyncTask.OnPathsListedCallback
|
|
||||||
import code.name.monkey.retromusic.fragments.folder.FoldersFragment.ListSongsAsyncTask.OnSongsListedCallback
|
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote.openQueue
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote.openQueue
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote.playingQueue
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote.playingQueue
|
||||||
import code.name.monkey.retromusic.helper.menu.SongMenuHelper.handleMenuClick
|
|
||||||
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
|
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
|
||||||
import code.name.monkey.retromusic.interfaces.ICabCallback
|
import code.name.monkey.retromusic.interfaces.ICabCallback
|
||||||
import code.name.monkey.retromusic.interfaces.ICabHolder
|
import code.name.monkey.retromusic.interfaces.ICabHolder
|
||||||
import code.name.monkey.retromusic.interfaces.ICallbacks
|
import code.name.monkey.retromusic.interfaces.ICallbacks
|
||||||
import code.name.monkey.retromusic.interfaces.IMainActivityFragmentCallbacks
|
import code.name.monkey.retromusic.interfaces.IMainActivityFragmentCallbacks
|
||||||
import code.name.monkey.retromusic.misc.DialogAsyncTask
|
|
||||||
import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener
|
import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener
|
||||||
import code.name.monkey.retromusic.misc.WrappedAsyncTaskLoader
|
import code.name.monkey.retromusic.misc.WrappedAsyncTaskLoader
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
|
@ -69,10 +64,12 @@ import com.afollestad.materialcab.attached.AttachedCab
|
||||||
import com.afollestad.materialcab.attached.destroy
|
import com.afollestad.materialcab.attached.destroy
|
||||||
import com.afollestad.materialcab.attached.isActive
|
import com.afollestad.materialcab.attached.isActive
|
||||||
import com.afollestad.materialcab.createCab
|
import com.afollestad.materialcab.createCab
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import com.google.android.material.shape.MaterialShapeDrawable
|
import com.google.android.material.shape.MaterialShapeDrawable
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.google.android.material.transition.MaterialFadeThrough
|
import com.google.android.material.transition.MaterialFadeThrough
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileFilter
|
import java.io.FileFilter
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
@ -101,6 +98,7 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
_binding = FragmentFolderBinding.bind(view)
|
_binding = FragmentFolderBinding.bind(view)
|
||||||
|
|
||||||
|
setHasOptionsMenu(true)
|
||||||
mainActivity.addMusicServiceEventListener(libraryViewModel)
|
mainActivity.addMusicServiceEventListener(libraryViewModel)
|
||||||
mainActivity.setSupportActionBar(binding.toolbar)
|
mainActivity.setSupportActionBar(binding.toolbar)
|
||||||
mainActivity.supportActionBar?.title = null
|
mainActivity.supportActionBar?.title = null
|
||||||
|
@ -185,23 +183,20 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
||||||
popupMenu.setOnMenuItemClickListener { item: MenuItem ->
|
popupMenu.setOnMenuItemClickListener { item: MenuItem ->
|
||||||
when (val itemId = item.itemId) {
|
when (val itemId = item.itemId) {
|
||||||
R.id.action_play_next, R.id.action_add_to_current_playing, R.id.action_add_to_playlist, R.id.action_delete_from_device -> {
|
R.id.action_play_next, R.id.action_add_to_current_playing, R.id.action_add_to_playlist, R.id.action_delete_from_device -> {
|
||||||
ListSongsAsyncTask(
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
activity,
|
listSongs(
|
||||||
null,
|
requireContext(),
|
||||||
object : OnSongsListedCallback {
|
toList(file),
|
||||||
override fun onSongsListed(songs: List<Song>, extra: Any?) {
|
AUDIO_FILE_FILTER,
|
||||||
if (songs.isNotEmpty()) {
|
fileComparator
|
||||||
SongsMenuHelper.handleMenuClick(
|
) { songs ->
|
||||||
requireActivity(), songs, itemId
|
if (songs.isNotEmpty()) {
|
||||||
)
|
SongsMenuHelper.handleMenuClick(
|
||||||
}
|
requireActivity(), songs, itemId
|
||||||
|
)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.execute(
|
}
|
||||||
ListSongsAsyncTask.LoadingInfo(
|
|
||||||
toList(file), AUDIO_FILE_FILTER, fileComparator
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return@setOnMenuItemClickListener true
|
return@setOnMenuItemClickListener true
|
||||||
}
|
}
|
||||||
R.id.action_add_to_blacklist -> {
|
R.id.action_add_to_blacklist -> {
|
||||||
|
@ -216,14 +211,9 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
||||||
return@setOnMenuItemClickListener true
|
return@setOnMenuItemClickListener true
|
||||||
}
|
}
|
||||||
R.id.action_scan -> {
|
R.id.action_scan -> {
|
||||||
ListPathsAsyncTask(
|
lifecycleScope.launch {
|
||||||
activity,
|
listPaths(file, AUDIO_FILE_FILTER) { paths -> scanPaths(paths) }
|
||||||
object : OnPathsListedCallback {
|
}
|
||||||
override fun onPathsListed(paths: Array<String?>) {
|
|
||||||
scanPaths(paths)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.execute(ListPathsAsyncTask.LoadingInfo(file, AUDIO_FILE_FILTER))
|
|
||||||
return@setOnMenuItemClickListener true
|
return@setOnMenuItemClickListener true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,32 +224,26 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
||||||
popupMenu.setOnMenuItemClickListener { item: MenuItem ->
|
popupMenu.setOnMenuItemClickListener { item: MenuItem ->
|
||||||
when (val itemId = item.itemId) {
|
when (val itemId = item.itemId) {
|
||||||
R.id.action_play_next, R.id.action_add_to_current_playing, R.id.action_add_to_playlist, R.id.action_go_to_album, R.id.action_go_to_artist, R.id.action_share, R.id.action_tag_editor, R.id.action_details, R.id.action_set_as_ringtone, R.id.action_delete_from_device -> {
|
R.id.action_play_next, R.id.action_add_to_current_playing, R.id.action_add_to_playlist, R.id.action_go_to_album, R.id.action_go_to_artist, R.id.action_share, R.id.action_tag_editor, R.id.action_details, R.id.action_set_as_ringtone, R.id.action_delete_from_device -> {
|
||||||
ListSongsAsyncTask(
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
activity,
|
listSongs(
|
||||||
null,
|
requireContext(),
|
||||||
object : OnSongsListedCallback {
|
toList(file),
|
||||||
override fun onSongsListed(songs: List<Song>, extra: Any?) {
|
AUDIO_FILE_FILTER,
|
||||||
handleMenuClick(
|
fileComparator
|
||||||
requireActivity(), songs[0], itemId
|
) { songs ->
|
||||||
|
if (songs.isNotEmpty()) {
|
||||||
|
SongsMenuHelper.handleMenuClick(
|
||||||
|
requireActivity(), songs, itemId
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.execute(
|
}
|
||||||
ListSongsAsyncTask.LoadingInfo(
|
|
||||||
toList(file), AUDIO_FILE_FILTER, fileComparator
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return@setOnMenuItemClickListener true
|
return@setOnMenuItemClickListener true
|
||||||
}
|
}
|
||||||
R.id.action_scan -> {
|
R.id.action_scan -> {
|
||||||
ListPathsAsyncTask(
|
lifecycleScope.launch {
|
||||||
activity,
|
listPaths(file, AUDIO_FILE_FILTER) { paths -> scanPaths(paths) }
|
||||||
object : OnPathsListedCallback {
|
}
|
||||||
override fun onPathsListed(paths: Array<String?>) {
|
|
||||||
scanPaths(paths)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.execute(ListPathsAsyncTask.LoadingInfo(file, AUDIO_FILE_FILTER))
|
|
||||||
return@setOnMenuItemClickListener true
|
return@setOnMenuItemClickListener true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,16 +262,17 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
||||||
val fileFilter = FileFilter { pathname: File ->
|
val fileFilter = FileFilter { pathname: File ->
|
||||||
!pathname.isDirectory && AUDIO_FILE_FILTER.accept(pathname)
|
!pathname.isDirectory && AUDIO_FILE_FILTER.accept(pathname)
|
||||||
}
|
}
|
||||||
ListSongsAsyncTask(
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
activity,
|
listSongs(
|
||||||
mFile,
|
requireContext(),
|
||||||
object : OnSongsListedCallback {
|
toList(mFile.parentFile),
|
||||||
override fun onSongsListed(songs: List<Song>, extra: Any?) {
|
fileFilter,
|
||||||
val file1 = extra as File
|
fileComparator
|
||||||
|
) { songs ->
|
||||||
|
if (songs.isNotEmpty()) {
|
||||||
var startIndex = -1
|
var startIndex = -1
|
||||||
for (i in songs.indices) {
|
for (i in songs.indices) {
|
||||||
if (file1
|
if (mFile.path
|
||||||
.path
|
|
||||||
== songs[i].data
|
== songs[i].data
|
||||||
) { // path is already canonical here
|
) { // path is already canonical here
|
||||||
startIndex = i
|
startIndex = i
|
||||||
|
@ -299,39 +284,29 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
||||||
} else {
|
} else {
|
||||||
Snackbar.make(
|
Snackbar.make(
|
||||||
mainActivity.slidingPanel,
|
mainActivity.slidingPanel,
|
||||||
Html.fromHtml(
|
String.format(
|
||||||
String.format(
|
getString(R.string.not_listed_in_media_store), mFile.name
|
||||||
getString(R.string.not_listed_in_media_store), file1.name
|
|
||||||
)
|
).parseAsHtml(),
|
||||||
),
|
|
||||||
Snackbar.LENGTH_LONG
|
Snackbar.LENGTH_LONG
|
||||||
)
|
)
|
||||||
.setAction(
|
.setAction(
|
||||||
R.string.action_scan
|
R.string.action_scan
|
||||||
) {
|
) {
|
||||||
ListPathsAsyncTask(
|
lifecycleScope.launch {
|
||||||
requireActivity(),
|
listPaths(mFile, AUDIO_FILE_FILTER) { paths ->
|
||||||
object : OnPathsListedCallback {
|
scanPaths(
|
||||||
override fun onPathsListed(paths: Array<String?>) {
|
paths
|
||||||
scanPaths(paths)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.execute(
|
|
||||||
ListPathsAsyncTask.LoadingInfo(
|
|
||||||
file1, AUDIO_FILE_FILTER
|
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.setActionTextColor(accentColor(requireActivity()))
|
.setActionTextColor(accentColor(requireActivity()))
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.execute(
|
}
|
||||||
ListSongsAsyncTask.LoadingInfo(
|
|
||||||
toList(mFile.parentFile), fileFilter, fileComparator
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,19 +320,16 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
||||||
|
|
||||||
override fun onMultipleItemAction(item: MenuItem, files: ArrayList<File>) {
|
override fun onMultipleItemAction(item: MenuItem, files: ArrayList<File>) {
|
||||||
val itemId = item.itemId
|
val itemId = item.itemId
|
||||||
ListSongsAsyncTask(
|
|
||||||
activity,
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
null,
|
listSongs(requireContext(), files, AUDIO_FILE_FILTER, fileComparator) { songs ->
|
||||||
object : OnSongsListedCallback {
|
if (songs.isNotEmpty()) {
|
||||||
override fun onSongsListed(songs: List<Song>, extra: Any?) {
|
|
||||||
SongsMenuHelper.handleMenuClick(
|
SongsMenuHelper.handleMenuClick(
|
||||||
requireActivity(),
|
requireActivity(), songs, itemId
|
||||||
songs,
|
|
||||||
itemId
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.execute(ListSongsAsyncTask.LoadingInfo(files, AUDIO_FILE_FILTER, fileComparator))
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||||
|
@ -397,14 +369,9 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
||||||
R.id.action_scan -> {
|
R.id.action_scan -> {
|
||||||
val crumb = activeCrumb
|
val crumb = activeCrumb
|
||||||
if (crumb != null) {
|
if (crumb != null) {
|
||||||
ListPathsAsyncTask(
|
lifecycleScope.launch {
|
||||||
activity,
|
listPaths(crumb.file, AUDIO_FILE_FILTER) { paths -> scanPaths(paths) }
|
||||||
object : OnPathsListedCallback {
|
}
|
||||||
override fun onPathsListed(paths: Array<String?>) {
|
|
||||||
scanPaths(paths)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.execute(ListPathsAsyncTask.LoadingInfo(crumb.file, AUDIO_FILE_FILTER))
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -557,69 +524,32 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
||||||
_binding = null
|
_binding = null
|
||||||
}
|
}
|
||||||
|
|
||||||
class ListPathsAsyncTask(context: Context?, callback: OnPathsListedCallback) :
|
private suspend fun listPaths(
|
||||||
ListingFilesDialogAsyncTask<ListPathsAsyncTask.LoadingInfo, String?, Array<String?>>(
|
file: File,
|
||||||
context
|
fileFilter: FileFilter,
|
||||||
) {
|
doOnPathListed: (paths: Array<String?>) -> Unit
|
||||||
private val onPathsListedCallbackWeakReference: WeakReference<OnPathsListedCallback> =
|
) {
|
||||||
WeakReference(callback)
|
val paths = try {
|
||||||
|
val paths: Array<String?>
|
||||||
override fun doInBackground(vararg params: LoadingInfo): Array<String?> {
|
if (file.isDirectory) {
|
||||||
return try {
|
val files = FileUtil.listFilesDeep(file, fileFilter)
|
||||||
if (isCancelled || checkCallbackReference() == null) {
|
paths = arrayOfNulls(files.size)
|
||||||
return arrayOf()
|
for (i in files.indices) {
|
||||||
|
val f = files[i]
|
||||||
|
paths[i] = FileUtil.safeGetCanonicalPath(f)
|
||||||
}
|
}
|
||||||
val info = params[0]
|
} else {
|
||||||
val paths: Array<String?>
|
paths = arrayOfNulls(1)
|
||||||
if (info.file.isDirectory) {
|
paths[0] = file.path
|
||||||
val files = FileUtil.listFilesDeep(info.file, info.fileFilter)
|
|
||||||
if (isCancelled || checkCallbackReference() == null) {
|
|
||||||
return arrayOf()
|
|
||||||
}
|
|
||||||
paths = arrayOfNulls(files.size)
|
|
||||||
for (i in files.indices) {
|
|
||||||
val f = files[i]
|
|
||||||
paths[i] = FileUtil.safeGetCanonicalPath(f)
|
|
||||||
if (isCancelled || checkCallbackReference() == null) {
|
|
||||||
return arrayOf()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
paths = arrayOfNulls(1)
|
|
||||||
paths[0] = info.file.path
|
|
||||||
}
|
|
||||||
paths
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
cancel(false)
|
|
||||||
arrayOf()
|
|
||||||
}
|
}
|
||||||
|
paths
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
arrayOf()
|
||||||
}
|
}
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
override fun onPostExecute(paths: Array<String?>) {
|
doOnPathListed(paths)
|
||||||
super.onPostExecute(paths)
|
|
||||||
checkCallbackReference()?.onPathsListed(paths)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPreExecute() {
|
|
||||||
super.onPreExecute()
|
|
||||||
checkCallbackReference()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkCallbackReference(): OnPathsListedCallback? {
|
|
||||||
val callback = onPathsListedCallbackWeakReference.get()
|
|
||||||
if (callback == null) {
|
|
||||||
cancel(false)
|
|
||||||
}
|
|
||||||
return callback
|
|
||||||
}
|
|
||||||
|
|
||||||
interface OnPathsListedCallback {
|
|
||||||
fun onPathsListed(paths: Array<String?>)
|
|
||||||
}
|
|
||||||
|
|
||||||
class LoadingInfo(val file: File, val fileFilter: FileFilter)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AsyncFileLoader(foldersFragment: FoldersFragment) :
|
private class AsyncFileLoader(foldersFragment: FoldersFragment) :
|
||||||
|
@ -647,87 +577,25 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
||||||
LinkedList()
|
LinkedList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private open class ListSongsAsyncTask(
|
suspend fun listSongs(
|
||||||
context: Context?,
|
context: Context,
|
||||||
private val extra: Any?,
|
files: List<File>,
|
||||||
callback: OnSongsListedCallback
|
fileFilter: FileFilter,
|
||||||
) : ListingFilesDialogAsyncTask<ListSongsAsyncTask.LoadingInfo, Void, List<Song>>(context) {
|
fileComparator: Comparator<File>,
|
||||||
private val callbackWeakReference = WeakReference(callback)
|
doOnSongsListed: (songs: List<Song>) -> Unit
|
||||||
private val contextWeakReference = WeakReference(context)
|
) {
|
||||||
override fun doInBackground(vararg params: LoadingInfo): List<Song> {
|
val songs = try {
|
||||||
return try {
|
val fileList = FileUtil.listFilesDeep(files, fileFilter)
|
||||||
val info = params[0]
|
Collections.sort(fileList, fileComparator)
|
||||||
val files = FileUtil.listFilesDeep(info.files, info.fileFilter)
|
FileUtil.matchFilesWithMediaStore(context, fileList)
|
||||||
if (isCancelled || checkContextReference() == null || checkCallbackReference() == null) {
|
} catch (e: Exception) {
|
||||||
return emptyList()
|
e.printStackTrace()
|
||||||
}
|
emptyList()
|
||||||
Collections.sort(files, info.fileComparator)
|
|
||||||
val context = checkContextReference()
|
|
||||||
if (isCancelled || context == null || checkCallbackReference() == null) {
|
|
||||||
emptyList()
|
|
||||||
} else FileUtil.matchFilesWithMediaStore(context, files)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
cancel(false)
|
|
||||||
emptyList()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
override fun onPostExecute(songs: List<Song>) {
|
doOnSongsListed(songs)
|
||||||
super.onPostExecute(songs)
|
|
||||||
checkCallbackReference()?.onSongsListed(songs, extra)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPreExecute() {
|
|
||||||
super.onPreExecute()
|
|
||||||
checkCallbackReference()
|
|
||||||
checkContextReference()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkCallbackReference(): OnSongsListedCallback? {
|
|
||||||
val callback = callbackWeakReference.get()
|
|
||||||
if (callback == null) {
|
|
||||||
cancel(false)
|
|
||||||
}
|
|
||||||
return callback
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkContextReference(): Context? {
|
|
||||||
val context = contextWeakReference.get()
|
|
||||||
if (context == null) {
|
|
||||||
cancel(false)
|
|
||||||
}
|
|
||||||
return context
|
|
||||||
}
|
|
||||||
|
|
||||||
interface OnSongsListedCallback {
|
|
||||||
fun onSongsListed(songs: List<Song>, extra: Any?)
|
|
||||||
}
|
|
||||||
|
|
||||||
class LoadingInfo(
|
|
||||||
val files: List<File>,
|
|
||||||
val fileFilter: FileFilter,
|
|
||||||
val fileComparator: Comparator<File>
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class ListingFilesDialogAsyncTask<Params, Progress, Result> internal constructor(
|
|
||||||
context: Context?
|
|
||||||
) :
|
|
||||||
DialogAsyncTask<Params, Progress, Result>(context) {
|
|
||||||
|
|
||||||
override fun createDialog(context: Context): Dialog {
|
|
||||||
return MaterialAlertDialogBuilder(context)
|
|
||||||
.setTitle(R.string.listing_files)
|
|
||||||
.setCancelable(false)
|
|
||||||
.setView(R.layout.loading)
|
|
||||||
.setOnCancelListener { cancel(false) }
|
|
||||||
.setOnDismissListener { cancel(false) }
|
|
||||||
.create()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -768,7 +636,11 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
||||||
(!file.isHidden
|
(!file.isHidden
|
||||||
&& (file.isDirectory
|
&& (file.isDirectory
|
||||||
|| FileUtil.fileIsMimeType(file, "audio/*", MimeTypeMap.getSingleton())
|
|| FileUtil.fileIsMimeType(file, "audio/*", MimeTypeMap.getSingleton())
|
||||||
|| FileUtil.fileIsMimeType(file, "application/opus", MimeTypeMap.getSingleton())
|
|| FileUtil.fileIsMimeType(
|
||||||
|
file,
|
||||||
|
"application/opus",
|
||||||
|
MimeTypeMap.getSingleton()
|
||||||
|
)
|
||||||
|| FileUtil.fileIsMimeType(
|
|| FileUtil.fileIsMimeType(
|
||||||
file,
|
file,
|
||||||
"application/ogg",
|
"application/ogg",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue