|
@ -14,8 +14,8 @@ android {
|
|||
vectorDrawables.useSupportLibrary = true
|
||||
|
||||
applicationId "code.name.monkey.retromusic"
|
||||
versionCode 10551
|
||||
versionName '5.5.0'
|
||||
versionCode 10555
|
||||
versionName '5.6.1'
|
||||
|
||||
buildConfigField("String", "GOOGLE_PLAY_LICENSING_KEY", "\"${getProperty(getProperties('../public.properties'), 'GOOGLE_PLAY_LICENSE_KEY')}\"")
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ dependencies {
|
|||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
|
||||
def kotlin_coroutines_version = '1.6.0-RC3'
|
||||
def kotlin_coroutines_version = '1.6.0'
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
|
||||
|
||||
|
|
7
app/proguard-rules.pro
vendored
|
@ -34,11 +34,16 @@
|
|||
|
||||
# Glide
|
||||
-keep public class * implements com.bumptech.glide.module.GlideModule
|
||||
-keep public class * extends com.bumptech.glide.module.AppGlideModule
|
||||
-keep class * extends com.bumptech.glide.module.AppGlideModule {
|
||||
<init>(...);
|
||||
}
|
||||
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
||||
**[] $VALUES;
|
||||
public *;
|
||||
}
|
||||
-keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder {
|
||||
*** rewind();
|
||||
}
|
||||
|
||||
# OkHttp
|
||||
-keepattributes Signature
|
||||
|
|
|
@ -63,8 +63,22 @@
|
|||
|
||||
<body>
|
||||
<div>
|
||||
<h5>December 24, 2021</h5>
|
||||
<h2>v5.5.0<span class="tag"><i>Beta</i></span></h2>
|
||||
<h5>December 28, 2021</h5>
|
||||
<h2>v5.6.1<span class="tag"><i>Beta</i></span></h2>
|
||||
<h3>Fixed</h3>
|
||||
<ul>
|
||||
<li>Fixed artist covers not updating and showing album cover images.</li>
|
||||
<li>Fixed FAB's not visible (Shuffle, Save, etc.)</li>
|
||||
<li>Fixed a crash when a Song is deleted in Artist Details</li>
|
||||
<li>Fixed Snowfall effect</li>
|
||||
<li>Fixed empty notification when queue is cleared</li>
|
||||
<li>Fixed Fit theme button colors</li>
|
||||
<li>Show Dismiss button in Notification only on A12</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h5>December 25, 2021</h5>
|
||||
<h2>v5.6.0<span class="tag"><i>Beta</i></span></h2>
|
||||
<h3>What's New</h3>
|
||||
<ul>
|
||||
<li>Added Artwork editing for songs</li>
|
||||
|
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 17 KiB |
|
@ -25,7 +25,10 @@ import android.view.ViewTreeObserver
|
|||
import android.view.animation.PathInterpolator
|
||||
import android.widget.FrameLayout
|
||||
import androidx.core.animation.doOnEnd
|
||||
import androidx.core.view.*
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.commit
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
|
@ -143,8 +146,11 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
setupSlidingUpPanel()
|
||||
setupBottomSheet()
|
||||
updateColor()
|
||||
if (!PreferenceUtil.materialYou) {
|
||||
binding.slidingPanel.backgroundTintList = ColorStateList.valueOf(darkAccentColor())
|
||||
bottomNavigationView.backgroundTintList = ColorStateList.valueOf(darkAccentColor())
|
||||
}
|
||||
|
||||
navigationBarColor = surfaceColor()
|
||||
}
|
||||
|
||||
|
@ -395,12 +401,12 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
bottomSheetBehavior.peekHeight = -windowInsets.safeGetBottomInsets()
|
||||
bottomSheetBehavior.state = STATE_COLLAPSED
|
||||
libraryViewModel.setFabMargin(if (isBottomNavVisible) dip(R.dimen.bottom_nav_height) else 0)
|
||||
ViewCompat.setElevation(binding.slidingPanel, 0f)
|
||||
ViewCompat.setElevation(binding.bottomNavigationView, 10f)
|
||||
binding.slidingPanel.elevation = 0F
|
||||
binding.bottomNavigationView.elevation = 10F
|
||||
} else {
|
||||
if (MusicPlayerRemote.playingQueue.isNotEmpty()) {
|
||||
ViewCompat.setElevation(binding.slidingPanel, 10f)
|
||||
ViewCompat.setElevation(binding.bottomNavigationView, 10f)
|
||||
binding.slidingPanel.elevation = 0F
|
||||
binding.bottomNavigationView.elevation = 10F
|
||||
if (isBottomNavVisible) {
|
||||
println("List")
|
||||
if (animate) {
|
||||
|
|
|
@ -24,6 +24,7 @@ import androidx.fragment.app.Fragment
|
|||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.activities.MainActivity
|
||||
import code.name.monkey.retromusic.fragments.AlbumCoverStyle
|
||||
import code.name.monkey.retromusic.fragments.NowPlayingScreen.*
|
||||
import code.name.monkey.retromusic.fragments.base.goToLyrics
|
||||
|
@ -35,6 +36,7 @@ import code.name.monkey.retromusic.model.Song
|
|||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -89,6 +91,7 @@ class AlbumCoverPagerAdapter(
|
|||
private lateinit var song: Song
|
||||
private var colorReceiver: ColorReceiver? = null
|
||||
private var request: Int = 0
|
||||
private val mainActivity get() = activity as MainActivity
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -105,6 +108,11 @@ class AlbumCoverPagerAdapter(
|
|||
val view = inflater.inflate(getLayoutWithPlayerTheme(), container, false)
|
||||
ViewCompat.setTransitionName(view, "lyrics")
|
||||
albumCover = view.findViewById(R.id.player_image)
|
||||
view.setOnClickListener {
|
||||
if (mainActivity.getBottomSheetBehavior().state == STATE_EXPANDED) {
|
||||
showLyricsDialog()
|
||||
}
|
||||
}
|
||||
return view
|
||||
}
|
||||
|
||||
|
@ -140,7 +148,6 @@ class AlbumCoverPagerAdapter(
|
|||
AlbumCoverStyle.Flat -> R.layout.fragment_album_flat_cover
|
||||
AlbumCoverStyle.Circle -> R.layout.fragment_album_circle_cover
|
||||
AlbumCoverStyle.Card -> R.layout.fragment_album_card_cover
|
||||
AlbumCoverStyle.Material -> R.layout.fragment_album_material_cover
|
||||
AlbumCoverStyle.Full -> R.layout.fragment_album_full_cover
|
||||
AlbumCoverStyle.FullCard -> R.layout.fragment_album_full_card_cover
|
||||
}
|
||||
|
|
|
@ -77,6 +77,10 @@ fun Context.colorControlNormal() = resolveColor(android.R.attr.colorControlNorma
|
|||
|
||||
fun Fragment.colorControlNormal() = resolveColor(android.R.attr.colorControlNormal)
|
||||
|
||||
fun Context.colorBackground() = resolveColor(android.R.attr.colorBackground)
|
||||
|
||||
fun Fragment.colorBackground() = resolveColor(android.R.attr.colorBackground)
|
||||
|
||||
fun Context.textColorPrimary() = resolveColor(android.R.attr.textColorPrimary)
|
||||
|
||||
fun Fragment.textColorPrimary() = resolveColor(android.R.attr.textColorPrimary)
|
||||
|
@ -244,9 +248,14 @@ fun Context.getColorCompat(@ColorRes colorRes: Int): Int {
|
|||
|
||||
@ColorInt
|
||||
fun Context.darkAccentColor(): Int {
|
||||
val colorSurfaceVariant = if (surfaceColor().isColorLight) {
|
||||
surfaceColor()
|
||||
} else {
|
||||
surfaceColor().lighterColor
|
||||
}
|
||||
return ColorUtils.blendARGB(
|
||||
accentColor(),
|
||||
surfaceColor(),
|
||||
colorSurfaceVariant,
|
||||
if (surfaceColor().isColorLight) 0.96f else 0.975f
|
||||
)
|
||||
}
|
||||
|
@ -262,3 +271,9 @@ fun Context.darkAccentColorVariant(): Int {
|
|||
|
||||
inline val @receiver:ColorInt Int.isColorLight
|
||||
get() = ColorUtil.isColorLight(this)
|
||||
|
||||
inline val @receiver:ColorInt Int.lighterColor
|
||||
get() = ColorUtil.lightenColor(this)
|
||||
|
||||
inline val @receiver:ColorInt Int.darkerColor
|
||||
get() = ColorUtil.darkenColor(this)
|
|
@ -2,11 +2,12 @@ package code.name.monkey.retromusic.extensions
|
|||
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
|
||||
fun WindowInsetsCompat?.safeGetBottomInsets(): Int {
|
||||
return if (PreferenceUtil.isFullScreenMode) {
|
||||
return 0
|
||||
} else {
|
||||
this?.getInsets(WindowInsetsCompat.Type.systemBars())?.bottom ?: 0
|
||||
this?.getInsets(WindowInsetsCompat.Type.systemBars())?.bottom ?: RetroUtil.getNavigationBarHeight()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,11 +23,10 @@ enum class AlbumCoverStyle(
|
|||
@DrawableRes val drawableResId: Int,
|
||||
val id: Int
|
||||
) {
|
||||
Card(R.string.card, R.drawable.np_blur_card, 4),
|
||||
Card(R.string.card, R.drawable.np_blur_card, 3),
|
||||
Circle(R.string.circular, R.drawable.np_circle, 2),
|
||||
Flat(R.string.flat, R.drawable.np_flat, 1),
|
||||
FullCard(R.string.full_card, R.drawable.np_adaptive, 6),
|
||||
Full(R.string.full, R.drawable.np_full, 5),
|
||||
Material(R.string.material, R.drawable.np_material, 3),
|
||||
FullCard(R.string.full_card, R.drawable.np_adaptive, 5),
|
||||
Full(R.string.full, R.drawable.np_full, 4),
|
||||
Normal(R.string.normal, R.drawable.np_normal, 0),
|
||||
}
|
||||
|
|
|
@ -206,6 +206,7 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
|
||||
private fun showAlbum(album: Album) {
|
||||
if (album.songs.isEmpty()) {
|
||||
findNavController().navigateUp()
|
||||
return
|
||||
}
|
||||
this.album = album
|
||||
|
|
|
@ -141,6 +141,10 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
|
|||
}
|
||||
|
||||
private fun showArtist(artist: Artist) {
|
||||
if (artist.songCount == 0) {
|
||||
findNavController().navigateUp()
|
||||
return
|
||||
}
|
||||
this.artist = artist
|
||||
loadArtistImage(artist)
|
||||
if (RetroUtil.isAllowedToDownloadMetadata(requireContext())) {
|
||||
|
|
|
@ -35,6 +35,7 @@ import code.name.monkey.retromusic.extensions.surfaceColor
|
|||
import code.name.monkey.retromusic.fragments.NowPlayingScreen.*
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMusicServiceFragment
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToLyrics
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
import code.name.monkey.retromusic.lyrics.CoverLrcView
|
||||
|
@ -141,6 +142,9 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe
|
|||
MusicPlayerRemote.resumePlaying()
|
||||
true
|
||||
}
|
||||
setOnClickListener {
|
||||
goToLyrics(requireActivity())
|
||||
}
|
||||
setOnFlingXListener { velocityX ->
|
||||
when {
|
||||
velocityX < 0 -> {
|
||||
|
|
|
@ -128,7 +128,7 @@ class FitPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun setColor(color: MediaNotificationProcessor) {
|
||||
if (ColorUtil.isColorLight(colorControlNormal())) {
|
||||
if (ColorUtil.isColorLight(colorBackground())) {
|
||||
lastPlaybackControlsColor =
|
||||
MaterialValueHelper.getSecondaryTextColor(requireContext(), true)
|
||||
lastDisabledPlaybackControlsColor =
|
||||
|
|
|
@ -21,7 +21,6 @@ import android.graphics.drawable.GradientDrawable
|
|||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.preference.PreferenceManager
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
|
@ -126,13 +125,7 @@ class PlayerFragment : AbsPlayerFragment(R.layout.fragment_player),
|
|||
_binding = FragmentPlayerBinding.bind(view)
|
||||
setUpSubFragments()
|
||||
setUpPlayerToolbar()
|
||||
if (PreferenceUtil.isSnowFalling) {
|
||||
binding.snowfallView.isVisible = true
|
||||
binding.snowfallView.restartFalling()
|
||||
} else {
|
||||
binding.snowfallView.isVisible = false
|
||||
binding.snowfallView.stopFalling()
|
||||
}
|
||||
startOrStopSnow(PreferenceUtil.isSnowFalling)
|
||||
|
||||
PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
.registerOnSharedPreferenceChangeListener(this)
|
||||
|
@ -168,7 +161,13 @@ class PlayerFragment : AbsPlayerFragment(R.layout.fragment_player),
|
|||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||
if (key == SNOWFALL && PreferenceUtil.isSnowFalling) {
|
||||
if (key == SNOWFALL) {
|
||||
startOrStopSnow(PreferenceUtil.isSnowFalling)
|
||||
}
|
||||
}
|
||||
|
||||
private fun startOrStopSnow(isSnowFalling: Boolean) {
|
||||
if (isSnowFalling) {
|
||||
binding.snowfallView.isVisible = true
|
||||
binding.snowfallView.restartFalling()
|
||||
} else {
|
||||
|
|
|
@ -30,6 +30,7 @@ import com.bumptech.glide.load.engine.GlideException
|
|||
import com.bumptech.glide.request.BaseRequestOptions
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.bumptech.glide.request.target.Target.SIZE_ORIGINAL
|
||||
import com.bumptech.glide.request.transition.DrawableCrossFadeFactory
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
import com.bumptech.glide.signature.MediaStoreSignature
|
||||
|
@ -107,6 +108,7 @@ object RetroGlideExtension {
|
|||
.priority(Priority.LOW)
|
||||
.error(DEFAULT_ARTIST_IMAGE)
|
||||
.placeholder(DEFAULT_ARTIST_IMAGE)
|
||||
.override(SIZE_ORIGINAL, SIZE_ORIGINAL)
|
||||
.signature(createSignature(artist))
|
||||
}
|
||||
|
||||
|
|
|
@ -90,11 +90,19 @@ class ArtistImageFetcher(
|
|||
}
|
||||
|
||||
private fun getFallbackAlbumImage(): InputStream? {
|
||||
model.artist.safeGetFirstAlbum().id.let { id->
|
||||
return if (id != -1L) {
|
||||
val imageUri = MusicUtil.getMediaStoreAlbumCoverUri(model.artist.safeGetFirstAlbum().id)
|
||||
return try {
|
||||
try {
|
||||
context.contentResolver.openInputStream(imageUri)
|
||||
} catch (e: FileNotFoundException){
|
||||
null
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
null
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
package code.name.monkey.retromusic.helper
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.annotation.TargetApi
|
||||
import android.app.Activity
|
||||
import android.content.*
|
||||
|
@ -328,6 +329,7 @@ object MusicPlayerRemote : KoinComponent {
|
|||
return false
|
||||
}
|
||||
|
||||
@SuppressLint("StringFormatInvalid")
|
||||
fun playNext(songs: List<Song>): Boolean {
|
||||
if (musicService != null) {
|
||||
if (playingQueue.isNotEmpty()) {
|
||||
|
|
|
@ -169,6 +169,9 @@ class CoverLrcView @JvmOverloads constructor(
|
|||
mCurrentLine = centerLine
|
||||
invalidate()
|
||||
return true
|
||||
} else {
|
||||
callOnClick()
|
||||
return true
|
||||
}
|
||||
}
|
||||
return super.onSingleTapConfirmed(e)
|
||||
|
|
|
@ -24,8 +24,6 @@ import static code.name.monkey.retromusic.ConstantsKt.COLORED_NOTIFICATION;
|
|||
import static code.name.monkey.retromusic.ConstantsKt.CROSS_FADE_DURATION;
|
||||
import static code.name.monkey.retromusic.ConstantsKt.TOGGLE_HEADSET;
|
||||
import static code.name.monkey.retromusic.service.AudioFader.startFadeAnimator;
|
||||
import static code.name.monkey.retromusic.service.notification.PlayingNotification.NOTIFY_MODE_BACKGROUND;
|
||||
import static code.name.monkey.retromusic.service.notification.PlayingNotification.NOTIFY_MODE_FOREGROUND;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
|
@ -101,8 +99,8 @@ import code.name.monkey.retromusic.providers.HistoryStore;
|
|||
import code.name.monkey.retromusic.providers.MusicPlaybackQueueStore;
|
||||
import code.name.monkey.retromusic.providers.SongPlayCountStore;
|
||||
import code.name.monkey.retromusic.service.notification.PlayingNotification;
|
||||
import code.name.monkey.retromusic.service.notification.PlayingNotificationImpl;
|
||||
import code.name.monkey.retromusic.service.notification.PlayingNotificationOreo;
|
||||
import code.name.monkey.retromusic.service.notification.PlayingNotificationClassic;
|
||||
import code.name.monkey.retromusic.service.notification.PlayingNotificationImpl24;
|
||||
import code.name.monkey.retromusic.service.playback.Playback;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.PackageValidator;
|
||||
|
@ -371,7 +369,6 @@ public class MusicService extends MediaBrowserServiceCompat
|
|||
private PowerManager.WakeLock wakeLock;
|
||||
private NotificationManager notificationManager;
|
||||
private boolean isForeground = false;
|
||||
private int notifyMode = NOTIFY_MODE_BACKGROUND;
|
||||
|
||||
private static Bitmap copy(Bitmap bitmap) {
|
||||
Bitmap.Config config = bitmap.getConfig();
|
||||
|
@ -784,9 +781,9 @@ public class MusicService extends MediaBrowserServiceCompat
|
|||
public void initNotification() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
|
||||
&& !PreferenceUtil.INSTANCE.isClassicNotification()) {
|
||||
playingNotification = PlayingNotificationImpl.Companion.from(this, notificationManager, mediaSession);
|
||||
playingNotification = PlayingNotificationImpl24.Companion.from(this, notificationManager, mediaSession);
|
||||
} else {
|
||||
playingNotification = PlayingNotificationOreo.Companion.from(this, notificationManager);
|
||||
playingNotification = PlayingNotificationClassic.Companion.from(this, notificationManager);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1460,16 +1457,20 @@ public class MusicService extends MediaBrowserServiceCompat
|
|||
}
|
||||
|
||||
private Unit startForegroundOrNotify() {
|
||||
int newNotifyMode = isPlaying() ? NOTIFY_MODE_FOREGROUND : NOTIFY_MODE_BACKGROUND;
|
||||
if (playingNotification != null && getCurrentSong().getId() != -1) {
|
||||
boolean isPlaying = isPlaying();
|
||||
|
||||
if (notifyMode != newNotifyMode && newNotifyMode == NOTIFY_MODE_BACKGROUND) {
|
||||
if ((isForeground != isPlaying) && !isPlaying) {
|
||||
// This makes the notification dismissible
|
||||
// We can't call stopForeground(false) on A12 though, which may result in crashes
|
||||
// when we call startForeground after that e.g. when Alarm goes off,
|
||||
if (Build.VERSION.SDK_INT < VERSION_CODES.S) stopForeground(false);
|
||||
if (Build.VERSION.SDK_INT < VERSION_CODES.S) {
|
||||
stopForeground(false);
|
||||
isForeground = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (newNotifyMode == NOTIFY_MODE_FOREGROUND) {
|
||||
if (!isForeground && isPlaying) {
|
||||
// Specify that this is a media service, if supported.
|
||||
if (VersionUtils.hasQ()) {
|
||||
startForeground(
|
||||
|
@ -1487,7 +1488,7 @@ public class MusicService extends MediaBrowserServiceCompat
|
|||
PlayingNotification.NOTIFICATION_ID, playingNotification.build()
|
||||
);
|
||||
}
|
||||
notifyMode = newNotifyMode;
|
||||
}
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,6 @@ abstract class PlayingNotification(context: Context) :
|
|||
const val NOTIFICATION_CONTROLS_SIZE_MULTIPLIER = 1.0f
|
||||
internal const val NOTIFICATION_CHANNEL_ID = "playing_notification"
|
||||
const val NOTIFICATION_ID = 1
|
||||
const val NOTIFY_MODE_FOREGROUND = 1
|
||||
const val NOTIFY_MODE_BACKGROUND = 0
|
||||
|
||||
|
||||
@RequiresApi(26)
|
||||
|
|
|
@ -50,7 +50,7 @@ import com.bumptech.glide.request.transition.Transition
|
|||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
@SuppressLint("RestrictedApi")
|
||||
class PlayingNotificationOreo(
|
||||
class PlayingNotificationClassic(
|
||||
val context: Context
|
||||
) : PlayingNotification(context) {
|
||||
|
||||
|
@ -313,7 +313,7 @@ class PlayingNotificationOreo(
|
|||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
createNotificationChannel(context, notificationManager)
|
||||
}
|
||||
return PlayingNotificationOreo(context)
|
||||
return PlayingNotificationClassic(context)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@ import android.app.PendingIntent
|
|||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Build
|
||||
|
@ -47,7 +48,7 @@ import kotlinx.coroutines.launch
|
|||
import kotlinx.coroutines.withContext
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
class PlayingNotificationImpl(
|
||||
class PlayingNotificationImpl24(
|
||||
val context: Context,
|
||||
mediaSessionToken: MediaSessionCompat.Token
|
||||
) : PlayingNotification(context) {
|
||||
|
@ -91,7 +92,7 @@ class PlayingNotificationImpl(
|
|||
)
|
||||
val dismissAction = NotificationCompat.Action(
|
||||
R.drawable.ic_close,
|
||||
context.getString(R.string.customactivityoncrash_error_activity_error_details_close),
|
||||
context.getString(R.string.action_cancel),
|
||||
retrievePlaybackAction(ACTION_QUIT)
|
||||
)
|
||||
setSmallIcon(R.drawable.ic_notification)
|
||||
|
@ -102,7 +103,9 @@ class PlayingNotificationImpl(
|
|||
addAction(previousAction)
|
||||
addAction(playPauseAction)
|
||||
addAction(nextAction)
|
||||
if (VersionUtils.hasS()) {
|
||||
addAction(dismissAction)
|
||||
}
|
||||
|
||||
setStyle(
|
||||
MediaStyle()
|
||||
|
@ -152,12 +155,20 @@ class PlayingNotificationImpl(
|
|||
|
||||
override fun onLoadFailed(errorDrawable: Drawable?) {
|
||||
super.onLoadFailed(errorDrawable)
|
||||
setLargeIcon(null)
|
||||
setLargeIcon(
|
||||
BitmapFactory.decodeResource(
|
||||
context.resources,
|
||||
R.drawable.default_audio_art
|
||||
)
|
||||
)
|
||||
onUpdate()
|
||||
}
|
||||
|
||||
override fun onLoadCleared(placeholder: Drawable?) {
|
||||
setLargeIcon(null)
|
||||
setLargeIcon(BitmapFactory.decodeResource(
|
||||
context.resources,
|
||||
R.drawable.default_audio_art
|
||||
))
|
||||
onUpdate()
|
||||
}
|
||||
})
|
||||
|
@ -184,23 +195,8 @@ class PlayingNotificationImpl(
|
|||
).build()
|
||||
}
|
||||
|
||||
private fun buildDismissAction(): NotificationCompat.Action {
|
||||
return NotificationCompat.Action.Builder(
|
||||
R.drawable.ic_close,
|
||||
context.getString(R.string.customactivityoncrash_error_activity_error_details_close),
|
||||
retrievePlaybackAction(ACTION_QUIT)
|
||||
).build()
|
||||
}
|
||||
|
||||
override fun setPlaying(isPlaying: Boolean) {
|
||||
mActions[2] = buildPlayAction(isPlaying)
|
||||
// Show dismiss action if we are not playing but only for A12+, as we can't call stopForeground(false)
|
||||
// on A12 which would result in crashes when we call startForeground after that
|
||||
if (!isPlaying) {
|
||||
addAction(buildDismissAction())
|
||||
} else {
|
||||
if (mActions.size == 5) mActions.removeAt(4)
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateFavorite(song: Song, onUpdate: () -> Unit) {
|
||||
|
@ -234,7 +230,7 @@ class PlayingNotificationImpl(
|
|||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
createNotificationChannel(context, notificationManager)
|
||||
}
|
||||
return PlayingNotificationImpl(context, mediaSession.sessionToken)
|
||||
return PlayingNotificationImpl24(context, mediaSession.sessionToken)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="@color/dark_color"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
</vector>
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="@color/window_color"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
</vector>
|
41
app/src/main/res/drawable/ic_launcher_foreground.xml
Normal file
|
@ -0,0 +1,41 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<group android:scaleX="2.25"
|
||||
android:scaleY="2.25"
|
||||
android:translateX="27"
|
||||
android:translateY="27">
|
||||
<path
|
||||
android:pathData="M20.8636,10.3382L6.8454,2.318C5.4474,1.5183 3.7022,2.5177 3.7022,4.1177V20.1576C3.7022,21.7576 5.4499,22.7571 6.8479,21.9572L20.8636,13.9371C22.2623,13.1374 22.2623,11.1379 20.8636,10.3382Z"
|
||||
android:fillColor="#0D0754"/>
|
||||
<path
|
||||
android:pathData="M20.1755,10.3463C18.1822,10.4054 17.9373,11.4297 15.2074,12.2823C13.5363,12.8044 12.142,12.703 10.3899,12.66C8.1888,12.6059 7.7856,12.0888 5.5706,12.0626C4.817,12.0539 4.216,12.0471 3.6998,12.0813V20.1576C3.6992,20.3933 3.7387,20.6275 3.8166,20.8502C4.6788,21.1744 5.7081,21.5242 6.939,21.9051L20.8637,13.9396C22.2403,13.1523 22.2604,11.2014 20.9266,10.3799C20.6774,10.3514 20.4264,10.3401 20.1755,10.3463Z"
|
||||
android:strokeAlpha="0.0625"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillAlpha="0.0625"/>
|
||||
<path
|
||||
android:pathData="M3.7022,11.9058V19.987C4.7838,20.6867 5.9221,21.2965 7.1054,21.8099L20.8636,13.937C21.2889,13.6946 21.6149,13.3121 21.7846,12.8561C21.9543,12.4001 21.957,11.8994 21.7924,11.4416C21.1315,11.787 20.3965,11.9703 19.6491,11.9761C17.6232,12.0191 17.0196,10.9854 14.7708,11.365C13.3296,11.6083 13.1197,12.1118 11.6534,12.2755C9.8617,12.4777 8.7533,11.8884 7.6662,11.6457C6.4026,11.365 4.9865,11.5094 3.7022,11.9058Z"
|
||||
android:strokeAlpha="0.07"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillAlpha="0.07"/>
|
||||
<path
|
||||
android:pathData="M3.7022,18.0311C4.4696,19.2821 5.6352,20.6113 7.0746,21.8273L20.7495,14.0048C20.1009,14.2198 19.4235,14.3371 18.7398,14.3527C15.4013,14.4449 14.7778,12.2941 10.7817,11.8946C8.5448,11.6712 5.3181,12.0035 3.6978,13.222L3.7022,18.0311Z"
|
||||
android:strokeAlpha="0.045"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillAlpha="0.045"/>
|
||||
<path
|
||||
android:pathData="M13.4087,11.2667C13.4087,10.6865 13.2932,10.1119 13.0692,9.5759C12.8451,9.0398 12.5168,8.5527 12.1027,8.1425C11.6886,7.7322 11.1971,7.4067 10.6561,7.1847C10.1152,6.9626 9.5354,6.8483 8.9498,6.8483H5.4393L10.4401,15.4299C11.3083,15.1248 12.0598,14.5607 12.5913,13.8154C13.123,13.0699 13.4085,12.1795 13.4087,11.2667Z"
|
||||
android:fillColor="#00F8BC"/>
|
||||
<path
|
||||
android:pathData="M11.9919,18.096L10.4401,15.4299L5.4405,6.8483H3.7022V20.1581C3.7022,21.7581 5.4499,22.7576 6.8479,21.958L12.3918,18.7841L11.9919,18.096Z"
|
||||
android:fillColor="#00D1F7"/>
|
||||
<path
|
||||
android:pathData="M3.7022,15.6851V20.1601C3.7022,21.7601 5.4499,22.7594 6.8479,21.9598L12.3918,18.7861L11.9919,18.096L10.4401,15.4299C9.9621,15.5986 9.4585,15.6849 8.9511,15.6851H3.7022Z"
|
||||
android:fillColor="#4E75F3"/>
|
||||
<path
|
||||
android:pathData="M3.7022,6.8483V15.6851H8.9536C9.4608,15.6855 9.9645,15.5999 10.4426,15.4319L5.4405,6.8483H3.7022Z"
|
||||
android:fillColor="#00D1F7"/>
|
||||
</group>
|
||||
</vector>
|
|
@ -9,7 +9,6 @@
|
|||
android:id="@+id/image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@+id/content"
|
||||
android:layout_alignParentEnd="true">
|
||||
|
||||
<ImageView
|
||||
|
@ -60,9 +59,8 @@
|
|||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="0dp">
|
||||
android:layout_marginTop="16dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/action_prev"
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
app:expandedTitleMarginBottom="24dp"
|
||||
app:expandedTitleMarginEnd="24dp"
|
||||
app:expandedTitleMarginStart="24dp"
|
||||
app:expandedTitleTextAppearance="@style/TextAppearance.Material3.HeadlineLarge"
|
||||
app:expandedTitleTextAppearance="@style/TextViewHeadline4"
|
||||
app:collapsedTitleTextAppearance="@style/TextViewHeadline6"
|
||||
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap|enterAlwaysCollapsed">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
|
|
|
@ -8,9 +8,8 @@
|
|||
<com.google.android.material.card.MaterialCardView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_margin="16dp"
|
||||
app:cardCornerRadius="@dimen/m3_card_corner_radius"
|
||||
app:cardElevation="8dp"
|
||||
app:cardUseCompatPadding="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_margin="16dp"
|
||||
app:cardCornerRadius="@dimen/m3_card_corner_radius"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/player_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
tools:ignore="ContentDescription,UnusedAttribute"
|
||||
tools:srcCompat="@tools:sample/backgrounds/scenic[8]" />
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -9,7 +9,7 @@
|
|||
android:orientation="vertical"
|
||||
tools:ignore="MissingPrefix">
|
||||
|
||||
<RelativeLayout
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/progress_container_height"
|
||||
android:background="@color/twenty_percent_black_overlay">
|
||||
|
@ -18,21 +18,26 @@
|
|||
android:id="@+id/songCurrentProgress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:gravity="center_vertical|left|end"
|
||||
android:paddingLeft="8dp"
|
||||
android:gravity="center_vertical|start"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="0dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="?colorOnSecondary"
|
||||
android:textSize="12sp"
|
||||
tools:ignore="RtlHardcoded,RtlSymmetry"
|
||||
tools:text="@tools:sample/date/hhmmss" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatSeekBar
|
||||
android:id="@+id/progressSlider"
|
||||
android:layout_width="0dp"
|
||||
style="@style/MusicProgressSlider"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/songTotalTime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentRight="true"
|
||||
android:gravity="center_vertical|right|end"
|
||||
android:gravity="center_vertical|end"
|
||||
android:paddingRight="8dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="?colorOnSecondary"
|
||||
|
@ -40,15 +45,7 @@
|
|||
tools:ignore="RtlHardcoded,RtlSymmetry"
|
||||
tools:text="@tools:sample/date/hhmmss" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatSeekBar
|
||||
android:id="@+id/progressSlider"
|
||||
style="@style/MusicProgressSlider"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_toLeftOf="@id/songTotalTime"
|
||||
android:layout_toRightOf="@id/songCurrentProgress"
|
||||
tools:ignore="RtlHardcoded,UnusedAttribute" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/media_button"
|
||||
|
@ -71,7 +68,6 @@
|
|||
android:orientation="horizontal"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/image"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorSurface"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:orientation="vertical">
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
android:layoutDirection="ltr"
|
||||
android:paddingStart="4dp"
|
||||
android:paddingEnd="4dp"
|
||||
tools:ignore="ContentDescription,UnusedAttribute">
|
||||
android:clipToPadding="false">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/repeatButton"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 5 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.7 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
@ -35,4 +35,6 @@
|
|||
</item>
|
||||
<item name="popupMenuBackground">@drawable/popup_background</item>
|
||||
</style>
|
||||
|
||||
<style name="mcab_theme" parent="@style/ThemeOverlay.MaterialComponents.Dark" />
|
||||
</resources>
|
|
@ -46,12 +46,13 @@
|
|||
<item name="titleMarginStart">16dp</item>
|
||||
</style>
|
||||
|
||||
<style name="mcab_theme" parent="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar">
|
||||
<item name="android:actionOverflowButtonStyle">@style/Widget.ActionButton.Overflow</item>
|
||||
<style name="mcab_theme" parent="@style/ThemeOverlay.MaterialComponents.Light">
|
||||
<item name="android:actionOverflowButtonStyle">@style/mcab_overflow_style</item>
|
||||
</style>
|
||||
|
||||
<style name="mcab_overflow_style">
|
||||
<style name="mcab_overflow_style" parent="Widget.AppCompat.ActionButton.Overflow">
|
||||
<item name="srcCompat">@drawable/ic_more_vert</item>
|
||||
<item name="android:tint">?colorSurface</item>
|
||||
</style>
|
||||
|
||||
<style name="ToolbarTextAppearanceNormal">
|
||||
|
|