diff --git a/app/build.gradle b/app/build.gradle
index 76c3b034f..ddb856324 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -15,8 +15,8 @@ android {
vectorDrawables.useSupportLibrary = true
applicationId "code.name.monkey.retromusic"
- versionCode 10544
- versionName '5.4.1 ' + "_" + getDate()
+ versionCode 10545
+ versionName '5.4.2 ' + "_" + getDate()
buildConfigField("String", "GOOGLE_PLAY_LICENSING_KEY", "\"${getProperty(getProperties('../public.properties'), 'GOOGLE_PLAY_LICENSE_KEY')}\"")
}
@@ -94,8 +94,8 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'androidx.annotation:annotation:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
- implementation 'androidx.recyclerview:recyclerview:1.2.1'
- implementation 'androidx.preference:preference-ktx:1.1.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.0-alpha01'
+ implementation 'androidx.preference:preference-ktx:1.2.0-beta01'
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.palette:palette-ktx:1.0.0'
@@ -110,7 +110,7 @@ dependencies {
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
- def room_version = '2.4.0-beta02'
+ def room_version = '2.4.0-rc01'
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
kapt "androidx.room:room-compiler:$room_version"
@@ -138,7 +138,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
- def kotlin_coroutines_version = '1.5.2'
+ def kotlin_coroutines_version = '1.6.0-RC'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e785fea33..fda8258e7 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -121,7 +121,7 @@
@@ -256,13 +256,25 @@
android:name="android.appwidget.provider"
android:resource="@xml/app_widget_card_info" />
+
+
+
+
+
+
+
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt
index d2bbcbe2b..df912bcd4 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt
@@ -24,6 +24,7 @@ import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
import code.name.monkey.retromusic.databinding.ActivityDriveModeBinding
+import code.name.monkey.retromusic.extensions.setDrawUnderStatusBar
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.glide.BlurTransformation
import code.name.monkey.retromusic.glide.GlideApp
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/LockScreenActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/LockScreenActivity.kt
index ba026cdb4..46c1e4385 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/LockScreenActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/LockScreenActivity.kt
@@ -24,7 +24,7 @@ import androidx.core.view.ViewCompat
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
import code.name.monkey.retromusic.databinding.ActivityLockScreenBinding
-import code.name.monkey.retromusic.extensions.whichFragment
+import code.name.monkey.retromusic.extensions.*
import code.name.monkey.retromusic.fragments.player.lockscreen.LockScreenControlsFragment
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
@@ -47,7 +47,7 @@ class LockScreenActivity : AbsMusicServiceActivity() {
binding = ActivityLockScreenBinding.inflate(layoutInflater)
setContentView(binding.root)
hideStatusBar()
- setStatusbarColorAuto()
+ setStatusBarColorAuto()
setTaskDescriptionColorAuto()
val config = SlidrConfig.Builder().listener(object : SlidrListener {
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt
index 59b59bf13..72b1910ee 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt
@@ -26,9 +26,7 @@ import androidx.navigation.ui.setupWithNavController
import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.activities.base.AbsCastActivity
import code.name.monkey.retromusic.databinding.SlidingMusicPanelLayoutBinding
-import code.name.monkey.retromusic.extensions.currentFragment
-import code.name.monkey.retromusic.extensions.extra
-import code.name.monkey.retromusic.extensions.findNavController
+import code.name.monkey.retromusic.extensions.*
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewFragment
import code.name.monkey.retromusic.fragments.home.HomeFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote
@@ -136,8 +134,8 @@ class MainActivity : AbsCastActivity(), OnSharedPreferenceChangeListener {
PreferenceUtil.registerOnSharedPreferenceChangedListener(this)
val expand = extra(EXPAND_PANEL).value ?: false
if (expand && PreferenceUtil.isExpandPanel) {
- setBottomNavVisibility(false)
fromNotification = true
+ slidingPanel.bringToFront()
expandPanel()
intent.removeExtra(EXPAND_PANEL)
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/PermissionActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/PermissionActivity.kt
index 34d4a50cc..8a5d75431 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/PermissionActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/PermissionActivity.kt
@@ -30,6 +30,8 @@ import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
import code.name.monkey.retromusic.databinding.ActivityPermissionBinding
import code.name.monkey.retromusic.extensions.accentBackgroundColor
+import code.name.monkey.retromusic.extensions.setStatusBarColorAuto
+import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.util.RingtoneManager
@@ -40,7 +42,7 @@ class PermissionActivity : AbsMusicServiceActivity() {
super.onCreate(savedInstanceState)
binding = ActivityPermissionBinding.inflate(layoutInflater)
setContentView(binding.root)
- setStatusbarColorAuto()
+ setStatusBarColorAuto()
setTaskDescriptionColorAuto()
setupTitle()
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/PurchaseActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/PurchaseActivity.kt
index 1550ee3cd..1054c1ef9 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/PurchaseActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/PurchaseActivity.kt
@@ -28,6 +28,9 @@ import code.name.monkey.retromusic.Constants.PRO_VERSION_PRODUCT_ID
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
import code.name.monkey.retromusic.databinding.ActivityProVersionBinding
+import code.name.monkey.retromusic.extensions.setDrawUnderStatusBar
+import code.name.monkey.retromusic.extensions.setLightStatusBar
+import code.name.monkey.retromusic.extensions.setStatusBarColor
import com.anjlab.android.iab.v3.BillingProcessor
import com.anjlab.android.iab.v3.PurchaseInfo
@@ -41,8 +44,8 @@ class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
super.onCreate(savedInstanceState)
binding = ActivityProVersionBinding.inflate(layoutInflater)
setContentView(binding.root)
- setStatusbarColor(Color.TRANSPARENT)
- setLightStatusbar(false)
+ setStatusBarColor(Color.TRANSPARENT)
+ setLightStatusBar(false)
binding.toolbar.navigationIcon?.setTint(Color.WHITE)
binding.toolbar.setNavigationOnClickListener { onBackPressed() }
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/SettingsActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/SettingsActivity.kt
index b9a233bb9..39702cf9f 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/SettingsActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/SettingsActivity.kt
@@ -25,10 +25,7 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.base.AbsThemeActivity
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager
import code.name.monkey.retromusic.databinding.ActivitySettingsBinding
-import code.name.monkey.retromusic.extensions.applyToolbar
-import code.name.monkey.retromusic.extensions.extra
-import code.name.monkey.retromusic.extensions.findNavController
-import code.name.monkey.retromusic.extensions.surfaceColor
+import code.name.monkey.retromusic.extensions.*
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.color.ColorCallback
@@ -38,7 +35,7 @@ class SettingsActivity : AbsThemeActivity(), ColorCallback, OnThemeChangedListen
setDrawUnderStatusBar()
val mSavedInstanceState = extra(TAG).value ?: savedInstanceState
super.onCreate(mSavedInstanceState)
- setLightStatusbarAuto(surfaceColor())
+ setLightStatusBarAuto(surfaceColor())
binding = ActivitySettingsBinding.inflate(layoutInflater)
setContentView(binding.root)
setupToolbar()
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/ShareInstagramStory.kt b/app/src/main/java/code/name/monkey/retromusic/activities/ShareInstagramStory.kt
index a0a719738..6fd9a2b86 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/ShareInstagramStory.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/ShareInstagramStory.kt
@@ -28,6 +28,10 @@ import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
import code.name.monkey.retromusic.databinding.ActivityShareInstagramBinding
+import code.name.monkey.retromusic.extensions.applyToolbar
+import code.name.monkey.retromusic.extensions.setDrawUnderStatusBar
+import code.name.monkey.retromusic.extensions.setLightStatusBar
+import code.name.monkey.retromusic.extensions.setStatusBarColor
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
@@ -60,7 +64,7 @@ class ShareInstagramStory : AbsBaseActivity() {
super.onCreate(savedInstanceState)
binding = ActivityShareInstagramBinding.inflate(layoutInflater)
setContentView(binding.root)
- setStatusbarColor(Color.TRANSPARENT)
+ setStatusBarColor(Color.TRANSPARENT)
binding.toolbar.setBackgroundColor(Color.TRANSPARENT)
setSupportActionBar(binding.toolbar)
@@ -104,7 +108,7 @@ class ShareInstagramStory : AbsBaseActivity() {
}
private fun setColors(colorLight: Boolean, color: Int) {
- setLightStatusbar(colorLight)
+ setLightStatusBar(colorLight)
binding.toolbar.setTitleTextColor(
MaterialValueHelper.getPrimaryTextColor(
this@ShareInstagramStory,
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/SupportDevelopmentActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/SupportDevelopmentActivity.kt
index 128746fb2..b055c45e0 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/SupportDevelopmentActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/SupportDevelopmentActivity.kt
@@ -37,6 +37,8 @@ import code.name.monkey.retromusic.BuildConfig
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
import code.name.monkey.retromusic.databinding.ActivityDonationBinding
+import code.name.monkey.retromusic.extensions.setStatusBarColorAuto
+import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto
import code.name.monkey.retromusic.extensions.textColorPrimary
import code.name.monkey.retromusic.extensions.textColorSecondary
import com.anjlab.android.iab.v3.BillingProcessor
@@ -73,7 +75,7 @@ class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingH
binding = ActivityDonationBinding.inflate(layoutInflater)
setContentView(binding.root)
- setStatusbarColorAuto()
+ setStatusBarColorAuto()
setTaskDescriptionColorAuto()
setupToolbar()
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/WhatsNewActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/WhatsNewActivity.kt
index a8b059994..40200eba0 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/WhatsNewActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/WhatsNewActivity.kt
@@ -17,6 +17,8 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.base.AbsThemeActivity
import code.name.monkey.retromusic.databinding.ActivityWhatsNewBinding
import code.name.monkey.retromusic.extensions.accentColor
+import code.name.monkey.retromusic.extensions.setLightStatusBarAuto
+import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto
import code.name.monkey.retromusic.util.PreferenceUtil.lastVersion
import code.name.monkey.retromusic.util.RetroUtil
import java.io.BufferedReader
@@ -29,7 +31,7 @@ class WhatsNewActivity : AbsThemeActivity() {
super.onCreate(savedInstanceState)
val binding = ActivityWhatsNewBinding.inflate(layoutInflater)
setContentView(binding.root)
- setLightStatusbarAuto(resolveColor(this, R.attr.colorSurface))
+ setLightStatusBarAuto(resolveColor(this, R.attr.colorSurface))
setTaskDescriptionColorAuto()
binding.toolbar.setNavigationOnClickListener { onBackPressed() }
ToolbarContentTintHelper.colorBackButton(binding.toolbar)
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt
index fea75a460..8034362b5 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt
@@ -14,7 +14,6 @@
*/
package code.name.monkey.retromusic.activities.base
-import android.animation.Animator
import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle
@@ -25,6 +24,7 @@ import android.widget.FrameLayout
import androidx.core.animation.doOnEnd
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
@@ -67,11 +67,10 @@ import org.koin.androidx.viewmodel.ext.android.viewModel
abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
companion object {
val TAG: String = AbsSlidingMusicPanelActivity::class.java.simpleName
- var fromNotification: Boolean = false
}
+ var fromNotification = false
private var windowInsets: WindowInsetsCompat? = null
- private var bottomNavAnimator: Animator? = null
protected val libraryViewModel by viewModel()
private lateinit var bottomSheetBehavior: RetroBottomSheetBehavior
private var playerFragment: AbsPlayerFragment? = null
@@ -93,21 +92,19 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
when (newState) {
STATE_EXPANDED -> {
onPanelExpanded()
+
}
STATE_COLLAPSED -> {
onPanelCollapsed()
- if (fromNotification) {
- hideBottomSheet(MusicPlayerRemote.playingQueue.isEmpty())
- fromNotification = false
- }
}
STATE_SETTLING, STATE_DRAGGING -> {
if (fromNotification) {
- bottomNavigationView.isVisible = true
+ binding.bottomNavigationView.bringToFront()
+ fromNotification = false
}
}
else -> {
- println("Do something")
+ println("Do a flip")
}
}
}
@@ -175,7 +172,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
if (progress < 0) return
val alpha = 1 - progress
miniPlayerFragment?.view?.alpha = 1 - (progress / 0.2F)
- miniPlayerFragment?.view?.visibility = if (alpha == 0f) View.GONE else View.VISIBLE
+ miniPlayerFragment?.view?.isGone = alpha == 0f
binding.bottomNavigationView.translationY = progress * 500
binding.bottomNavigationView.alpha = alpha
binding.playerFragmentContainer.alpha = (progress - 0.2F) / 0.2F
@@ -184,9 +181,9 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
open fun onPanelCollapsed() {
setMiniPlayerAlphaProgress(0F)
// restore values
- super.setLightStatusbarAuto(surfaceColor())
- super.setLightNavigationAuto()
- super.setTaskDescriptionColor(taskColor)
+ setLightStatusBarAuto(surfaceColor())
+ setLightNavigationAuto()
+ setTaskDescriptionColor(taskColor)
}
open fun onPanelExpanded() {
@@ -217,6 +214,8 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
val bottomNavigationView get() = binding.bottomNavigationView
+ val slidingPanel get() = binding.slidingPanel
+
override fun onServiceConnected() {
super.onServiceConnected()
if (MusicPlayerRemote.playingQueue.isNotEmpty()) {
@@ -251,32 +250,31 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
collapsePanel()
return true
}
-
return false
}
private fun onPaletteColorChanged() {
if (panelState == STATE_EXPANDED) {
- super.setTaskDescriptionColor(paletteColor)
+ setTaskDescColor(paletteColor)
val isColorLight = ColorUtil.isColorLight(paletteColor)
if (PreferenceUtil.isAdaptiveColor && (nowPlayingScreen == Normal || nowPlayingScreen == Flat)) {
- super.setLightNavigationBar(true)
- super.setLightStatusbar(isColorLight)
+ setLightNavigationBar(true)
+ setLightStatusBar(isColorLight)
} else if (nowPlayingScreen == Card || nowPlayingScreen == Blur || nowPlayingScreen == BlurCard) {
- super.setLightStatusbar(false)
- super.setLightNavigationBar(true)
+ setLightStatusBar(false)
+ setLightNavigationBar(true)
} else if (nowPlayingScreen == Color || nowPlayingScreen == Tiny || nowPlayingScreen == Gradient) {
- super.setLightNavigationBar(isColorLight)
- super.setLightStatusbar(isColorLight)
+ setLightNavigationBar(isColorLight)
+ setLightStatusBar(isColorLight)
} else if (nowPlayingScreen == Full) {
- super.setLightNavigationBar(isColorLight)
- super.setLightStatusbar(false)
+ setLightNavigationBar(isColorLight)
+ setLightStatusBar(false)
} else if (nowPlayingScreen == Classic) {
- super.setLightStatusbar(false)
+ setLightStatusBar(false)
} else if (nowPlayingScreen == Fit) {
- super.setLightStatusbar(false)
+ setLightStatusBar(false)
} else {
- super.setLightStatusbar(
+ setLightStatusBar(
ColorUtil.isColorLight(
ATHUtil.resolveColor(
this,
@@ -284,15 +282,15 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
)
)
)
- super.setLightNavigationBar(true)
+ setLightNavigationBar(true)
}
}
}
- override fun setTaskDescriptionColor(color: Int) {
+ private fun setTaskDescColor(color: Int) {
taskColor = color
if (panelState == STATE_COLLAPSED) {
- super.setTaskDescriptionColor(color)
+ setTaskDescriptionColor(color)
}
}
@@ -319,53 +317,63 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
}
fun setBottomNavVisibility(visible: Boolean, animate: Boolean = false) {
- binding.bottomNavigationView.isVisible = visible
- hideBottomSheet(MusicPlayerRemote.playingQueue.isEmpty(), animate)
+ val translationY =
+ if (visible) 0F else dip(R.dimen.bottom_nav_height).toFloat() + windowInsets.safeGetBottomInsets()
+ if (animate) {
+ binding.bottomNavigationView.translateYAnimate(translationY).doOnEnd {
+ if (visible && bottomSheetBehavior.state != STATE_EXPANDED) {
+ binding.bottomNavigationView.bringToFront()
+ }
+ }
+ } else {
+ binding.bottomNavigationView.translationY =
+ translationY
+ if (visible && bottomSheetBehavior.state != STATE_EXPANDED) {
+ binding.bottomNavigationView.bringToFront()
+ }
+ }
+ hideBottomSheet(
+ hide = MusicPlayerRemote.playingQueue.isEmpty(),
+ animate = animate,
+ isBottomNavVisible = visible
+ )
}
- fun hideBottomSheet(hide: Boolean, animate: Boolean = false) {
+ fun hideBottomSheet(
+ hide: Boolean,
+ animate: Boolean = false,
+ isBottomNavVisible: Boolean = bottomNavigationView.isVisible
+ ) {
val heightOfBar =
windowInsets.safeGetBottomInsets() +
if (MusicPlayerRemote.isCasting) dip(R.dimen.cast_mini_player_height) else dip(R.dimen.mini_player_height)
val heightOfBarWithTabs = heightOfBar + dip(R.dimen.bottom_nav_height)
- val isVisible = binding.bottomNavigationView.isVisible
if (hide) {
bottomSheetBehavior.peekHeight = -windowInsets.safeGetBottomInsets()
bottomSheetBehavior.state = STATE_COLLAPSED
- libraryViewModel.setFabMargin(if (isVisible) dip(R.dimen.bottom_nav_height) else 0)
+ libraryViewModel.setFabMargin(if (isBottomNavVisible) dip(R.dimen.bottom_nav_height) else 0)
ViewCompat.setElevation(binding.slidingPanel, 0f)
ViewCompat.setElevation(binding.bottomNavigationView, 10f)
} else {
if (MusicPlayerRemote.playingQueue.isNotEmpty()) {
-
ViewCompat.setElevation(binding.slidingPanel, 10f)
ViewCompat.setElevation(binding.bottomNavigationView, 10f)
- if (isVisible) {
+ if (isBottomNavVisible) {
println("List")
if (animate) {
- bottomNavAnimator?.end()
bottomSheetBehavior.peekHeightAnimate(heightOfBarWithTabs)
- bottomNavAnimator = binding.bottomNavigationView.translateYAnimate(0F)
} else {
bottomSheetBehavior.peekHeight = heightOfBarWithTabs
- binding.bottomNavigationView.translationY = 0F
}
- binding.bottomNavigationView.bringToFront()
libraryViewModel.setFabMargin(dip(R.dimen.mini_player_height_expanded))
} else {
println("Details")
if (animate) {
- bottomSheetBehavior.peekHeightAnimate(heightOfBar)
- bottomNavAnimator?.end()
- bottomNavAnimator =
- bottomNavigationView.translateYAnimate(dip(R.dimen.bottom_nav_height).toFloat())
- bottomNavAnimator?.doOnEnd {
+ bottomSheetBehavior.peekHeightAnimate(heightOfBar).doOnEnd {
binding.slidingPanel.bringToFront()
}
} else {
bottomSheetBehavior.peekHeight = heightOfBar
- binding.bottomNavigationView.translationY =
- dip(R.dimen.bottom_nav_height).toFloat()
binding.slidingPanel.bringToFront()
}
libraryViewModel.setFabMargin(dip(R.dimen.mini_player_height))
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsThemeActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsThemeActivity.kt
index f53fe5ecd..87ff2f32a 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsThemeActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsThemeActivity.kt
@@ -16,28 +16,16 @@ package code.name.monkey.retromusic.activities.base
import android.content.Context
import android.content.res.Resources
-import android.graphics.Color
import android.os.Bundle
import android.os.Handler
import android.view.KeyEvent
import android.view.View
-import android.view.WindowManager
-import androidx.annotation.ColorInt
import androidx.appcompat.app.AppCompatDelegate.setDefaultNightMode
import androidx.core.os.ConfigurationCompat
-import androidx.core.view.WindowInsetsCompat
-import androidx.core.view.WindowInsetsControllerCompat
-import code.name.monkey.appthemehelper.ATH
-import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.common.ATHToolbarActivity
-import code.name.monkey.appthemehelper.util.ATHUtil
-import code.name.monkey.appthemehelper.util.ColorUtil
-import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.LanguageContextWrapper
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.extensions.surfaceColor
+import code.name.monkey.retromusic.extensions.*
import code.name.monkey.retromusic.util.PreferenceUtil
-import code.name.monkey.retromusic.util.RetroUtil
import code.name.monkey.retromusic.util.theme.ThemeManager
import com.google.android.material.color.DynamicColors
import java.util.*
@@ -53,9 +41,8 @@ abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
setImmersiveFullscreen()
registerSystemUiVisibility()
toggleScreenOn()
- setDrawUnderNavigationBar()
setLightNavigationAuto()
- setLightStatusbarAuto(surfaceColor())
+ setLightStatusBarAuto(surfaceColor())
}
private fun updateTheme() {
@@ -71,14 +58,6 @@ abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
}
}
- private fun toggleScreenOn() {
- if (PreferenceUtil.isScreenOnEnabled) {
- window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
- } else {
- window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
- }
- }
-
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if (hasFocus) {
@@ -90,95 +69,6 @@ abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
}
}
- fun hideStatusBar() {
- hideStatusBar(PreferenceUtil.isFullScreenMode)
- }
-
- private fun hideStatusBar(fullscreen: Boolean) {
- val statusBar = window.decorView.rootView.findViewById(R.id.status_bar)
- if (statusBar != null) {
- statusBar.visibility = if (fullscreen) View.GONE else View.VISIBLE
- }
- }
-
- fun setDrawUnderStatusBar() {
- RetroUtil.setAllowDrawUnderStatusBar(window)
- }
-
- private fun setDrawUnderNavigationBar() {
- RetroUtil.setAllowDrawUnderNavigationBar(window)
- }
-
- /**
- * This will set the color of the view with the id "status_bar" on KitKat and Lollipop. On
- * Lollipop if no such view is found it will set the statusbar color using the native method.
- *
- * @param color the new statusbar color (will be shifted down on Lollipop and above)
- */
- fun setStatusbarColor(color: Int) {
- val statusBar = window.decorView.rootView.findViewById(R.id.status_bar)
- if (statusBar != null) {
- when {
- VersionUtils.hasMarshmallow() -> statusBar.setBackgroundColor(color)
- else -> statusBar.setBackgroundColor(
- ColorUtil.darkenColor(
- color
- )
- )
- }
- } else {
- when {
- VersionUtils.hasMarshmallow() -> window.statusBarColor = color
- else -> window.statusBarColor = ColorUtil.darkenColor(color)
- }
- }
- setLightStatusbarAuto(ATHUtil.resolveColor(this, R.attr.colorSurface))
- }
-
- fun setStatusbarColorAuto() {
- // we don't want to use statusbar color because we are doing the color darkening on our own to support KitKat
- setStatusbarColor(ATHUtil.resolveColor(this, R.attr.colorSurface))
- setLightStatusbarAuto(ATHUtil.resolveColor(this, R.attr.colorSurface))
- }
-
- open fun setTaskDescriptionColor(@ColorInt color: Int) {
- ATH.setTaskDescriptionColor(this, color)
- }
-
- fun setTaskDescriptionColorAuto() {
- setTaskDescriptionColor(ATHUtil.resolveColor(this, R.attr.colorSurface))
- }
-
- open fun setNavigationbarColor(color: Int) {
- if (ThemeStore.coloredNavigationBar(this)) {
- ATH.setNavigationbarColor(this, color)
- } else {
- ATH.setNavigationbarColor(this, Color.BLACK)
- }
- }
-
- fun setNavigationbarColorAuto() {
- setNavigationbarColor(ATHUtil.resolveColor(this, R.attr.colorSurface))
- }
-
- fun setLightNavigationAuto() {
- ATH.setLightNavigationbarAuto(this, surfaceColor())
- }
-
- open fun setLightStatusbar(enabled: Boolean) {
- ATH.setLightStatusbar(this, enabled)
- }
-
- fun setLightStatusbarAuto(bgColor: Int) {
- setLightStatusbar(ColorUtil.isColorLight(bgColor))
- }
-
- open fun setLightNavigationBar(enabled: Boolean) {
- if (!ATHUtil.isWindowBackgroundDark(this) and ThemeStore.coloredNavigationBar(this)) {
- ATH.setLightNavigationbar(this, enabled)
- }
- }
-
private fun registerSystemUiVisibility() {
val decorView = window.decorView
decorView.setOnSystemUiVisibilityChangeListener { visibility ->
@@ -193,23 +83,6 @@ abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
decorView.setOnSystemUiVisibilityChangeListener(null)
}
- private fun setImmersiveFullscreen() {
- if (PreferenceUtil.isFullScreenMode) {
- WindowInsetsControllerCompat(window, window.decorView).apply {
- systemBarsBehavior =
- WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
- hide(WindowInsetsCompat.Type.systemBars())
- }
- }
- }
-
- private fun exitFullscreen() {
- WindowInsetsControllerCompat(window, window.decorView).apply {
- systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
- show(WindowInsetsCompat.Type.systemBars())
- }
- }
-
override fun run() {
setImmersiveFullscreen()
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/BugReportActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/BugReportActivity.kt
index cc0ca55c4..c446fdcfd 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/BugReportActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/BugReportActivity.kt
@@ -41,6 +41,7 @@ import code.name.monkey.retromusic.activities.bugreport.model.github.ExtraInfo
import code.name.monkey.retromusic.activities.bugreport.model.github.GithubLogin
import code.name.monkey.retromusic.activities.bugreport.model.github.GithubTarget
import code.name.monkey.retromusic.databinding.ActivityBugReportBinding
+import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto
import code.name.monkey.retromusic.misc.DialogAsyncTask
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.floatingactionbutton.FloatingActionButton
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AbsTagEditorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AbsTagEditorActivity.kt
index 3c6d0c7e8..cee65c013 100755
--- a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AbsTagEditorActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AbsTagEditorActivity.kt
@@ -42,6 +42,7 @@ 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.extensions.setTaskDescriptionColorAuto
import code.name.monkey.retromusic.model.ArtworkInfo
import code.name.monkey.retromusic.model.AudioTagInfo
import code.name.monkey.retromusic.repository.Repository
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt
index bd6bf459d..4b9958c6b 100755
--- a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt
@@ -32,6 +32,7 @@ import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.databinding.ActivityAlbumTagEditorBinding
import code.name.monkey.retromusic.extensions.appHandleColor
+import code.name.monkey.retromusic.extensions.setDrawUnderStatusBar
import code.name.monkey.retromusic.extensions.setTint
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt
index 25e24ff7f..75fbd1a13 100644
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt
@@ -163,7 +163,7 @@ open class AlbumAdapter(
when (PreferenceUtil.albumSortOrder) {
SortOrder.AlbumSortOrder.ALBUM_A_Z, SortOrder.AlbumSortOrder.ALBUM_Z_A -> sectionName =
dataSet[position].title
- SortOrder.AlbumSortOrder.ALBUM_ARTIST -> sectionName = dataSet[position].artistName
+ SortOrder.AlbumSortOrder.ALBUM_ARTIST -> sectionName = dataSet[position].albumArtist
SortOrder.AlbumSortOrder.ALBUM_YEAR -> return MusicUtil.getYearString(
dataSet[position].year
)
diff --git a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetMD3.kt b/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetMD3.kt
new file mode 100644
index 000000000..a60c7bca5
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetMD3.kt
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2020 Hemanth Savarla.
+ *
+ * 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.appwidgets
+
+import android.app.PendingIntent
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.graphics.Bitmap
+import android.graphics.drawable.Drawable
+import android.text.TextUtils
+import android.view.View
+import android.widget.RemoteViews
+import code.name.monkey.appthemehelper.util.MaterialValueHelper
+import code.name.monkey.appthemehelper.util.VersionUtils
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.activities.MainActivity
+import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
+import code.name.monkey.retromusic.glide.GlideApp
+import code.name.monkey.retromusic.glide.RetroGlideExtension
+import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
+import code.name.monkey.retromusic.service.MusicService
+import code.name.monkey.retromusic.service.MusicService.*
+import code.name.monkey.retromusic.util.DensityUtil
+import code.name.monkey.retromusic.util.ImageUtil
+import code.name.monkey.retromusic.util.PreferenceUtil
+import code.name.monkey.retromusic.util.RetroUtil
+import com.bumptech.glide.Glide
+import com.bumptech.glide.request.target.SimpleTarget
+import com.bumptech.glide.request.target.Target
+import com.bumptech.glide.request.transition.Transition
+
+class AppWidgetMD3 : BaseAppWidget() {
+ private var target: Target? = null // for cancellation
+
+ /**
+ * Initialize given widgets to default state, where we launch Music on default click and hide
+ * actions if service not running.
+ */
+ override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
+ val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_md3)
+
+ appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
+ appWidgetView.setImageViewResource(R.id.image, R.drawable.default_audio_art)
+ val secondaryColor = MaterialValueHelper.getSecondaryTextColor(context, true)
+ appWidgetView.setImageViewBitmap(
+ R.id.button_next, createBitmap(
+ RetroUtil.getTintedVectorDrawable(
+ context,
+ R.drawable.ic_skip_next,
+ secondaryColor
+ ), 1f
+ )
+ )
+ appWidgetView.setImageViewBitmap(
+ R.id.button_prev, createBitmap(
+ RetroUtil.getTintedVectorDrawable(
+ context,
+ R.drawable.ic_skip_previous,
+ secondaryColor
+ ), 1f
+ )
+ )
+ appWidgetView.setImageViewBitmap(
+ R.id.button_toggle_play_pause, createBitmap(
+ RetroUtil.getTintedVectorDrawable(
+ context,
+ R.drawable.ic_play_arrow_white_32dp,
+ secondaryColor
+ ), 1f
+ )
+ )
+
+ linkButtons(context, appWidgetView)
+ pushUpdate(context, appWidgetIds, appWidgetView)
+ }
+
+ /**
+ * Update all active widget instances by pushing changes
+ */
+ override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
+ val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_md3)
+
+ val isPlaying = service.isPlaying
+ val song = service.currentSong
+
+ // Set the titles and artwork
+ if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
+ appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
+ } else {
+ appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE)
+ appWidgetView.setTextViewText(R.id.title, song.title)
+ appWidgetView.setTextViewText(R.id.text, getSongArtistAndAlbum(song))
+ }
+
+ // Set correct drawable for pause state
+ val playPauseRes =
+ if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play_arrow_white_32dp
+ appWidgetView.setImageViewBitmap(
+ R.id.button_toggle_play_pause, createBitmap(
+ RetroUtil.getTintedVectorDrawable(
+ service,
+ playPauseRes,
+ MaterialValueHelper.getSecondaryTextColor(service, true)
+ ), 1f
+ )
+ )
+
+ // Set prev/next button drawables
+ appWidgetView.setImageViewBitmap(
+ R.id.button_next, createBitmap(
+ RetroUtil.getTintedVectorDrawable(
+ service,
+ R.drawable.ic_skip_next,
+ MaterialValueHelper.getSecondaryTextColor(service, true)
+ ), 1f
+ )
+ )
+ appWidgetView.setImageViewBitmap(
+ R.id.button_prev, createBitmap(
+ RetroUtil.getTintedVectorDrawable(
+ service,
+ R.drawable.ic_skip_previous,
+ MaterialValueHelper.getSecondaryTextColor(service, true)
+ ), 1f
+ )
+ )
+
+ // Link actions buttons to intents
+ linkButtons(service, appWidgetView)
+
+ if (imageSize == 0) {
+ imageSize =
+ service.resources.getDimensionPixelSize(R.dimen.app_widget_card_image_size)
+ }
+ if (cardRadius == 0f) {
+ cardRadius =
+ DensityUtil.dip2px(service, 8F).toFloat()
+ }
+
+ // Load the album cover async and push the update on completion
+ service.runOnUiThread {
+ if (target != null) {
+ Glide.with(service).clear(target)
+ }
+ target = GlideApp.with(service).asBitmapPalette().songCoverOptions(song)
+ .load(RetroGlideExtension.getSongModel(song))
+ .centerCrop()
+ .into(object : SimpleTarget(imageSize, imageSize) {
+ override fun onResourceReady(
+ resource: BitmapPaletteWrapper,
+ transition: Transition?
+ ) {
+ val palette = resource.palette
+ update(
+ resource.bitmap, palette.getVibrantColor(
+ palette.getMutedColor(
+ MaterialValueHelper.getSecondaryTextColor(
+ service, true
+ )
+ )
+ )
+ )
+ }
+
+ override fun onLoadFailed(errorDrawable: Drawable?) {
+ super.onLoadFailed(errorDrawable)
+ update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
+ }
+
+ private fun update(bitmap: Bitmap?, color: Int) {
+ // Set correct drawable for pause state
+ appWidgetView.setImageViewBitmap(
+ R.id.button_toggle_play_pause, ImageUtil.createBitmap(
+ ImageUtil.getTintedVectorDrawable(
+ service, playPauseRes, color
+ )
+ )
+ )
+
+ // Set prev/next button drawables
+ appWidgetView.setImageViewBitmap(
+ R.id.button_next, ImageUtil.createBitmap(
+ ImageUtil.getTintedVectorDrawable(
+ service, R.drawable.ic_skip_next, color
+ )
+ )
+ )
+ appWidgetView.setImageViewBitmap(
+ R.id.button_prev, ImageUtil.createBitmap(
+ ImageUtil.getTintedVectorDrawable(
+ service, R.drawable.ic_skip_previous, color
+ )
+ )
+ )
+
+ val image = getAlbumArtDrawable(service.resources, bitmap)
+ val roundedBitmap = createRoundedBitmap(
+ image, imageSize, imageSize, cardRadius, cardRadius, cardRadius, cardRadius
+ )
+ appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap)
+
+ pushUpdate(service, appWidgetIds, appWidgetView)
+ }
+ })
+ }
+ }
+
+ /**
+ * Link up various button actions using [PendingIntent].
+ */
+ private fun linkButtons(context: Context, views: RemoteViews) {
+ val action = Intent(context, MainActivity::class.java)
+ .putExtra(
+ MainActivity.EXPAND_PANEL,
+ PreferenceUtil.isExpandPanel
+ )
+
+ val serviceName = ComponentName(context, MusicService::class.java)
+
+ // Home
+ action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
+ var pendingIntent =
+ PendingIntent.getActivity(
+ context, 0, action, if (VersionUtils.hasMarshmallow())
+ PendingIntent.FLAG_IMMUTABLE
+ else 0
+ )
+ views.setOnClickPendingIntent(R.id.image, pendingIntent)
+ views.setOnClickPendingIntent(R.id.media_titles, pendingIntent)
+
+ // Previous track
+ pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName)
+ views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
+
+ // Play and pause
+ pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName)
+ views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
+
+ // Next track
+ pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName)
+ views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
+ }
+
+ companion object {
+
+ const val NAME = "app_widget_md3"
+
+ private var mInstance: AppWidgetMD3? = null
+ private var imageSize = 0
+ private var cardRadius = 0F
+
+ val instance: AppWidgetMD3
+ @Synchronized get() {
+ if (mInstance == null) {
+ mInstance = AppWidgetMD3()
+ }
+ return mInstance!!
+ }
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/extensions/ActivityThemeExtensions.kt b/app/src/main/java/code/name/monkey/retromusic/extensions/ActivityThemeExtensions.kt
new file mode 100644
index 000000000..4806c1bad
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/extensions/ActivityThemeExtensions.kt
@@ -0,0 +1,139 @@
+package code.name.monkey.retromusic.extensions
+
+import android.app.ActivityManager
+import android.graphics.Color
+import android.os.Build
+import android.view.View
+import android.view.WindowManager
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.WindowCompat
+import androidx.core.view.WindowInsetsCompat
+import androidx.core.view.WindowInsetsControllerCompat
+import androidx.fragment.app.FragmentActivity
+import code.name.monkey.appthemehelper.ATH
+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.VersionUtils
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.util.PreferenceUtil
+import code.name.monkey.retromusic.util.RetroUtil
+
+fun AppCompatActivity.toggleScreenOn() {
+ if (PreferenceUtil.isScreenOnEnabled) {
+ window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
+ } else {
+ window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
+ }
+}
+
+fun AppCompatActivity.setImmersiveFullscreen() {
+ if (PreferenceUtil.isFullScreenMode) {
+ WindowInsetsControllerCompat(window, window.decorView).apply {
+ systemBarsBehavior =
+ WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
+ hide(WindowInsetsCompat.Type.systemBars())
+ }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+ window.attributes.layoutInDisplayCutoutMode =
+ WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
+ }
+ }
+}
+
+fun AppCompatActivity.exitFullscreen() {
+ WindowInsetsControllerCompat(window, window.decorView).apply {
+ systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
+ show(WindowInsetsCompat.Type.systemBars())
+ }
+}
+
+
+fun AppCompatActivity.hideStatusBar() {
+ hideStatusBar(PreferenceUtil.isFullScreenMode)
+}
+
+private fun AppCompatActivity.hideStatusBar(fullscreen: Boolean) {
+ val statusBar = window.decorView.rootView.findViewById(R.id.status_bar)
+ if (statusBar != null) {
+ statusBar.visibility = if (fullscreen) View.GONE else View.VISIBLE
+ }
+}
+
+fun AppCompatActivity.setDrawUnderStatusBar() {
+ WindowCompat.setDecorFitsSystemWindows(window, false)
+ window.statusBarColor = Color.TRANSPARENT
+}
+
+fun FragmentActivity.setTaskDescriptionColor(color: Int) {
+ var colorFinal = color
+ // Task description requires fully opaque color
+ colorFinal = ColorUtil.stripAlpha(colorFinal)
+ // Sets color of entry in the system recents page
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+ setTaskDescription(
+ ActivityManager.TaskDescription(
+ title as String?,
+ -1,
+ colorFinal
+ )
+ )
+ } else {
+ setTaskDescription(ActivityManager.TaskDescription(title as String?))
+ }
+}
+
+fun AppCompatActivity.setTaskDescriptionColorAuto() {
+ setTaskDescriptionColor(surfaceColor())
+}
+
+fun AppCompatActivity.setLightNavigationAuto() {
+ ATH.setLightNavigationBarAuto(this, surfaceColor())
+}
+
+fun AppCompatActivity.setLightStatusBar(enabled: Boolean) {
+ ATH.setLightStatusBar(this, enabled)
+}
+
+fun AppCompatActivity.setLightStatusBarAuto(bgColor: Int) {
+ setLightStatusBar(ColorUtil.isColorLight(bgColor))
+}
+
+fun AppCompatActivity.setLightNavigationBar(enabled: Boolean) {
+ if (!ATHUtil.isWindowBackgroundDark(this) and ThemeStore.coloredNavigationBar(this)) {
+ ATH.setLightNavigationbar(this, enabled)
+ }
+}
+
+
+/**
+ * This will set the color of the view with the id "status_bar" on KitKat and Lollipop. On
+ * Lollipop if no such view is found it will set the statusbar color using the native method.
+ *
+ * @param color the new statusbar color (will be shifted down on Lollipop and above)
+ */
+fun AppCompatActivity.setStatusBarColor(color: Int) {
+ val statusBar = window.decorView.rootView.findViewById(R.id.status_bar)
+ if (statusBar != null) {
+ when {
+ VersionUtils.hasMarshmallow() -> statusBar.setBackgroundColor(color)
+ else -> statusBar.setBackgroundColor(
+ ColorUtil.darkenColor(
+ color
+ )
+ )
+ }
+ } else {
+ when {
+ VersionUtils.hasMarshmallow() -> window.statusBarColor = color
+ else -> window.statusBarColor = ColorUtil.darkenColor(color)
+ }
+ }
+ setLightStatusBarAuto(ATHUtil.resolveColor(this, R.attr.colorSurface))
+}
+
+fun AppCompatActivity.setStatusBarColorAuto() {
+ // we don't want to use statusbar color because we are doing the color darkening on our own to support KitKat
+ setStatusBarColor(ATHUtil.resolveColor(this, R.attr.colorSurface))
+ setLightStatusBarAuto(ATHUtil.resolveColor(this, R.attr.colorSurface))
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/extensions/FragmentMusicExtensions.kt b/app/src/main/java/code/name/monkey/retromusic/extensions/FragmentMusicExtensions.kt
new file mode 100644
index 000000000..c1998b6b0
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/extensions/FragmentMusicExtensions.kt
@@ -0,0 +1,39 @@
+package code.name.monkey.retromusic.extensions
+
+import android.net.Uri
+import android.webkit.MimeTypeMap
+import androidx.fragment.app.Fragment
+import code.name.monkey.retromusic.model.Song
+import code.name.monkey.retromusic.util.RetroUtil
+import org.jaudiotagger.audio.AudioFileIO
+import java.io.File
+import java.net.URLEncoder
+
+fun getSongInfo(song: Song): String {
+ val file = File(song.data)
+ if (file.exists()) {
+ return try {
+ val audioHeader = AudioFileIO.read(File(song.data)).audioHeader
+ val string: StringBuilder = StringBuilder()
+ val uriFile = Uri.fromFile(file)
+ string.append(getMimeType(uriFile.toString())).append(" • ")
+ string.append(audioHeader.bitRate).append(" kb/s").append(" • ")
+ string.append(RetroUtil.frequencyCount(audioHeader.sampleRate.toInt()))
+ .append(" kHz")
+ string.toString()
+ } catch (er: Exception) {
+ " - "
+ }
+ }
+ return "-"
+}
+
+private fun getMimeType(url: String): String {
+ var type: String? = MimeTypeMap.getFileExtensionFromUrl(
+ URLEncoder.encode(url, "utf-8")
+ ).uppercase()
+ if (type == null) {
+ type = url.substring(url.lastIndexOf(".") + 1)
+ }
+ return type
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/extensions/InsetsExtensions.kt b/app/src/main/java/code/name/monkey/retromusic/extensions/InsetsExtensions.kt
index b24168a33..8b6606b4c 100644
--- a/app/src/main/java/code/name/monkey/retromusic/extensions/InsetsExtensions.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/extensions/InsetsExtensions.kt
@@ -1,7 +1,9 @@
package code.name.monkey.retromusic.extensions
import androidx.core.view.WindowInsetsCompat
+import code.name.monkey.retromusic.util.RetroUtil
fun WindowInsetsCompat?.safeGetBottomInsets(): Int {
- return this?.getInsets(WindowInsetsCompat.Type.systemBars())?.bottom ?: 0
+ // Get Navbar heights if insets are null
+ return (this?.getInsets(WindowInsetsCompat.Type.systemBars())?.bottom ?: RetroUtil.getNavigationBarHeight())
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/extensions/ViewExtensions.kt b/app/src/main/java/code/name/monkey/retromusic/extensions/ViewExtensions.kt
index 270db6588..141540daa 100644
--- a/app/src/main/java/code/name/monkey/retromusic/extensions/ViewExtensions.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/extensions/ViewExtensions.kt
@@ -37,6 +37,7 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.imageview.ShapeableImageView
import com.google.android.material.shape.ShapeAppearanceModel
+
@Suppress("UNCHECKED_CAST")
fun ViewGroup.inflate(@LayoutRes layout: Int): T {
return LayoutInflater.from(context).inflate(layout, this, false) as T
@@ -67,21 +68,22 @@ fun View.translateYAnimate(value: Float): Animator {
.apply {
duration = 300
doOnStart {
- if (value == 0f) {
- show()
- }
+ show()
+ bringToFront()
}
doOnEnd {
if (value != 0f) {
hide()
+ } else {
+ show()
}
}
start()
}
}
-fun BottomSheetBehavior<*>.peekHeightAnimate(value: Int) {
- ObjectAnimator.ofInt(this, "peekHeight", value)
+fun BottomSheetBehavior<*>.peekHeightAnimate(value: Int): Animator {
+ return ObjectAnimator.ofInt(this, "peekHeight", value)
.apply {
duration = 300
start()
@@ -136,6 +138,7 @@ fun ShapeableImageView.setCircleShape(boolean: Boolean) {
* This will draw our view above the navigation bar instead of behind it by adding margins.
*/
fun View.drawAboveSystemBars(onlyPortrait: Boolean = true) {
+ if (PreferenceUtil.isFullScreenMode) return
if (onlyPortrait && RetroUtil.isLandscape()) return
// Create a snapshot of the view's margin state
val initialMargin = recordInitialMarginForView(this)
@@ -157,6 +160,7 @@ fun View.drawAboveSystemBars(onlyPortrait: Boolean = true) {
* This will draw our view above the navigation bar instead of behind it by adding padding.
*/
fun View.drawAboveSystemBarsWithPadding(consume: Boolean = false) {
+ if (PreferenceUtil.isFullScreenMode) return
val initialPadding = recordInitialPaddingForView(this)
ViewCompat.setOnApplyWindowInsetsListener(
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt
index dcf116c2e..171983cdf 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt
@@ -29,6 +29,7 @@ import code.name.monkey.retromusic.util.DensityUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
import java.io.File
class LibraryViewModel(
@@ -278,14 +279,16 @@ class LibraryViewModel(
}
emit(songs)
// Cleaning up deleted or moved songs
- songs.forEach { song ->
- if (!File(song.data).exists() || song.id == -1L) {
- repository.deleteSongInPlayCount(song.toPlayCount())
+ withContext(IO) {
+ songs.forEach { song ->
+ if (!File(song.data).exists() || song.id == -1L) {
+ repository.deleteSongInPlayCount(song.toPlayCount())
+ }
}
+ emit(repository.playCountSongs().map {
+ it.toSong()
+ })
}
- emit(repository.playCountSongs().map {
- it.toSong()
- })
}
fun artists(type: Int): LiveData> = liveData {
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumsFragment.kt
index e7d713b55..320632de8 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumsFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumsFragment.kt
@@ -196,7 +196,7 @@ class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment 0 && MusicPlayerRemote.playingQueue.isNotEmpty()) {
+ binding.recyclerView.updatePadding(bottom = dip(R.dimen.mini_player_height))
+ } else {
+ binding.recyclerView.updatePadding(bottom = 0)
+ }
}
private fun checkIsEmpty() {
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/settings/AbsSettingsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/settings/AbsSettingsFragment.kt
index 1fd169bc3..afdd8a9b6 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/settings/AbsSettingsFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/settings/AbsSettingsFragment.kt
@@ -19,15 +19,16 @@ import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.View
import android.widget.Toast
+import androidx.core.view.ViewCompat
import androidx.core.view.updatePadding
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceManager
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEPreferenceFragmentCompat
import code.name.monkey.retromusic.activities.OnThemeChangedListener
+import code.name.monkey.retromusic.extensions.safeGetBottomInsets
import code.name.monkey.retromusic.preferences.*
import code.name.monkey.retromusic.util.NavigationUtil
-import code.name.monkey.retromusic.util.RetroUtil
/**
* @author Hemanth S (h4h13).
@@ -66,16 +67,19 @@ abstract class AbsSettingsFragment : ATEPreferenceFragmentCompat() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setDivider(ColorDrawable(Color.TRANSPARENT))
- // This is a workaround as CollapsingToolbarLayout consumes insets and
- // insets are not passed to child views
+ // CollapsingToolbarLayout consumes insets and insets are not passed to child views
+ // So we get insets from root view
// https://github.com/material-components/material-components-android/issues/1310
- if (!RetroUtil.isLandscape()) {
- listView.updatePadding(bottom = RetroUtil.getNavigationBarHeight())
+ ViewCompat.setOnApplyWindowInsetsListener(
+ view
+ ) { _, insets ->
+ listView.updatePadding(bottom = insets.safeGetBottomInsets())
+ insets
}
invalidateSettings()
}
- override fun onDisplayPreferenceDialog(preference: Preference?) {
+ override fun onDisplayPreferenceDialog(preference: Preference) {
when (preference) {
is LibraryPreference -> {
val fragment = LibraryPreferenceDialog.newInstance()
diff --git a/app/src/main/java/code/name/monkey/retromusic/glide/RetroGlideExtension.kt b/app/src/main/java/code/name/monkey/retromusic/glide/RetroGlideExtension.kt
index 5f54bb943..9db983669 100644
--- a/app/src/main/java/code/name/monkey/retromusic/glide/RetroGlideExtension.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/glide/RetroGlideExtension.kt
@@ -33,10 +33,10 @@ import java.io.File
@GlideExtension
object RetroGlideExtension {
- private const val DEFAULT_ERROR_ARTIST_IMAGE =
+ private const val DEFAULT_ARTIST_IMAGE =
R.drawable.default_artist_art
- private const val DEFAULT_ERROR_SONG_IMAGE: Int = R.drawable.default_audio_art
- private const val DEFAULT_ERROR_ALBUM_IMAGE = R.drawable.default_album_art
+ private const val DEFAULT_SONG_IMAGE: Int = R.drawable.default_audio_art
+ private const val DEFAULT_ALBUM_IMAGE = R.drawable.default_album_art
private const val DEFAULT_ERROR_IMAGE_BANNER = R.drawable.material_design_default
private val DEFAULT_DISK_CACHE_STRATEGY_ARTIST = DiskCacheStrategy.RESOURCE
@@ -99,7 +99,8 @@ object RetroGlideExtension {
return baseRequestOptions
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY_ARTIST)
.priority(Priority.LOW)
- .error(DEFAULT_ERROR_ARTIST_IMAGE)
+ .error(DEFAULT_ARTIST_IMAGE)
+ .placeholder(DEFAULT_ARTIST_IMAGE)
.signature(createSignature(artist))
}
@@ -110,7 +111,8 @@ object RetroGlideExtension {
song: Song
): BaseRequestOptions<*> {
return baseRequestOptions.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
- .error(DEFAULT_ERROR_SONG_IMAGE)
+ .error(DEFAULT_SONG_IMAGE)
+ .placeholder(DEFAULT_SONG_IMAGE)
.signature(createSignature(song))
}
@@ -121,7 +123,8 @@ object RetroGlideExtension {
song: Song
): BaseRequestOptions<*> {
return baseRequestOptions.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
- .error(DEFAULT_ERROR_ALBUM_IMAGE)
+ .error(DEFAULT_ALBUM_IMAGE)
+ .placeholder(DEFAULT_ALBUM_IMAGE)
.signature(createSignature(song))
}
@@ -154,7 +157,7 @@ object RetroGlideExtension {
baseRequestOptions: BaseRequestOptions<*>
): BaseRequestOptions<*> {
return baseRequestOptions.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
- .error(DEFAULT_ERROR_ALBUM_IMAGE)
+ .error(DEFAULT_ALBUM_IMAGE)
}
private fun createSignature(song: Song): Key {
diff --git a/app/src/main/java/code/name/monkey/retromusic/glide/RetroMusicColoredTarget.kt b/app/src/main/java/code/name/monkey/retromusic/glide/RetroMusicColoredTarget.kt
index 195f7010b..6e92597f7 100644
--- a/app/src/main/java/code/name/monkey/retromusic/glide/RetroMusicColoredTarget.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/glide/RetroMusicColoredTarget.kt
@@ -33,8 +33,7 @@ abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(vi
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
- val colors = MediaNotificationProcessor(App.getContext(), errorDrawable)
- onColorReady(colors)
+ onColorReady(MediaNotificationProcessor.errorColor(App.getContext()))
}
override fun onResourceReady(
diff --git a/app/src/main/java/code/name/monkey/retromusic/helper/SortOrder.kt b/app/src/main/java/code/name/monkey/retromusic/helper/SortOrder.kt
index 6c5b8a69c..0771b2936 100644
--- a/app/src/main/java/code/name/monkey/retromusic/helper/SortOrder.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/helper/SortOrder.kt
@@ -54,11 +54,11 @@ class SortOrder {
const val ALBUM_Z_A = "$ALBUM_A_Z DESC"
/* Album sort order songs */
- const val ALBUM_NUMBER_OF_SONGS = MediaStore.Audio.AlbumColumns.NUMBER_OF_SONGS + " DESC"
+ const val ALBUM_NUMBER_OF_SONGS =
+ MediaStore.Audio.AlbumColumns.NUMBER_OF_SONGS + " DESC"
- /* Album sort order artist */
- const val ALBUM_ARTIST = (MediaStore.Audio.Artists.DEFAULT_SORT_ORDER +
- ", " + MediaStore.Audio.Albums.DEFAULT_SORT_ORDER)
+ /* Album Artist sort order artist */
+ const val ALBUM_ARTIST = "case when lower(album_artist) is null then 1 else 0 end, lower(album_artist)"
/* Album sort order year */
const val ALBUM_YEAR = MediaStore.Audio.Media.YEAR + " DESC"
diff --git a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java
index 0647dbc2c..d9946b82d 100644
--- a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java
+++ b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java
@@ -25,6 +25,7 @@ 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 android.app.NotificationManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.bluetooth.BluetoothDevice;
@@ -34,6 +35,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
+import android.content.pm.ServiceInfo;
import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.graphics.Point;
@@ -81,6 +83,7 @@ import code.name.monkey.retromusic.activities.LockScreenActivity;
import code.name.monkey.retromusic.appwidgets.AppWidgetBig;
import code.name.monkey.retromusic.appwidgets.AppWidgetCard;
import code.name.monkey.retromusic.appwidgets.AppWidgetClassic;
+import code.name.monkey.retromusic.appwidgets.AppWidgetMD3;
import code.name.monkey.retromusic.appwidgets.AppWidgetSmall;
import code.name.monkey.retromusic.appwidgets.AppWidgetText;
import code.name.monkey.retromusic.auto.AutoMediaIDHelper;
@@ -105,6 +108,7 @@ import code.name.monkey.retromusic.util.PreferenceUtil;
import code.name.monkey.retromusic.util.RetroUtil;
import code.name.monkey.retromusic.volume.AudioVolumeObserver;
import code.name.monkey.retromusic.volume.OnAudioVolumeChangedListener;
+import kotlin.Unit;
/**
* @author Karim Abou Zeid (kabouzeid), Andrew Neal
@@ -198,6 +202,8 @@ public class MusicService extends MediaBrowserServiceCompat
private final AppWidgetText appWidgetText = AppWidgetText.Companion.getInstance();
+ private final AppWidgetMD3 appWidgetMd3 = AppWidgetMD3.Companion.getInstance();
+
private final BroadcastReceiver widgetIntentReceiver =
new BroadcastReceiver() {
@Override
@@ -226,6 +232,10 @@ public class MusicService extends MediaBrowserServiceCompat
appWidgetText.performUpdate(MusicService.this, ids);
break;
}
+ case AppWidgetMD3.NAME: {
+ appWidgetMd3.performUpdate(MusicService.this, ids);
+ break;
+ }
}
}
}
@@ -273,7 +283,8 @@ public class MusicService extends MediaBrowserServiceCompat
new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
- updateNotification();
+ playingNotification.updateFavorite(getCurrentSong(), MusicService.this::startForegroundOrNotify);
+ startForegroundOrNotify();
}
};
private final BroadcastReceiver lockScreenReceiver =
@@ -356,6 +367,8 @@ public class MusicService extends MediaBrowserServiceCompat
private ThrottledSeekHandler throttledSeekHandler;
private Handler uiThreadHandler;
private PowerManager.WakeLock wakeLock;
+ private NotificationManager notificationManager;
+ private boolean isForeground = false;
private static Bitmap copy(Bitmap bitmap) {
Bitmap.Config config = bitmap.getConfig();
@@ -417,6 +430,10 @@ public class MusicService extends MediaBrowserServiceCompat
registerReceiver(updateFavoriteReceiver, new IntentFilter(FAVORITE_STATE_CHANGED));
registerReceiver(lockScreenReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
+ setSessionToken(mediaSession.getSessionToken());
+ if (VersionUtils.INSTANCE.hasMarshmallow()) {
+ notificationManager = getSystemService(NotificationManager.class);
+ }
initNotification();
mediaStoreObserver = new MediaStoreObserver(this, playerHandler);
@@ -467,7 +484,6 @@ public class MusicService extends MediaBrowserServiceCompat
mPackageValidator = new PackageValidator(this, R.xml.allowed_media_browser_callers);
mMusicProvider.setMusicService(this);
- setSessionToken(mediaSession.getSessionToken());
}
@Override
@@ -765,11 +781,10 @@ public class MusicService extends MediaBrowserServiceCompat
public void initNotification() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
&& !PreferenceUtil.INSTANCE.isClassicNotification()) {
- playingNotification = new PlayingNotificationImpl();
+ playingNotification = PlayingNotificationImpl.Companion.from(this, notificationManager, mediaSession);
} else {
- playingNotification = new PlayingNotificationOreo();
+ playingNotification = PlayingNotificationOreo.Companion.from(this, notificationManager);
}
- playingNotification.init(this);
}
public boolean isLastTrack() {
@@ -837,7 +852,8 @@ public class MusicService extends MediaBrowserServiceCompat
// Request from an untrusted package: return an empty browser root
return new BrowserRoot(AutoMediaIDHelper.MEDIA_ID_EMPTY_ROOT, null);
} else {
- /** By default return the browsable root. Treat the EXTRA_RECENT flag as a special case
+ /**
+ * By default return the browsable root. Treat the EXTRA_RECENT flag as a special case
* and return the recent root instead.
*/
boolean isRecentRequest = false;
@@ -882,7 +898,7 @@ public class MusicService extends MediaBrowserServiceCompat
/* Switch to MultiPlayer if Crossfade duration is 0 and
Playback is not an instance of MultiPlayer */
if (playback != null)
- playback.setCrossFadeDuration(PreferenceUtil.INSTANCE.getCrossFadeDuration());
+ playback.setCrossFadeDuration(PreferenceUtil.INSTANCE.getCrossFadeDuration());
if (!(playback instanceof MultiPlayer) && PreferenceUtil.INSTANCE.getCrossFadeDuration() == 0) {
if (playback != null) {
playback.release();
@@ -1042,6 +1058,7 @@ public class MusicService extends MediaBrowserServiceCompat
}
public void pause() {
+ Log.i(TAG, "Paused");
pausedByTransientLossOfFocus = false;
if (playback != null && playback.isPlaying()) {
startFadeAnimator(playback, false, () -> {
@@ -1163,7 +1180,8 @@ public class MusicService extends MediaBrowserServiceCompat
public void quit() {
pause();
- playingNotification.stop();
+ stopForeground(true);
+ notificationManager.cancel(PlayingNotification.NOTIFICATION_ID);
closeAudioEffectSession();
getAudioManager().abandonAudioFocus(audioFocusListener);
@@ -1326,7 +1344,8 @@ public class MusicService extends MediaBrowserServiceCompat
public void updateNotification() {
if (playingNotification != null && getCurrentSong().getId() != -1) {
- playingNotification.update();
+ stopForegroundAndNotification();
+ initNotification();
}
}
@@ -1400,17 +1419,19 @@ public class MusicService extends MediaBrowserServiceCompat
private void handleChangeInternal(@NonNull final String what) {
switch (what) {
case PLAY_STATE_CHANGED:
- updateNotification();
updateMediaSessionPlaybackState();
final boolean isPlaying = isPlaying();
if (!isPlaying && getSongProgressMillis() > 0) {
savePositionInTrack();
}
songPlayCountHelper.notifyPlayStateChanged(isPlaying);
+ playingNotification.setPlaying(isPlaying);
+ startForegroundOrNotify();
break;
case FAVORITE_STATE_CHANGED:
+ playingNotification.updateFavorite(getCurrentSong(), this::startForegroundOrNotify);
case META_CHANGED:
- updateNotification();
+ playingNotification.updateMetadata(getCurrentSong(), this::startForegroundOrNotify);
updateMediaSessionMetaData();
updateMediaSessionPlaybackState();
savePosition();
@@ -1428,12 +1449,41 @@ public class MusicService extends MediaBrowserServiceCompat
if (playingQueue.size() > 0) {
prepareNext();
} else {
- playingNotification.stop();
+ stopForegroundAndNotification();
}
break;
}
}
+ private Unit startForegroundOrNotify() {
+ if (!isForeground) {
+ // Specify that this is a media service, if supported.
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ startForeground(
+ PlayingNotification.NOTIFICATION_ID, playingNotification.build(),
+ ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
+ );
+ } else {
+ startForeground(PlayingNotification.NOTIFICATION_ID, playingNotification.build());
+ }
+
+ isForeground = true;
+ } else {
+ // If we are already in foreground just update the notification
+ notificationManager.notify(
+ PlayingNotification.NOTIFICATION_ID, playingNotification.build()
+ );
+ }
+ return Unit.INSTANCE;
+ }
+
+ private void stopForegroundAndNotification() {
+ stopForeground(true);
+ notificationManager.cancel(PlayingNotification.NOTIFICATION_ID);
+
+ isForeground = false;
+ }
+
private boolean openCurrent() {
synchronized (this) {
try {
@@ -1551,6 +1601,7 @@ public class MusicService extends MediaBrowserServiceCompat
appWidgetSmall.notifyChange(this, what);
appWidgetCard.notifyChange(this, what);
appWidgetText.notifyChange(this, what);
+ appWidgetMd3.notifyChange(this, what);
}
private void setCustomAction(PlaybackStateCompat.Builder stateBuilder) {
@@ -1592,8 +1643,8 @@ public class MusicService extends MediaBrowserServiceCompat
mediaButtonIntent.setComponent(mediaButtonReceiverComponentName);
PendingIntent mediaButtonReceiverPendingIntent;
- mediaButtonReceiverPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent,
- VersionUtils.INSTANCE.hasMarshmallow() ? PendingIntent.FLAG_IMMUTABLE : 0);
+ mediaButtonReceiverPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent,
+ VersionUtils.INSTANCE.hasMarshmallow() ? PendingIntent.FLAG_IMMUTABLE : 0);
mediaSession = new MediaSessionCompat(
this,
diff --git a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotification.kt b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotification.kt
index 5557a285e..162775f06 100644
--- a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotification.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotification.kt
@@ -15,95 +15,51 @@
package code.name.monkey.retromusic.service.notification
-import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
-import android.content.Context.NOTIFICATION_SERVICE
-import android.content.pm.ServiceInfo
-import android.os.Build
+import android.content.Context
import androidx.annotation.RequiresApi
+import androidx.core.app.NotificationCompat
import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.service.MusicService
+import code.name.monkey.retromusic.model.Song
-abstract class PlayingNotification {
- protected lateinit var service: MusicService
- protected var stopped: Boolean = false
- private var notifyMode = NOTIFY_MODE_BACKGROUND
- private var notificationManager: NotificationManager? = null
+abstract class PlayingNotification(context: Context) :
+ NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) {
+ abstract fun updateMetadata(song: Song, onUpdate: () -> Unit)
- @Synchronized
- fun init(service: MusicService) {
- this.service = service
- notificationManager = service.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- createNotificationChannel()
- }
- }
+ abstract fun setPlaying(isPlaying: Boolean)
- abstract fun update()
-
- @Synchronized
- fun stop() {
- stopped = true
- service.stopForeground(true)
- notificationManager!!.cancel(NOTIFICATION_ID)
- }
-
- internal fun updateNotifyModeAndPostNotification(notification: Notification) {
- val newNotifyMode: Int = if (service.isPlaying) {
- NOTIFY_MODE_FOREGROUND
- } else {
- NOTIFY_MODE_BACKGROUND
- }
-
- if (notifyMode != newNotifyMode && newNotifyMode == NOTIFY_MODE_BACKGROUND) {
- service.stopForeground(false)
- }
-
- if (newNotifyMode == NOTIFY_MODE_FOREGROUND) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- service.startForeground(
- NOTIFICATION_ID,
- notification,
- ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
- )
- } else {
- service.startForeground(NOTIFICATION_ID,notification)
- }
- } else if (newNotifyMode == NOTIFY_MODE_BACKGROUND) {
- notificationManager!!.notify(NOTIFICATION_ID, notification)
- }
-
- notifyMode = newNotifyMode
- }
-
- @RequiresApi(26)
- private fun createNotificationChannel() {
- var notificationChannel: NotificationChannel? = notificationManager!!
- .getNotificationChannel(NOTIFICATION_CHANNEL_ID)
- if (notificationChannel == null) {
- notificationChannel = NotificationChannel(
- NOTIFICATION_CHANNEL_ID,
- service.getString(R.string.playing_notification_name),
- NotificationManager.IMPORTANCE_LOW
- )
- notificationChannel.description =
- service.getString(R.string.playing_notification_description)
- notificationChannel.enableLights(false)
- notificationChannel.enableVibration(false)
- notificationChannel.setShowBadge(false)
-
- notificationManager!!.createNotificationChannel(notificationChannel)
- }
- }
+ abstract fun updateFavorite(song: Song, onUpdate: () -> Unit)
companion object {
const val NOTIFICATION_CONTROLS_SIZE_MULTIPLIER = 1.0f
internal const val NOTIFICATION_CHANNEL_ID = "playing_notification"
- private const val NOTIFICATION_ID = 1
- private const val NOTIFY_MODE_FOREGROUND = 1
- private const val NOTIFY_MODE_BACKGROUND = 0
+ const val NOTIFICATION_ID = 1
+
+
+ @RequiresApi(26)
+ fun createNotificationChannel(
+ context: Context,
+ notificationManager: NotificationManager
+ ) {
+ var notificationChannel: NotificationChannel? = notificationManager
+ .getNotificationChannel(NOTIFICATION_CHANNEL_ID)
+ if (notificationChannel == null) {
+ notificationChannel = NotificationChannel(
+ NOTIFICATION_CHANNEL_ID,
+ context.getString(R.string.playing_notification_name),
+ NotificationManager.IMPORTANCE_LOW
+ )
+ notificationChannel.description =
+ context.getString(R.string.playing_notification_description)
+ notificationChannel.enableLights(false)
+ notificationChannel.enableVibration(false)
+ notificationChannel.setShowBadge(false)
+
+ notificationManager.createNotificationChannel(notificationChannel)
+ }
+ }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt
index 3cca67a25..49d43a877 100644
--- a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt
@@ -14,14 +14,16 @@
package code.name.monkey.retromusic.service.notification
+import android.annotation.SuppressLint
+import android.app.NotificationManager
import android.app.PendingIntent
import android.content.ComponentName
+import android.content.Context
import android.content.Intent
-import android.graphics.Bitmap
-import android.graphics.BitmapFactory
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Build
+import android.support.v4.media.session.MediaSessionCompat
import androidx.core.app.NotificationCompat
import androidx.core.text.HtmlCompat
import androidx.media.app.NotificationCompat.MediaStyle
@@ -33,177 +35,196 @@ import code.name.monkey.retromusic.db.toSongEntity
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
+import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.service.MusicService.*
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroColorUtil
-import com.bumptech.glide.Glide
-import com.bumptech.glide.request.target.SimpleTarget
-import com.bumptech.glide.request.target.Target
+import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
+import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
-import org.koin.core.component.KoinComponent
+import kotlinx.coroutines.withContext
-class PlayingNotificationImpl : PlayingNotification(), KoinComponent {
- private var target: Target? = null
+@SuppressLint("RestrictedApi")
+class PlayingNotificationImpl(
+ val context: Context,
+ mediaSessionToken: MediaSessionCompat.Token
+) : PlayingNotification(context) {
- @Synchronized
- override fun update() {
- stopped = false
- GlobalScope.launch {
- val song = service.currentSong
+ init {
+ val action = Intent(context, MainActivity::class.java)
+ action.putExtra(MainActivity.EXPAND_PANEL, PreferenceUtil.isExpandPanel)
+ action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
+ val clickIntent =
+ PendingIntent.getActivity(
+ context,
+ 0,
+ action,
+ PendingIntent.FLAG_UPDATE_CURRENT or if (VersionUtils.hasMarshmallow())
+ PendingIntent.FLAG_IMMUTABLE
+ else 0
+ )
+
+ val serviceName = ComponentName(context, MusicService::class.java)
+ val intent = Intent(ACTION_QUIT)
+ intent.component = serviceName
+ val deleteIntent = PendingIntent.getService(
+ context,
+ 0,
+ intent,
+ PendingIntent.FLAG_UPDATE_CURRENT or (if (VersionUtils.hasMarshmallow())
+ PendingIntent.FLAG_IMMUTABLE
+ else 0)
+ )
+ val toggleFavorite = buildFavoriteAction(false)
+ val playPauseAction = buildPlayAction(true)
+ val previousAction = NotificationCompat.Action(
+ R.drawable.ic_skip_previous_round_white_32dp,
+ context.getString(R.string.action_previous),
+ retrievePlaybackAction(ACTION_REWIND)
+ )
+ val nextAction = NotificationCompat.Action(
+ R.drawable.ic_skip_next_round_white_32dp,
+ context.getString(R.string.action_next),
+ retrievePlaybackAction(ACTION_SKIP)
+ )
+ val dismissAction = NotificationCompat.Action(
+ R.drawable.ic_close,
+ context.getString(R.string.customactivityoncrash_error_activity_error_details_close),
+ retrievePlaybackAction(ACTION_QUIT)
+ )
+ setSmallIcon(R.drawable.ic_notification)
+ setContentIntent(clickIntent)
+ setDeleteIntent(deleteIntent)
+ setShowWhen(false)
+ addAction(toggleFavorite)
+ addAction(previousAction)
+ addAction(playPauseAction)
+ addAction(nextAction)
+ addAction(dismissAction)
+
+ setStyle(
+ MediaStyle()
+ .setMediaSession(mediaSessionToken)
+ .setShowActionsInCompactView(1, 2, 3)
+ )
+ setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ if (Build.VERSION.SDK_INT <=
+ Build.VERSION_CODES.O && PreferenceUtil.isColoredNotification
+ ) {
+ this.color = color
+ }
+ }
+
+ override fun updateMetadata(song: Song, onUpdate: () -> Unit) {
+ setContentTitle(song.title)
+ setContentText(
+ HtmlCompat.fromHtml(
+ "" + song.albumName + "",
+ HtmlCompat.FROM_HTML_MODE_LEGACY
+ )
+ )
+ val bigNotificationImageSize = context.resources
+ .getDimensionPixelSize(R.dimen.notification_big_image_size)
+ GlideApp.with(context).asBitmapPalette().songCoverOptions(song)
+ .load(RetroGlideExtension.getSongModel(song))
+ //.checkIgnoreMediaStore()
+ .centerCrop()
+ .into(object : CustomTarget(
+ bigNotificationImageSize,
+ bigNotificationImageSize
+ ) {
+ override fun onResourceReady(
+ resource: BitmapPaletteWrapper,
+ transition: Transition?
+ ) {
+ setLargeIcon(
+ resource.bitmap
+ )
+ if (Build.VERSION.SDK_INT <=
+ Build.VERSION_CODES.O && PreferenceUtil.isColoredNotification
+ ) {
+ color = RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT)
+ }
+ onUpdate()
+ }
+
+ override fun onLoadFailed(errorDrawable: Drawable?) {
+ super.onLoadFailed(errorDrawable)
+ setLargeIcon(null)
+ onUpdate()
+ }
+
+ override fun onLoadCleared(placeholder: Drawable?) {
+ setLargeIcon(null)
+ onUpdate()
+ }
+ })
+ }
+
+ private fun buildPlayAction(isPlaying: Boolean): NotificationCompat.Action {
+ val playButtonResId =
+ if (isPlaying) R.drawable.ic_pause_white_48dp else R.drawable.ic_play_arrow_white_48dp
+ return NotificationCompat.Action.Builder(
+ playButtonResId,
+ context.getString(R.string.action_play_pause),
+ retrievePlaybackAction(ACTION_TOGGLE_PAUSE)
+ ).build()
+ }
+
+ private fun buildFavoriteAction(isFavorite: Boolean): NotificationCompat.Action {
+ val favoriteResId =
+ if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border
+ return NotificationCompat.Action.Builder(
+ favoriteResId,
+ context.getString(R.string.action_toggle_favorite),
+ retrievePlaybackAction(TOGGLE_FAVORITE)
+ ).build()
+ }
+
+ override fun setPlaying(isPlaying: Boolean) {
+ mActions[2] = buildPlayAction(isPlaying)
+ }
+
+ override fun updateFavorite(song: Song, onUpdate: () -> Unit) {
+ GlobalScope.launch(Dispatchers.IO) {
val playlist: PlaylistEntity = MusicUtil.repository.favoritePlaylist()
- val isPlaying = service.isPlaying
val isFavorite = if (playlist != null) {
val songEntity = song.toSongEntity(playlist.playListId)
MusicUtil.repository.isFavoriteSong(songEntity).isNotEmpty()
} else false
-
- val playButtonResId =
- if (isPlaying) R.drawable.ic_pause_white_48dp else R.drawable.ic_play_arrow_white_48dp
- val favoriteResId =
- if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border
-
- val action = Intent(service, MainActivity::class.java)
- action.putExtra(MainActivity.EXPAND_PANEL, PreferenceUtil.isExpandPanel)
- action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
- val clickIntent =
- PendingIntent.getActivity(
- service, 0, action, if (VersionUtils.hasMarshmallow())
- PendingIntent.FLAG_IMMUTABLE
- else 0 or PendingIntent.FLAG_UPDATE_CURRENT
- )
-
- val serviceName = ComponentName(service, MusicService::class.java)
- val intent = Intent(ACTION_QUIT)
- intent.component = serviceName
- val deleteIntent = PendingIntent.getService(
- service,
- 0,
- intent,
- if (VersionUtils.hasMarshmallow())
- PendingIntent.FLAG_IMMUTABLE
- else 0 or PendingIntent.FLAG_UPDATE_CURRENT
- )
- val bigNotificationImageSize = service.resources
- .getDimensionPixelSize(R.dimen.notification_big_image_size)
- service.runOnUiThread {
- if (target != null) {
- Glide.with(service).clear(target)
- }
- target = GlideApp.with(service).asBitmapPalette().songCoverOptions(song)
- .load(RetroGlideExtension.getSongModel(song))
- //.checkIgnoreMediaStore()
- .centerCrop()
- .into(object : SimpleTarget(
- bigNotificationImageSize,
- bigNotificationImageSize
- ) {
- override fun onResourceReady(
- resource: BitmapPaletteWrapper,
- transition: Transition?
- ) {
- update(
- resource.bitmap,
- RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT)
- )
- }
-
- override fun onLoadFailed(errorDrawable: Drawable?) {
- super.onLoadFailed(errorDrawable)
- update(null, Color.TRANSPARENT)
- }
-
- fun update(bitmap: Bitmap?, color: Int) {
- var bitmapFinal = bitmap
- if (bitmapFinal == null) {
- bitmapFinal = BitmapFactory.decodeResource(
- service.resources,
- R.drawable.default_audio_art
- )
- }
-
- val toggleFavorite = NotificationCompat.Action(
- favoriteResId,
- service.getString(R.string.action_toggle_favorite),
- retrievePlaybackAction(TOGGLE_FAVORITE)
- )
- val playPauseAction = NotificationCompat.Action(
- playButtonResId,
- service.getString(R.string.action_play_pause),
- retrievePlaybackAction(ACTION_TOGGLE_PAUSE)
- )
- val previousAction = NotificationCompat.Action(
- R.drawable.ic_skip_previous_round_white_32dp,
- service.getString(R.string.action_previous),
- retrievePlaybackAction(ACTION_REWIND)
- )
- val nextAction = NotificationCompat.Action(
- R.drawable.ic_skip_next_round_white_32dp,
- service.getString(R.string.action_next),
- retrievePlaybackAction(ACTION_SKIP)
- )
-
- val builder = NotificationCompat.Builder(
- service,
- NOTIFICATION_CHANNEL_ID
- )
- .setSmallIcon(R.drawable.ic_notification)
- .setLargeIcon(bitmapFinal)
- .setContentIntent(clickIntent)
- .setDeleteIntent(deleteIntent)
- .setContentTitle(
- HtmlCompat.fromHtml(
- "" + song.title + "",
- HtmlCompat.FROM_HTML_MODE_LEGACY
- )
- )
- .setContentText(song.artistName)
- .setSubText(
- HtmlCompat.fromHtml(
- "" + song.albumName + "",
- HtmlCompat.FROM_HTML_MODE_LEGACY
- )
- )
- .setOngoing(isPlaying)
- .setShowWhen(false)
- .addAction(toggleFavorite)
- .addAction(previousAction)
- .addAction(playPauseAction)
- .addAction(nextAction)
-
- builder.setStyle(
- MediaStyle()
- .setMediaSession(service.mediaSession.sessionToken)
- .setShowActionsInCompactView(1, 2, 3)
- )
- .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
- if (Build.VERSION.SDK_INT <=
- Build.VERSION_CODES.O && PreferenceUtil.isColoredNotification
- ) {
- builder.color = color
- }
-
- if (stopped) {
- return // notification has been stopped before loading was finished
- }
- updateNotifyModeAndPostNotification(builder.build())
- }
- })
+ withContext(Dispatchers.Main) {
+ mActions[0] = buildFavoriteAction(isFavorite)
+ onUpdate()
}
}
}
private fun retrievePlaybackAction(action: String): PendingIntent {
- val serviceName = ComponentName(service, MusicService::class.java)
+ val serviceName = ComponentName(context, MusicService::class.java)
val intent = Intent(action)
intent.component = serviceName
return PendingIntent.getService(
- service, 0, intent,
- if (VersionUtils.hasMarshmallow()) PendingIntent.FLAG_IMMUTABLE
- else 0 or PendingIntent.FLAG_UPDATE_CURRENT
+ context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or
+ if (VersionUtils.hasMarshmallow()) PendingIntent.FLAG_IMMUTABLE
+ else 0
)
}
+
+ companion object {
+
+ fun from(
+ context: Context,
+ notificationManager: NotificationManager,
+ mediaSession: MediaSessionCompat
+ ): PlayingNotification {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ createNotificationChannel(context, notificationManager)
+ }
+ return PlayingNotificationImpl(context, mediaSession.sessionToken)
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationOreo.kt b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationOreo.kt
index 29ff52875..a314ca2e5 100644
--- a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationOreo.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationOreo.kt
@@ -14,6 +14,8 @@
package code.name.monkey.retromusic.service.notification
+import android.annotation.SuppressLint
+import android.app.NotificationManager
import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context
@@ -21,6 +23,7 @@ import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.drawable.Drawable
+import android.os.Build
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import code.name.monkey.appthemehelper.util.ATHUtil.resolveColor
@@ -29,6 +32,7 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity
+import code.name.monkey.retromusic.extensions.surfaceColor
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
@@ -39,224 +43,231 @@ import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil
import code.name.monkey.retromusic.util.RetroUtil.createBitmap
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
-import com.bumptech.glide.Glide
-import com.bumptech.glide.request.target.SimpleTarget
-import com.bumptech.glide.request.target.Target
+import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
/**
* @author Hemanth S (h4h13).
*/
-class PlayingNotificationOreo : PlayingNotification() {
+@SuppressLint("RestrictedApi")
+class PlayingNotificationOreo(
+ val context: Context
+) : PlayingNotification(context) {
- private var target: Target? = null
+ private var primaryColor: Int = 0
- private fun getCombinedRemoteViews(collapsed: Boolean, song: Song): RemoteViews {
- val remoteViews = RemoteViews(
- service.packageName,
- if (collapsed) R.layout.layout_notification_collapsed else R.layout.layout_notification_expanded
- )
- remoteViews.setTextViewText(
- R.id.appName,
- service.getString(R.string.app_name) + " • " + song.albumName
- )
- remoteViews.setTextViewText(R.id.title, song.title)
- remoteViews.setTextViewText(R.id.subtitle, song.artistName)
- linkButtons(remoteViews)
- return remoteViews
- }
+ init {
+ val notificationLayout = getCombinedRemoteViews(true)
+ val notificationLayoutBig = getCombinedRemoteViews(false)
- override fun update() {
- stopped = false
- val song = service.currentSong
- val isPlaying = service.isPlaying
-
- val notificationLayout = getCombinedRemoteViews(true, song)
- val notificationLayoutBig = getCombinedRemoteViews(false, song)
-
- val action = Intent(service, MainActivity::class.java)
+ val action = Intent(context, MainActivity::class.java)
action.putExtra(MainActivity.EXPAND_PANEL, PreferenceUtil.isExpandPanel)
action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
val clickIntent = PendingIntent
.getActivity(
- service,
+ context,
0,
action,
PendingIntent.FLAG_UPDATE_CURRENT or if (VersionUtils.hasMarshmallow())
PendingIntent.FLAG_IMMUTABLE
else 0
)
- val deleteIntent = buildPendingIntent(service, ACTION_QUIT, null)
+ val deleteIntent = buildPendingIntent(context, ACTION_QUIT, null)
- val builder = NotificationCompat.Builder(service, NOTIFICATION_CHANNEL_ID)
- .setSmallIcon(R.drawable.ic_notification)
- .setContentIntent(clickIntent)
- .setDeleteIntent(deleteIntent)
- .setCategory(NotificationCompat.CATEGORY_SERVICE)
- .setPriority(NotificationCompat.PRIORITY_MAX)
- .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
- .setCustomContentView(notificationLayout)
- .setCustomBigContentView(notificationLayoutBig)
- .setOngoing(isPlaying)
-
- val bigNotificationImageSize = service.resources
- .getDimensionPixelSize(R.dimen.notification_big_image_size)
- service.runOnUiThread {
- if (target != null) {
- Glide.with(service).clear(target)
- }
- target = GlideApp.with(service).asBitmapPalette().songCoverOptions(song)
- .load(RetroGlideExtension.getSongModel(song))
- .centerCrop()
- .into(object : SimpleTarget(
- bigNotificationImageSize,
- bigNotificationImageSize
- ) {
- override fun onResourceReady(
- resource: BitmapPaletteWrapper,
- transition: Transition?
- ) {
- /* val mediaNotificationProcessor = MediaNotificationProcessor(
- service,
- service
- ) { i, _ -> update(resource.bitmap, i) }
- mediaNotificationProcessor.processNotification(resource.bitmap)*/
-
- val colors = MediaNotificationProcessor(service, resource.bitmap)
- update(resource.bitmap, colors.backgroundColor)
- }
-
- override fun onLoadFailed(errorDrawable: Drawable?) {
- super.onLoadFailed(errorDrawable)
- update(
- null,
- resolveColor(service, R.attr.colorSurface, Color.WHITE)
- )
- }
-
- private fun update(bitmap: Bitmap?, bgColor: Int) {
- var bgColorFinal = bgColor
- if (bitmap != null) {
- notificationLayout.setImageViewBitmap(R.id.largeIcon, bitmap)
- notificationLayoutBig.setImageViewBitmap(R.id.largeIcon, bitmap)
- } else {
- notificationLayout.setImageViewResource(
- R.id.largeIcon,
- R.drawable.default_audio_art
- )
- notificationLayoutBig.setImageViewResource(
- R.id.largeIcon,
- R.drawable.default_audio_art
- )
- }
-
- // Android 12 applies a standard Notification template to every notification
- // which will in turn have a default background so setting a different background
- // than that, looks weird
- if (!VersionUtils.hasS()) {
- if (!PreferenceUtil.isColoredNotification) {
- bgColorFinal =
- resolveColor(service, R.attr.colorPrimary, Color.WHITE)
- }
- setBackgroundColor(bgColorFinal)
- }
- setNotificationContent(ColorUtil.isColorLight(bgColorFinal))
-
- if (stopped) {
- return // notification has been stopped before loading was finished
- }
- updateNotifyModeAndPostNotification(builder.build())
- }
-
- private fun setBackgroundColor(color: Int) {
- notificationLayout.setInt(R.id.image, "setBackgroundColor", color)
- notificationLayoutBig.setInt(R.id.image, "setBackgroundColor", color)
- }
-
- private fun setNotificationContent(dark: Boolean) {
- val primary = MaterialValueHelper.getPrimaryTextColor(service, dark)
- val secondary = MaterialValueHelper.getSecondaryTextColor(service, dark)
-
- val close = createBitmap(
- RetroUtil.getTintedVectorDrawable(
- service,
- R.drawable.ic_close,
- primary
- ), NOTIFICATION_CONTROLS_SIZE_MULTIPLIER
- )
- val prev = createBitmap(
- RetroUtil.getTintedVectorDrawable(
- service,
- R.drawable.ic_skip_previous_round_white_32dp,
- primary
- ), NOTIFICATION_CONTROLS_SIZE_MULTIPLIER
- )
- val next = createBitmap(
- RetroUtil.getTintedVectorDrawable(
- service,
- R.drawable.ic_skip_next_round_white_32dp,
- primary
- ), NOTIFICATION_CONTROLS_SIZE_MULTIPLIER
- )
- val playPause = createBitmap(
- RetroUtil.getTintedVectorDrawable(
- service,
- if (isPlaying)
- R.drawable.ic_pause_white_48dp
- else
- R.drawable.ic_play_arrow_white_48dp, primary
- ), NOTIFICATION_CONTROLS_SIZE_MULTIPLIER
- )
-
- notificationLayout.setTextColor(R.id.title, primary)
- notificationLayout.setTextColor(R.id.subtitle, secondary)
- notificationLayout.setTextColor(R.id.appName, secondary)
-
- notificationLayout.setImageViewBitmap(R.id.action_prev, prev)
- notificationLayout.setImageViewBitmap(R.id.action_next, next)
- notificationLayout.setImageViewBitmap(R.id.action_play_pause, playPause)
-
- notificationLayoutBig.setTextColor(R.id.title, primary)
- notificationLayoutBig.setTextColor(R.id.subtitle, secondary)
- notificationLayoutBig.setTextColor(R.id.appName, secondary)
-
- notificationLayoutBig.setImageViewBitmap(R.id.action_quit, close)
- notificationLayoutBig.setImageViewBitmap(R.id.action_prev, prev)
- notificationLayoutBig.setImageViewBitmap(R.id.action_next, next)
- notificationLayoutBig.setImageViewBitmap(R.id.action_play_pause, playPause)
-
- notificationLayout.setImageViewBitmap(
- R.id.smallIcon,
- createBitmap(
- RetroUtil.getTintedVectorDrawable(
- service,
- R.drawable.ic_notification,
- secondary
- ), 0.6f
- )
- )
- notificationLayoutBig.setImageViewBitmap(
- R.id.smallIcon,
- createBitmap(
- RetroUtil.getTintedVectorDrawable(
- service,
- R.drawable.ic_notification,
- secondary
- ), 0.6f
- )
- )
-
- }
- })
- }
-
- if (stopped) {
- return // notification has been stopped before loading was finished
- }
- updateNotifyModeAndPostNotification(builder.build())
+ setSmallIcon(R.drawable.ic_notification)
+ setContentIntent(clickIntent)
+ setDeleteIntent(deleteIntent)
+ setCategory(NotificationCompat.CATEGORY_SERVICE)
+ priority = NotificationCompat.PRIORITY_MAX
+ setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ setCustomContentView(notificationLayout)
+ setCustomBigContentView(notificationLayoutBig)
+ setOngoing(true)
}
+ private fun getCombinedRemoteViews(collapsed: Boolean): RemoteViews {
+ val remoteViews = RemoteViews(
+ context.packageName,
+ if (collapsed) R.layout.layout_notification_collapsed else R.layout.layout_notification_expanded
+ )
+ linkButtons(remoteViews)
+ return remoteViews
+ }
+
+ @SuppressLint("RestrictedApi")
+ override fun updateMetadata(song: Song, onUpdate: () -> Unit) {
+ val bigNotificationImageSize = context.resources
+ .getDimensionPixelSize(R.dimen.notification_big_image_size)
+ GlideApp.with(context).asBitmapPalette().songCoverOptions(song)
+ .load(RetroGlideExtension.getSongModel(song))
+ .centerCrop()
+ .into(object : CustomTarget(
+ bigNotificationImageSize,
+ bigNotificationImageSize
+ ) {
+ override fun onResourceReady(
+ resource: BitmapPaletteWrapper,
+ transition: Transition?
+ ) {
+ val colors = MediaNotificationProcessor(context, resource.bitmap)
+ update(resource.bitmap, colors.backgroundColor)
+ }
+
+ override fun onLoadFailed(errorDrawable: Drawable?) {
+ super.onLoadFailed(errorDrawable)
+ update(
+ null,
+ resolveColor(context, R.attr.colorSurface, Color.WHITE)
+ )
+ }
+
+ override fun onLoadCleared(placeholder: Drawable?) {
+ }
+
+ private fun update(bitmap: Bitmap?, bgColor: Int) {
+ var bgColorFinal = bgColor
+ if (bitmap != null) {
+ contentView.setImageViewBitmap(R.id.largeIcon, bitmap)
+ bigContentView.setImageViewBitmap(R.id.largeIcon, bitmap)
+ } else {
+ contentView.setImageViewResource(
+ R.id.largeIcon,
+ R.drawable.default_audio_art
+ )
+ bigContentView.setImageViewResource(
+ R.id.largeIcon,
+ R.drawable.default_audio_art
+ )
+ }
+
+ // Android 12 applies a standard Notification template to every notification
+ // which will in turn have a default background so setting a different background
+ // than that, looks weird
+ if (!VersionUtils.hasS()) {
+ if (!PreferenceUtil.isColoredNotification) {
+ bgColorFinal =
+ resolveColor(context, R.attr.colorSurface, Color.WHITE)
+ }
+ setBackgroundColor(bgColorFinal)
+ setNotificationContent(ColorUtil.isColorLight(bgColorFinal))
+ }else {
+ setNotificationContent(!ColorUtil.isColorLight(context.surfaceColor()))
+ }
+ onUpdate()
+ }
+
+ private fun setBackgroundColor(color: Int) {
+ contentView.setInt(R.id.image, "setBackgroundColor", color)
+ bigContentView.setInt(R.id.image, "setBackgroundColor", color)
+ }
+
+ private fun setNotificationContent(dark: Boolean) {
+ val primary = MaterialValueHelper.getPrimaryTextColor(context, dark)
+ val secondary = MaterialValueHelper.getSecondaryTextColor(context, dark)
+ primaryColor = primary
+
+ val close = createBitmap(
+ RetroUtil.getTintedVectorDrawable(
+ context,
+ R.drawable.ic_close,
+ primary
+ ), NOTIFICATION_CONTROLS_SIZE_MULTIPLIER
+ )
+ val prev = createBitmap(
+ RetroUtil.getTintedVectorDrawable(
+ context,
+ R.drawable.ic_skip_previous_round_white_32dp,
+ primary
+ ), NOTIFICATION_CONTROLS_SIZE_MULTIPLIER
+ )
+ val next = createBitmap(
+ RetroUtil.getTintedVectorDrawable(
+ context,
+ R.drawable.ic_skip_next_round_white_32dp,
+ primary
+ ), NOTIFICATION_CONTROLS_SIZE_MULTIPLIER
+ )
+ val playPause = getPlayPauseBitmap(true)
+
+ contentView.setTextColor(R.id.title, primary)
+ contentView.setTextColor(R.id.subtitle, secondary)
+ contentView.setTextColor(R.id.appName, secondary)
+
+ contentView.setImageViewBitmap(R.id.action_prev, prev)
+ contentView.setImageViewBitmap(R.id.action_next, next)
+ contentView.setImageViewBitmap(R.id.action_play_pause, playPause)
+
+ contentView.setTextViewText(
+ R.id.appName,
+ context.getString(R.string.app_name) + " • " + song.albumName
+ )
+ contentView.setTextViewText(R.id.title, song.title)
+ contentView.setTextViewText(R.id.subtitle, song.artistName)
+
+
+ bigContentView.setTextColor(R.id.title, primary)
+ bigContentView.setTextColor(R.id.subtitle, secondary)
+ bigContentView.setTextColor(R.id.appName, secondary)
+
+ bigContentView.setImageViewBitmap(R.id.action_quit, close)
+ bigContentView.setImageViewBitmap(R.id.action_prev, prev)
+ bigContentView.setImageViewBitmap(R.id.action_next, next)
+ bigContentView.setImageViewBitmap(R.id.action_play_pause, playPause)
+
+ bigContentView.setTextViewText(
+ R.id.appName,
+ context.getString(R.string.app_name) + " • " + song.albumName
+ )
+ bigContentView.setTextViewText(R.id.title, song.title)
+ bigContentView.setTextViewText(R.id.subtitle, song.artistName)
+
+
+ contentView.setImageViewBitmap(
+ R.id.smallIcon,
+ createBitmap(
+ RetroUtil.getTintedVectorDrawable(
+ context,
+ R.drawable.ic_notification,
+ secondary
+ ), 0.6f
+ )
+ )
+ bigContentView.setImageViewBitmap(
+ R.id.smallIcon,
+ createBitmap(
+ RetroUtil.getTintedVectorDrawable(
+ context,
+ R.drawable.ic_notification,
+ secondary
+ ), 0.6f
+ )
+ )
+ }
+ })
+ }
+
+ private fun getPlayPauseBitmap(isPlaying: Boolean): Bitmap {
+ return createBitmap(
+ RetroUtil.getTintedVectorDrawable(
+ context,
+ if (isPlaying)
+ R.drawable.ic_pause_white_48dp
+ else
+ R.drawable.ic_play_arrow_white_48dp, primaryColor
+ ), NOTIFICATION_CONTROLS_SIZE_MULTIPLIER)
+ }
+
+ override fun setPlaying(isPlaying: Boolean) {
+ getPlayPauseBitmap(isPlaying).also {
+ contentView.setImageViewBitmap(R.id.action_play_pause, it)
+ bigContentView.setImageViewBitmap(R.id.action_play_pause, it)
+ }
+ }
+
+ override fun updateFavorite(song: Song, onUpdate: () -> Unit) {
+
+ }
private fun buildPendingIntent(
context: Context, action: String,
@@ -275,23 +286,34 @@ class PlayingNotificationOreo : PlayingNotification() {
private fun linkButtons(notificationLayout: RemoteViews) {
var pendingIntent: PendingIntent
- val serviceName = ComponentName(service, MusicService::class.java)
+ val serviceName = ComponentName(context, MusicService::class.java)
// Previous track
- pendingIntent = buildPendingIntent(service, ACTION_REWIND, serviceName)
+ pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName)
notificationLayout.setOnClickPendingIntent(R.id.action_prev, pendingIntent)
// Play and pause
- pendingIntent = buildPendingIntent(service, ACTION_TOGGLE_PAUSE, serviceName)
+ pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName)
notificationLayout.setOnClickPendingIntent(R.id.action_play_pause, pendingIntent)
// Next track
- pendingIntent = buildPendingIntent(service, ACTION_SKIP, serviceName)
+ pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName)
notificationLayout.setOnClickPendingIntent(R.id.action_next, pendingIntent)
// Close
- pendingIntent = buildPendingIntent(service, ACTION_QUIT, serviceName)
+ pendingIntent = buildPendingIntent(context, ACTION_QUIT, serviceName)
notificationLayout.setOnClickPendingIntent(R.id.action_quit, pendingIntent)
}
+ companion object {
+ fun from(
+ context: Context,
+ notificationManager: NotificationManager
+ ): PlayingNotification {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ createNotificationChannel(context, notificationManager)
+ }
+ return PlayingNotificationOreo(context)
+ }
+ }
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/MusicUtil.kt b/app/src/main/java/code/name/monkey/retromusic/util/MusicUtil.kt
index 119fc81f3..7bd0bbe00 100644
--- a/app/src/main/java/code/name/monkey/retromusic/util/MusicUtil.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/util/MusicUtil.kt
@@ -241,7 +241,7 @@ object MusicUtil : KoinComponent {
var musicMediaTitle = mediaTitle
return try {
if (TextUtils.isEmpty(musicMediaTitle)) {
- return ""
+ return "-"
}
musicMediaTitle = musicMediaTitle!!.trim { it <= ' ' }.lowercase()
if (musicMediaTitle.startsWith("the ")) {
@@ -526,6 +526,7 @@ object MusicUtil : KoinComponent {
@RequiresApi(Build.VERSION_CODES.R)
fun deleteTracksR(activity: Activity, songs: List) {
+ removeFromQueue(songs)
val pendingIntent = MediaStore.createDeleteRequest(activity.contentResolver, songs.map {
getSongFileUri(it.id)
})
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt
index 0de2b7b31..00268bc6e 100644
--- a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt
@@ -372,7 +372,7 @@ object PreferenceUtil {
var artistGridStyle: GridStyle
get() {
- val id: Int = sharedPreferences.getInt(ARTIST_GRID_STYLE, 4)
+ val id: Int = sharedPreferences.getInt(ARTIST_GRID_STYLE, 3)
return GridStyle.values().firstOrNull { gridStyle ->
gridStyle.id == id
} ?: GridStyle.Circular
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/color/MediaNotificationProcessor.java b/app/src/main/java/code/name/monkey/retromusic/util/color/MediaNotificationProcessor.java
index 58a8aad15..9a380d74b 100644
--- a/app/src/main/java/code/name/monkey/retromusic/util/color/MediaNotificationProcessor.java
+++ b/app/src/main/java/code/name/monkey/retromusic/util/color/MediaNotificationProcessor.java
@@ -473,4 +473,12 @@ public class MediaNotificationProcessor {
public interface OnPaletteLoadedListener {
void onPaletteLoaded(MediaNotificationProcessor mediaNotificationProcessor);
}
+
+ public static MediaNotificationProcessor errorColor(Context context) {
+ MediaNotificationProcessor errorColors = new MediaNotificationProcessor(context);
+ errorColors.backgroundColor = 0x15724528;
+ errorColors.primaryTextColor = 0x6974059;
+ errorColors.secondaryTextColor = 0x8684677;
+ return errorColors;
+ }
}
diff --git a/app/src/main/res/drawable/app_widget_background.xml b/app/src/main/res/drawable/app_widget_background.xml
new file mode 100644
index 000000000..e845d20cb
--- /dev/null
+++ b/app/src/main/res/drawable/app_widget_background.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/app_widget_md3.xml b/app/src/main/res/layout/app_widget_md3.xml
new file mode 100644
index 000000000..55f3fb286
--- /dev/null
+++ b/app/src/main/res/layout/app_widget_md3.xml
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_search.xml b/app/src/main/res/menu/menu_search.xml
index 683dbb511..116075329 100644
--- a/app/src/main/res/menu/menu_search.xml
+++ b/app/src/main/res/menu/menu_search.xml
@@ -5,5 +5,5 @@
android:id="@+id/action_search"
android:icon="@drawable/ic_search"
android:title="@string/action_search"
- app:showAsAction="ifRoom" />
+ app:showAsAction="always" />
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index ac705d443..a3f2064cf 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -39,6 +39,9 @@
2dp
12dp
+ 96dp
+ 80dp
+
32dp
8dp
48dp
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index b4aa0bba3..229596627 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -454,6 +454,7 @@
Ascending
Album
Artist
+ @string/album_artist
Composer
Date added
Date modified
@@ -517,4 +518,5 @@
Do you want to restore backup?
New Backup
Backup and restore your settings, playlists
+ MD3
diff --git a/app/src/main/res/xml/app_widget_md3_info.xml b/app/src/main/res/xml/app_widget_md3_info.xml
new file mode 100644
index 000000000..6aff4feba
--- /dev/null
+++ b/app/src/main/res/xml/app_widget_md3_info.xml
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/appthemehelper/build.gradle b/appthemehelper/build.gradle
index a3c296cad..468e82ff3 100644
--- a/appthemehelper/build.gradle
+++ b/appthemehelper/build.gradle
@@ -25,7 +25,7 @@ dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'com.google.android.material:material:1.5.0-beta01'
- implementation 'androidx.preference:preference-ktx:1.1.1'
+ implementation 'androidx.preference:preference-ktx:1.2.0-beta01'
implementation 'androidx.cardview:cardview:1.0.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
diff --git a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/ATH.kt b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/ATH.kt
index 3b5409dcb..719d9bf51 100755
--- a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/ATH.kt
+++ b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/ATH.kt
@@ -1,9 +1,9 @@
package code.name.monkey.appthemehelper
-import android.annotation.SuppressLint
import android.app.Activity
import android.app.ActivityManager
import android.content.Context
+import android.graphics.Color
import android.os.Build
import android.view.View
import androidx.annotation.ColorInt
@@ -18,7 +18,6 @@ import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
*/
object ATH {
- @SuppressLint("CommitPrefEdits")
fun didThemeValuesChange(context: Context, since: Long): Boolean {
return ThemeStore.isConfigured(context) && ThemeStore.prefs(context).getLong(
ThemeStorePrefKeys.VALUES_CHANGED,
@@ -26,7 +25,7 @@ object ATH {
) > since
}
- fun setLightStatusbar(activity: Activity, enabled: Boolean) {
+ fun setLightStatusBar(activity: Activity, enabled: Boolean) {
activity.window.apply {
WindowInsetsControllerCompat(
this,
@@ -36,29 +35,26 @@ object ATH {
}
fun setLightNavigationbar(activity: Activity, enabled: Boolean) {
- activity.window?.apply {
+ activity.window.apply {
WindowInsetsControllerCompat(
this,
decorView
).isAppearanceLightNavigationBars = enabled
+ navigationBarColor = Color.TRANSPARENT
}
}
- fun setLightNavigationbarAuto(activity: Activity, bgColor: Int) {
+ fun setLightNavigationBarAuto(activity: Activity, bgColor: Int) {
setLightNavigationbar(activity, ColorUtil.isColorLight(bgColor))
}
- fun setNavigationbarColorAuto(activity: Activity) {
- setNavigationbarColor(activity, ThemeStore.navigationBarColor(activity))
- }
-
- fun setNavigationbarColor(activity: Activity, color: Int) {
+ fun setNavigationBarColor(activity: Activity, color: Int) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
activity.window.navigationBarColor = color
} else {
activity.window.navigationBarColor = ColorUtil.darkenColor(color)
}
- setLightNavigationbarAuto(activity, color)
+ setLightNavigationBarAuto(activity, color)
}
fun setActivityToolbarColorAuto(activity: Activity, toolbar: Toolbar?) {
diff --git a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/prefs/ATEColorPreference.kt b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/prefs/ATEColorPreference.kt
index ba600c1e4..dcb990069 100644
--- a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/prefs/ATEColorPreference.kt
+++ b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/prefs/ATEColorPreference.kt
@@ -43,9 +43,9 @@ class ATEColorPreference @JvmOverloads constructor(
invalidateColor()
}*/
- override fun onBindViewHolder(holder: PreferenceViewHolder?) {
+ override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
- mView = holder?.itemView
+ mView = holder.itemView
invalidateColor()
}
diff --git a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/prefs/supportv7/ATEPreferenceCategory.kt b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/prefs/supportv7/ATEPreferenceCategory.kt
index c39affe91..5fb2fc4aa 100644
--- a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/prefs/supportv7/ATEPreferenceCategory.kt
+++ b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/prefs/supportv7/ATEPreferenceCategory.kt
@@ -22,7 +22,7 @@ import androidx.preference.PreferenceViewHolder
import code.name.monkey.appthemehelper.ThemeStore
class ATEPreferenceCategory @JvmOverloads constructor(
- context: Context?,
+ context: Context,
attrs: AttributeSet?,
defStyleAttr: Int = -1,
defStyleRes: Int = -1
diff --git a/build.gradle b/build.gradle
index 04b4fbcde..8a6bcb45b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,9 +9,9 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:7.0.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- def nav_version = "2.3.5"
+ def nav_version = "2.4.0-beta02"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
- classpath "com.diffplug.spotless:spotless-plugin-gradle:5.16.0"
+ classpath "com.diffplug.spotless:spotless-plugin-gradle:6.0.1"
}
}