PlayerAndroid/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt

290 lines
10 KiB
Kotlin
Raw Normal View History

2019-04-20 05:29:45 +00:00
package code.name.monkey.retromusic.fragments.base
2018-11-30 01:06:16 +00:00
import android.annotation.SuppressLint
import android.content.ContentUris
import android.content.Context
import android.content.Intent
import android.media.MediaMetadataRetriever
import android.os.AsyncTask
2019-08-05 08:43:12 +00:00
import android.os.Build
2018-11-30 01:06:16 +00:00
import android.os.Bundle
import android.provider.MediaStore
2019-03-25 12:43:43 +00:00
import android.text.TextUtils
2018-11-30 01:06:16 +00:00
import android.view.MenuItem
import android.view.View
import android.widget.Toast
import androidx.appcompat.widget.Toolbar
import code.name.monkey.retromusic.R
2019-07-31 16:42:19 +00:00
import code.name.monkey.retromusic.activities.tageditor.AbsTagEditorActivity
import code.name.monkey.retromusic.activities.tageditor.SongTagEditorActivity
import code.name.monkey.retromusic.dialogs.*
2019-08-05 08:43:12 +00:00
import code.name.monkey.retromusic.extensions.hide
2019-07-31 16:42:19 +00:00
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
2018-11-30 01:06:16 +00:00
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.interfaces.PaletteColorHolder
import code.name.monkey.retromusic.model.Song
2019-03-25 12:43:43 +00:00
import code.name.monkey.retromusic.model.lyrics.Lyrics
import code.name.monkey.retromusic.util.*
import kotlinx.android.synthetic.main.shadow_statusbar_toolbar.*
2019-03-25 12:43:43 +00:00
import java.io.FileNotFoundException
2019-02-23 17:39:02 +00:00
2019-08-02 18:34:18 +00:00
abstract class AbsPlayerFragment : AbsMusicServiceFragment(),
2020-01-06 18:07:02 +00:00
Toolbar.OnMenuItemClickListener,
PaletteColorHolder,
PlayerAlbumCoverFragment.Callbacks {
2019-08-02 18:34:18 +00:00
2018-11-30 01:06:16 +00:00
var callbacks: Callbacks? = null
private set
private var updateIsFavoriteTask: AsyncTask<*, *, *>? = null
2019-03-25 12:43:43 +00:00
private var updateLyricsAsyncTask: AsyncTask<*, *, *>? = null
private var playerAlbumCoverFragment: PlayerAlbumCoverFragment? = null
2018-11-30 01:06:16 +00:00
2019-08-02 18:34:18 +00:00
override fun onAttach(
2020-01-06 18:07:02 +00:00
context: Context
2019-08-02 18:34:18 +00:00
) {
2018-11-30 01:06:16 +00:00
super.onAttach(context)
try {
callbacks = context as Callbacks?
} catch (e: ClassCastException) {
2019-03-25 12:43:43 +00:00
throw RuntimeException(context.javaClass.simpleName + " must implement " + Callbacks::class.java.simpleName)
2018-11-30 01:06:16 +00:00
}
}
override fun onDetach() {
super.onDetach()
callbacks = null
}
2019-08-02 18:34:18 +00:00
override fun onMenuItemClick(
2020-01-06 18:07:02 +00:00
item: MenuItem
2019-08-02 18:34:18 +00:00
): Boolean {
2018-11-30 01:06:16 +00:00
val song = MusicPlayerRemote.currentSong
when (item.itemId) {
R.id.action_toggle_favorite -> {
toggleFavorite(song)
return true
}
R.id.action_share -> {
2020-02-02 12:44:16 +00:00
SongShareDialog.create(song).show(childFragmentManager, "SHARE_SONG")
2018-11-30 01:06:16 +00:00
return true
}
2020-03-01 08:54:39 +00:00
R.id.action_go_to_drive_mode -> {
NavigationUtil.gotoDriveMode(requireActivity())
return true
}
2018-11-30 01:06:16 +00:00
R.id.action_delete_from_device -> {
2020-02-02 12:44:16 +00:00
DeleteSongsDialog.create(song).show(childFragmentManager, "DELETE_SONGS")
2018-11-30 01:06:16 +00:00
return true
}
R.id.action_add_to_playlist -> {
2020-02-02 12:44:16 +00:00
AddToPlaylistDialog.create(song).show(childFragmentManager, "ADD_PLAYLIST")
2018-11-30 01:06:16 +00:00
return true
}
R.id.action_clear_playing_queue -> {
MusicPlayerRemote.clearQueue()
return true
}
R.id.action_save_playing_queue -> {
2020-04-25 07:27:05 +00:00
CreatePlaylistDialog.create(ArrayList(MusicPlayerRemote.playingQueue))
2020-02-02 12:44:16 +00:00
.show(childFragmentManager, "ADD_TO_PLAYLIST")
2018-11-30 01:06:16 +00:00
return true
}
R.id.action_tag_editor -> {
val intent = Intent(activity, SongTagEditorActivity::class.java)
intent.putExtra(AbsTagEditorActivity.EXTRA_ID, song.id)
startActivity(intent)
return true
}
R.id.action_details -> {
2020-02-02 12:44:16 +00:00
SongDetailDialog.create(song).show(childFragmentManager, "SONG_DETAIL")
2018-11-30 01:06:16 +00:00
return true
}
R.id.action_go_to_album -> {
2019-07-31 16:42:19 +00:00
NavigationUtil.goToAlbum(requireActivity(), song.albumId)
2018-11-30 01:06:16 +00:00
return true
}
R.id.action_go_to_artist -> {
2019-07-31 16:42:19 +00:00
NavigationUtil.goToArtist(requireActivity(), song.artistId)
2018-11-30 01:06:16 +00:00
return true
}
R.id.now_playing -> {
2019-07-31 16:42:19 +00:00
NavigationUtil.goToPlayingQueue(requireActivity())
2018-11-30 01:06:16 +00:00
return true
}
R.id.action_show_lyrics -> {
2019-10-28 17:08:09 +00:00
NavigationUtil.goToLyrics(requireActivity())
2018-11-30 01:06:16 +00:00
return true
}
R.id.action_equalizer -> {
2019-07-31 16:42:19 +00:00
NavigationUtil.openEqualizer(requireActivity())
2018-11-30 01:06:16 +00:00
return true
}
R.id.action_sleep_timer -> {
2020-03-01 12:05:43 +00:00
SleepTimerDialog().show(parentFragmentManager, TAG)
2018-11-30 01:06:16 +00:00
return true
}
R.id.action_set_as_ringtone -> {
2019-07-31 16:42:19 +00:00
if (RingtoneManager.requiresDialog(requireActivity())) {
RingtoneManager.getDialog(requireActivity())
2019-04-05 05:49:40 +00:00
}
2019-07-31 16:42:19 +00:00
val ringtoneManager = RingtoneManager(requireActivity())
2019-04-05 05:49:40 +00:00
ringtoneManager.setRingtone(song)
2018-11-30 01:06:16 +00:00
return true
}
R.id.action_go_to_genre -> {
val retriever = MediaMetadataRetriever()
2020-01-06 18:07:02 +00:00
val trackUri =
ContentUris.withAppendedId(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
song.id.toLong()
)
2018-11-30 01:06:16 +00:00
retriever.setDataSource(activity, trackUri)
var genre: String? =
retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE)
2018-11-30 01:06:16 +00:00
if (genre == null) {
genre = "Not Specified"
}
Toast.makeText(context, genre, Toast.LENGTH_SHORT).show()
return true
}
}
return false
}
protected open fun toggleFavorite(song: Song) {
2019-07-31 16:42:19 +00:00
MusicUtil.toggleFavorite(requireActivity(), song)
2018-11-30 01:06:16 +00:00
}
2020-01-06 18:07:02 +00:00
abstract fun playerToolbar(): Toolbar?
2018-11-30 01:06:16 +00:00
abstract fun onShow()
abstract fun onHide()
abstract fun onBackPressed(): Boolean
abstract fun toolbarIconColor(): Int
override fun onServiceConnected() {
updateIsFavorite()
2019-03-25 12:43:43 +00:00
updateLyrics()
2018-11-30 01:06:16 +00:00
}
override fun onPlayingMetaChanged() {
updateIsFavorite()
2019-03-25 12:43:43 +00:00
updateLyrics()
2018-11-30 01:06:16 +00:00
}
override fun onDestroyView() {
if (updateIsFavoriteTask != null && !updateIsFavoriteTask!!.isCancelled) {
updateIsFavoriteTask!!.cancel(true)
}
2019-03-25 12:43:43 +00:00
if (updateLyricsAsyncTask != null && !updateLyricsAsyncTask!!.isCancelled) {
updateLyricsAsyncTask!!.cancel(true)
}
2018-11-30 01:06:16 +00:00
super.onDestroyView()
}
@SuppressLint("StaticFieldLeak")
fun updateIsFavorite() {
if (updateIsFavoriteTask != null) {
updateIsFavoriteTask!!.cancel(false)
}
updateIsFavoriteTask = object : AsyncTask<Song, Void, Boolean>() {
2019-08-02 18:34:18 +00:00
override fun doInBackground(vararg params: Song): Boolean {
return MusicUtil.isFavorite(requireActivity(), params[0])
2018-11-30 01:06:16 +00:00
}
2019-08-02 18:34:18 +00:00
override fun onPostExecute(isFavorite: Boolean) {
val res = if (isFavorite)
R.drawable.ic_favorite_white_24dp
else
R.drawable.ic_favorite_border_white_24dp
val drawable =
RetroUtil.getTintedVectorDrawable(requireContext(), res, toolbarIconColor())
2020-01-06 18:07:02 +00:00
if (playerToolbar() != null && playerToolbar()!!.menu.findItem(R.id.action_toggle_favorite) != null)
playerToolbar()!!.menu.findItem(R.id.action_toggle_favorite).setIcon(drawable)
.title =
if (isFavorite) getString(R.string.action_remove_from_favorites) else getString(
R.string.action_add_to_favorites
)
2018-11-30 01:06:16 +00:00
}
}.execute(MusicPlayerRemote.currentSong)
}
2019-03-25 12:43:43 +00:00
@SuppressLint("StaticFieldLeak")
private fun updateLyrics() {
if (updateLyricsAsyncTask != null) updateLyricsAsyncTask!!.cancel(false)
updateLyricsAsyncTask = object : AsyncTask<Song, Void, Lyrics>() {
override fun onPreExecute() {
super.onPreExecute()
setLyrics(null)
}
override fun doInBackground(vararg params: Song): Lyrics? {
try {
var data: String? =
LyricUtil.getStringFromFile(params[0].title, params[0].artistName)
2019-03-25 12:43:43 +00:00
return if (TextUtils.isEmpty(data)) {
data = MusicUtil.getLyrics(params[0])
return if (TextUtils.isEmpty(data)) {
null
} else {
Lyrics.parse(params[0], data)
}
} else Lyrics.parse(params[0], data!!)
} catch (err: FileNotFoundException) {
return null
}
}
override fun onPostExecute(l: Lyrics?) {
setLyrics(l)
}
override fun onCancelled(s: Lyrics?) {
onPostExecute(null)
}
}.execute(MusicPlayerRemote.currentSong)
}
open fun setLyrics(l: Lyrics?) {
}
2018-11-30 01:06:16 +00:00
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (PreferenceUtilKT.isFullScreenMode &&
2020-01-06 18:07:02 +00:00
view.findViewById<View>(R.id.status_bar) != null
) {
2019-02-23 17:39:02 +00:00
view.findViewById<View>(R.id.status_bar).visibility = View.GONE
2018-11-30 01:06:16 +00:00
}
2020-01-06 18:07:02 +00:00
playerAlbumCoverFragment =
childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment?
2019-03-25 12:43:43 +00:00
playerAlbumCoverFragment?.setCallbacks(this)
2019-08-05 08:43:12 +00:00
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
2019-08-05 16:13:44 +00:00
statusBarShadow?.hide()
2018-11-30 01:06:16 +00:00
}
interface Callbacks {
fun onPaletteColorChanged()
}
companion object {
val TAG: String = AbsPlayerFragment::class.java.simpleName
2019-03-25 12:43:43 +00:00
const val VISIBILITY_ANIM_DURATION: Long = 300
2018-11-30 01:06:16 +00:00
}
2019-02-23 17:39:02 +00:00
protected fun getUpNextAndQueueTime(): String {
val duration = MusicPlayerRemote.getQueueDurationMillis(MusicPlayerRemote.position)
return MusicUtil.buildInfoString(
2020-01-06 18:07:02 +00:00
resources.getString(R.string.up_next),
MusicUtil.getReadableDurationString(duration)
2019-02-23 17:39:02 +00:00
)
}
2018-11-30 01:06:16 +00:00
}