From 13d9b6ab713ae334a0a9cee123eae143c1b08972 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Wed, 1 Dec 2021 00:44:40 +0530 Subject: [PATCH 01/17] Updated dependencies --- app/build.gradle | 6 +++--- .../retromusic/fragments/settings/AbsSettingsFragment.kt | 2 +- appthemehelper/build.gradle | 2 +- .../appthemehelper/common/prefs/ATEColorPreference.kt | 4 ++-- .../common/prefs/supportv7/ATEPreferenceCategory.kt | 2 +- build.gradle | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 76c3b034..28e61e8a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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' @@ -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/java/code/name/monkey/retromusic/fragments/settings/AbsSettingsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/settings/AbsSettingsFragment.kt index 1fd169bc..7e6ed914 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 @@ -75,7 +75,7 @@ abstract class AbsSettingsFragment : ATEPreferenceFragmentCompat() { invalidateSettings() } - override fun onDisplayPreferenceDialog(preference: Preference?) { + override fun onDisplayPreferenceDialog(preference: Preference) { when (preference) { is LibraryPreference -> { val fragment = LibraryPreferenceDialog.newInstance() diff --git a/appthemehelper/build.gradle b/appthemehelper/build.gradle index a3c296ca..468e82ff 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/common/prefs/ATEColorPreference.kt b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/prefs/ATEColorPreference.kt index ba600c1e..dcb99006 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 c39affe9..5fb2fc4a 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 04b4fbcd..95e66612 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.0" } } From bc93ff49b408bff7f600348a819005c467999c57 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Wed, 1 Dec 2021 12:44:27 +0530 Subject: [PATCH 02/17] [UI] Changed default grid style of Artists back to circular --- .../java/code/name/monkey/retromusic/util/PreferenceUtil.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 0de2b7b3..00268bc6 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 From c6f631783943eaf98fdecf80f81e01200d4a2cf6 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Wed, 1 Dec 2021 12:50:44 +0530 Subject: [PATCH 03/17] Remove songs from Queue when deleting songs on R --- app/src/main/java/code/name/monkey/retromusic/util/MusicUtil.kt | 1 + 1 file changed, 1 insertion(+) 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 119fc81f..feef2e06 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 @@ -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) }) From 238c54c6fb3a1215b6a2720957d29244e73c151f Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Wed, 1 Dec 2021 13:49:52 +0530 Subject: [PATCH 04/17] [UI] Better support for Immersive mode on notched devices --- .../monkey/retromusic/activities/base/AbsThemeActivity.kt | 4 ++++ .../code/name/monkey/retromusic/extensions/ViewExtensions.kt | 2 ++ .../src/main/java/code/name/monkey/appthemehelper/ATH.kt | 2 -- 3 files changed, 6 insertions(+), 2 deletions(-) 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 f53fe5ec..598cdc34 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 @@ -17,6 +17,7 @@ package code.name.monkey.retromusic.activities.base import android.content.Context import android.content.res.Resources import android.graphics.Color +import android.os.Build import android.os.Bundle import android.os.Handler import android.view.KeyEvent @@ -200,6 +201,9 @@ abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable { 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 + } } } 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 270db658..0641ab94 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 @@ -136,6 +136,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 +158,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/appthemehelper/src/main/java/code/name/monkey/appthemehelper/ATH.kt b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/ATH.kt index 3b5409dc..6653930a 100755 --- a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/ATH.kt +++ b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/ATH.kt @@ -1,6 +1,5 @@ package code.name.monkey.appthemehelper -import android.annotation.SuppressLint import android.app.Activity import android.app.ActivityManager import android.content.Context @@ -18,7 +17,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, From 12cf44637573cefb9294cff98382a976da5f8fce Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Wed, 1 Dec 2021 14:02:50 +0530 Subject: [PATCH 05/17] [UI] Fixed last playlist song hidden by mini player --- .../fragments/playlists/PlaylistDetailsFragment.kt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsFragment.kt index bf85121a..f66054ca 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsFragment.kt @@ -18,9 +18,10 @@ import code.name.monkey.retromusic.adapter.song.OrderablePlaylistSongAdapter import code.name.monkey.retromusic.databinding.FragmentPlaylistDetailBinding import code.name.monkey.retromusic.db.PlaylistWithSongs import code.name.monkey.retromusic.db.toSongs -import code.name.monkey.retromusic.extensions.dipToPix +import code.name.monkey.retromusic.extensions.dip import code.name.monkey.retromusic.extensions.surfaceColor import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment +import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper import code.name.monkey.retromusic.interfaces.ICabCallback import code.name.monkey.retromusic.interfaces.ICabHolder @@ -123,8 +124,12 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli } private fun checkForPadding() { - val height = dipToPix(52f) - binding.recyclerView.setPadding(0, 0, 0, height.toInt()) + val itemCount: Int = playlistSongAdapter.itemCount + if (itemCount > 0 && MusicPlayerRemote.playingQueue.isNotEmpty()) { + binding.recyclerView.updatePadding(bottom = dip(R.dimen.mini_player_height)) + } else { + binding.recyclerView.updatePadding(bottom = 0) + } } private fun checkIsEmpty() { From fd639d6348caf97283cd1ccff3f3cacc0c726167 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Wed, 1 Dec 2021 18:05:16 +0530 Subject: [PATCH 06/17] Fixed Album artist sort order in Albums tab --- .../name/monkey/retromusic/adapter/album/AlbumAdapter.kt | 2 +- .../monkey/retromusic/fragments/albums/AlbumsFragment.kt | 2 +- .../java/code/name/monkey/retromusic/helper/SortOrder.kt | 8 ++++---- .../java/code/name/monkey/retromusic/util/MusicUtil.kt | 2 +- app/src/main/res/values/strings.xml | 1 + 5 files changed, 8 insertions(+), 7 deletions(-) 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 25e24ff7..75fbd1a1 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/fragments/albums/AlbumsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumsFragment.kt index e7d713b5..320632de 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 : AbsRecyclerViewCustomGridSizeFragmentAscending Album Artist + @string/album_artist Composer Date added Date modified From 42a00dee95cf88ccf97de86784ca27c156e22855 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Wed, 1 Dec 2021 20:14:46 +0530 Subject: [PATCH 07/17] [Widget] Added a new MD3 widget --- app/src/main/AndroidManifest.xml | 18 +- .../retromusic/appwidgets/AppWidgetMD3.kt | 273 ++++++++++++++++++ .../retromusic/service/MusicService.java | 8 + .../res/drawable/app_widget_background.xml | 10 + app/src/main/res/layout/app_widget_md3.xml | 100 +++++++ app/src/main/res/values/dimens.xml | 3 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/app_widget_md3_info.xml | 11 + 8 files changed, 421 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetMD3.kt create mode 100644 app/src/main/res/drawable/app_widget_background.xml create mode 100644 app/src/main/res/layout/app_widget_md3.xml create mode 100644 app/src/main/res/xml/app_widget_md3_info.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e785fea3..a4ea84e9 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" /> + + + + + + + @@ -284,6 +296,6 @@ + android:value=".cast.CastOptionsProvider" /> 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 00000000..a60c7bca --- /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/service/MusicService.java b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java index 0647dbc2..99067cd4 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 @@ -81,6 +81,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; @@ -198,6 +199,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 +229,10 @@ public class MusicService extends MediaBrowserServiceCompat appWidgetText.performUpdate(MusicService.this, ids); break; } + case AppWidgetMD3.NAME: { + appWidgetMd3.performUpdate(MusicService.this, ids); + break; + } } } } @@ -1551,6 +1558,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) { 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 00000000..e845d20c --- /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 00000000..55f3fb28 --- /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/values/dimens.xml b/app/src/main/res/values/dimens.xml index ac705d44..a3f2064c 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 44901dcd..22959662 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -518,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 00000000..6aff4feb --- /dev/null +++ b/app/src/main/res/xml/app_widget_md3_info.xml @@ -0,0 +1,11 @@ + + \ No newline at end of file From e5743ee98b32c51b7680b1f0206bc7c45e59d6f1 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Thu, 2 Dec 2021 00:37:43 +0530 Subject: [PATCH 08/17] [Cleanup] Converted functions of super class(AbsThemeActivity) to extension functions --- app/src/main/AndroidManifest.xml | 2 +- .../activities/DriveModeActivity.kt | 1 + .../activities/LockScreenActivity.kt | 4 +- .../retromusic/activities/MainActivity.kt | 4 +- .../activities/PermissionActivity.kt | 4 +- .../retromusic/activities/PurchaseActivity.kt | 7 +- .../retromusic/activities/SettingsActivity.kt | 7 +- .../activities/ShareInstagramStory.kt | 8 +- .../activities/SupportDevelopmentActivity.kt | 4 +- .../retromusic/activities/WhatsNewActivity.kt | 4 +- .../base/AbsSlidingMusicPanelActivity.kt | 36 ++--- .../activities/base/AbsThemeActivity.kt | 135 +---------------- .../activities/bugreport/BugReportActivity.kt | 1 + .../tageditor/AbsTagEditorActivity.kt | 1 + .../tageditor/AlbumTagEditorActivity.kt | 1 + .../extensions/ActivityThemeExtensions.kt | 139 ++++++++++++++++++ .../extensions/FragmentMusicExtensions.kt | 39 +++++ .../fragments/base/AbsMainActivityFragment.kt | 4 +- .../fragments/base/AbsMusicServiceFragment.kt | 36 ----- .../AdaptivePlaybackControlsFragment.kt | 5 +- .../blur/BlurPlaybackControlsFragment.kt | 1 + .../card/CardPlaybackControlsFragment.kt | 1 + .../CardBlurPlaybackControlsFragment.kt | 1 + .../player/classic/ClassicPlayerFragment.kt | 1 + .../color/ColorPlaybackControlsFragment.kt | 1 + .../player/fit/FitPlaybackControlsFragment.kt | 1 + .../flat/FlatPlaybackControlsFragment.kt | 5 +- .../full/FullPlaybackControlsFragment.kt | 1 + .../normal/PlayerPlaybackControlsFragment.kt | 5 +- .../player/peak/PeakPlayerFragment.kt | 1 + .../plain/PlainPlaybackControlsFragment.kt | 1 + .../simple/SimplePlaybackControlsFragment.kt | 1 + .../player/tiny/TinyPlayerFragment.kt | 1 + .../code/name/monkey/appthemehelper/ATH.kt | 12 +- 34 files changed, 249 insertions(+), 226 deletions(-) create mode 100644 app/src/main/java/code/name/monkey/retromusic/extensions/ActivityThemeExtensions.kt create mode 100644 app/src/main/java/code/name/monkey/retromusic/extensions/FragmentMusicExtensions.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a4ea84e9..fda8258e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -296,6 +296,6 @@ + android:value="code.name.monkey.retromusic.cast.CastOptionsProvider" /> 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 d2bbcbe2..df912bcd 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 ba026cdb..46c1e438 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 59b59bf1..632cf71f 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 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 34d4a50c..8a5d7543 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 1550ee3c..1054c1ef 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 b9a233bb..39702cf9 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 a0a71973..6fd9a2b8 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 128746fb..b055c45e 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 a8b05999..40200eba 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 fea75a46..5c800900 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 @@ -184,9 +184,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() { @@ -257,26 +257,26 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { 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 +284,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) } } 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 598cdc34..87ff2f32 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,29 +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.Build 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.* @@ -54,9 +41,8 @@ abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable { setImmersiveFullscreen() registerSystemUiVisibility() toggleScreenOn() - setDrawUnderNavigationBar() setLightNavigationAuto() - setLightStatusbarAuto(surfaceColor()) + setLightStatusBarAuto(surfaceColor()) } private fun updateTheme() { @@ -72,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) { @@ -91,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 -> @@ -194,26 +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()) - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES - } - } - } - - 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 cc0ca55c..c446fdcf 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 3c6d0c7e..cee65c01 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 bd6bf459..4b9958c6 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/extensions/ActivityThemeExtensions.kt b/app/src/main/java/code/name/monkey/retromusic/extensions/ActivityThemeExtensions.kt new file mode 100644 index 00000000..4806c1ba --- /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 00000000..c1998b6b --- /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/fragments/base/AbsMainActivityFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsMainActivityFragment.kt index 0ced7780..7ee590fd 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsMainActivityFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsMainActivityFragment.kt @@ -22,6 +22,8 @@ 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.activities.MainActivity +import code.name.monkey.retromusic.extensions.setLightStatusBarAuto +import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto import code.name.monkey.retromusic.fragments.LibraryViewModel import org.koin.androidx.viewmodel.ext.android.sharedViewModel @@ -42,7 +44,7 @@ abstract class AbsMainActivityFragment(@LayoutRes layout: Int) : AbsMusicService if (statusBar != null) { if (VersionUtils.hasMarshmallow()) { statusBar.setBackgroundColor(color) - mainActivity.setLightStatusbarAuto(color) + mainActivity.setLightStatusBarAuto(color) } else { statusBar.setBackgroundColor(color) } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsMusicServiceFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsMusicServiceFragment.kt index 6be8f2d5..536c46e1 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsMusicServiceFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsMusicServiceFragment.kt @@ -15,21 +15,14 @@ package code.name.monkey.retromusic.fragments.base import android.content.Context -import android.net.Uri import android.os.Bundle import android.view.View -import android.webkit.MimeTypeMap import androidx.annotation.LayoutRes import androidx.fragment.app.Fragment import androidx.navigation.navOptions import code.name.monkey.retromusic.R import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity import code.name.monkey.retromusic.interfaces.IMusicServiceEventListener -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 /** * Created by hemanths on 18/08/17. @@ -103,33 +96,4 @@ open class AbsMusicServiceFragment(@LayoutRes layout: Int) : Fragment(layout), override fun onMediaStoreChanged() { } - - 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 - } } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/adaptive/AdaptivePlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/adaptive/AdaptivePlaybackControlsFragment.kt index a1196a03..55891b96 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/adaptive/AdaptivePlaybackControlsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/adaptive/AdaptivePlaybackControlsFragment.kt @@ -29,10 +29,7 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.databinding.FragmentAdaptivePlayerPlaybackControlsBinding -import code.name.monkey.retromusic.extensions.applyColor -import code.name.monkey.retromusic.extensions.hide -import code.name.monkey.retromusic.extensions.ripAlpha -import code.name.monkey.retromusic.extensions.show +import code.name.monkey.retromusic.extensions.* import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/blur/BlurPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/blur/BlurPlaybackControlsFragment.kt index 55f8e322..83dcd1fc 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/blur/BlurPlaybackControlsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/blur/BlurPlaybackControlsFragment.kt @@ -29,6 +29,7 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.databinding.FragmentBlurPlayerPlaybackControlsBinding +import code.name.monkey.retromusic.extensions.getSongInfo import code.name.monkey.retromusic.extensions.hide import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/card/CardPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/card/CardPlaybackControlsFragment.kt index a142ebaf..f9647e6b 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/card/CardPlaybackControlsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/card/CardPlaybackControlsFragment.kt @@ -27,6 +27,7 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.databinding.FragmentCardPlayerPlaybackControlsBinding +import code.name.monkey.retromusic.extensions.getSongInfo import code.name.monkey.retromusic.extensions.hide import code.name.monkey.retromusic.extensions.ripAlpha import code.name.monkey.retromusic.extensions.show diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/cardblur/CardBlurPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/cardblur/CardBlurPlaybackControlsFragment.kt index a78ed750..753a060e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/cardblur/CardBlurPlaybackControlsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/cardblur/CardBlurPlaybackControlsFragment.kt @@ -27,6 +27,7 @@ import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.databinding.FragmentCardBlurPlayerPlaybackControlsBinding import code.name.monkey.retromusic.extensions.applyColor +import code.name.monkey.retromusic.extensions.getSongInfo import code.name.monkey.retromusic.extensions.hide import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/classic/ClassicPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/classic/ClassicPlayerFragment.kt index f0d5c696..6a34c809 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/classic/ClassicPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/classic/ClassicPlayerFragment.kt @@ -36,6 +36,7 @@ import code.name.monkey.retromusic.R import code.name.monkey.retromusic.RetroBottomSheetBehavior import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter import code.name.monkey.retromusic.databinding.FragmentClassicPlayerBinding +import code.name.monkey.retromusic.extensions.getSongInfo import code.name.monkey.retromusic.extensions.hide import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/color/ColorPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/color/ColorPlaybackControlsFragment.kt index 7b3170af..22ffee1e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/color/ColorPlaybackControlsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/color/ColorPlaybackControlsFragment.kt @@ -32,6 +32,7 @@ import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.databinding.FragmentColorPlayerPlaybackControlsBinding import code.name.monkey.retromusic.extensions.applyColor +import code.name.monkey.retromusic.extensions.getSongInfo import code.name.monkey.retromusic.extensions.hide import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/fit/FitPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/fit/FitPlaybackControlsFragment.kt index e7bab207..a480f4e7 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/fit/FitPlaybackControlsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/fit/FitPlaybackControlsFragment.kt @@ -29,6 +29,7 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.databinding.FragmentFitPlaybackControlsBinding +import code.name.monkey.retromusic.extensions.getSongInfo import code.name.monkey.retromusic.extensions.hide import code.name.monkey.retromusic.extensions.ripAlpha import code.name.monkey.retromusic.extensions.show diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/flat/FlatPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/flat/FlatPlaybackControlsFragment.kt index 4d277fa2..c258edd4 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/flat/FlatPlaybackControlsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/flat/FlatPlaybackControlsFragment.kt @@ -28,10 +28,7 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.databinding.FragmentFlatPlayerPlaybackControlsBinding -import code.name.monkey.retromusic.extensions.applyColor -import code.name.monkey.retromusic.extensions.hide -import code.name.monkey.retromusic.extensions.ripAlpha -import code.name.monkey.retromusic.extensions.show +import code.name.monkey.retromusic.extensions.* import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment import code.name.monkey.retromusic.fragments.base.goToAlbum import code.name.monkey.retromusic.fragments.base.goToArtist diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt index 968794db..24a3616a 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt @@ -36,6 +36,7 @@ import code.name.monkey.retromusic.db.PlaylistEntity import code.name.monkey.retromusic.db.SongEntity import code.name.monkey.retromusic.db.toSongEntity import code.name.monkey.retromusic.extensions.applyColor +import code.name.monkey.retromusic.extensions.getSongInfo import code.name.monkey.retromusic.extensions.hide import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.fragments.LibraryViewModel diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/normal/PlayerPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/normal/PlayerPlaybackControlsFragment.kt index 79631258..c0306e71 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/normal/PlayerPlaybackControlsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/normal/PlayerPlaybackControlsFragment.kt @@ -28,10 +28,7 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.databinding.FragmentPlayerPlaybackControlsBinding -import code.name.monkey.retromusic.extensions.applyColor -import code.name.monkey.retromusic.extensions.hide -import code.name.monkey.retromusic.extensions.ripAlpha -import code.name.monkey.retromusic.extensions.show +import code.name.monkey.retromusic.extensions.* import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment import code.name.monkey.retromusic.fragments.base.goToAlbum import code.name.monkey.retromusic.fragments.base.goToArtist diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/peak/PeakPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/peak/PeakPlayerFragment.kt index 9b2b0b11..c2ed05b6 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/peak/PeakPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/peak/PeakPlayerFragment.kt @@ -22,6 +22,7 @@ import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.databinding.FragmentPeakPlayerBinding import code.name.monkey.retromusic.extensions.drawAboveSystemBars +import code.name.monkey.retromusic.extensions.getSongInfo import code.name.monkey.retromusic.extensions.hide import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/plain/PlainPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/plain/PlainPlaybackControlsFragment.kt index 2f3d45c3..f8438b0f 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/plain/PlainPlaybackControlsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/plain/PlainPlaybackControlsFragment.kt @@ -30,6 +30,7 @@ import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.databinding.FragmentPlainControlsFragmentBinding import code.name.monkey.retromusic.extensions.applyColor +import code.name.monkey.retromusic.extensions.getSongInfo import code.name.monkey.retromusic.extensions.hide import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/simple/SimplePlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/simple/SimplePlaybackControlsFragment.kt index 16aaaf71..5619b42f 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/simple/SimplePlaybackControlsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/simple/SimplePlaybackControlsFragment.kt @@ -25,6 +25,7 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.databinding.FragmentSimpleControlsFragmentBinding +import code.name.monkey.retromusic.extensions.getSongInfo import code.name.monkey.retromusic.extensions.hide import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/tiny/TinyPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/tiny/TinyPlayerFragment.kt index 80ba1c56..e73992e0 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/tiny/TinyPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/tiny/TinyPlayerFragment.kt @@ -28,6 +28,7 @@ import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.databinding.FragmentTinyPlayerBinding import code.name.monkey.retromusic.extensions.drawAboveSystemBars +import code.name.monkey.retromusic.extensions.getSongInfo import code.name.monkey.retromusic.extensions.hide import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment 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 6653930a..1c4a65fe 100755 --- a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/ATH.kt +++ b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/ATH.kt @@ -24,7 +24,7 @@ object ATH { ) > since } - fun setLightStatusbar(activity: Activity, enabled: Boolean) { + fun setLightStatusBar(activity: Activity, enabled: Boolean) { activity.window.apply { WindowInsetsControllerCompat( this, @@ -42,21 +42,17 @@ object ATH { } } - 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?) { From 1f84026682176f6b329e4fc8187ac8f1acbd4971 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Thu, 2 Dec 2021 01:17:23 +0530 Subject: [PATCH 09/17] [UI] Fixed white navigation bar on Now Playing --- .../src/main/java/code/name/monkey/appthemehelper/ATH.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 1c4a65fe..719d9bf5 100755 --- a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/ATH.kt +++ b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/ATH.kt @@ -3,6 +3,7 @@ package code.name.monkey.appthemehelper 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 @@ -34,11 +35,12 @@ object ATH { } fun setLightNavigationbar(activity: Activity, enabled: Boolean) { - activity.window?.apply { + activity.window.apply { WindowInsetsControllerCompat( this, decorView ).isAppearanceLightNavigationBars = enabled + navigationBarColor = Color.TRANSPARENT } } From a6319167c9d961ae85a6cdcb298434a7aa887a96 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Thu, 2 Dec 2021 14:27:13 +0530 Subject: [PATCH 10/17] [Lyrics] Fixed search icon not visible in LyricsFragment --- .../name/monkey/retromusic/fragments/other/LyricsFragment.kt | 1 + app/src/main/res/menu/menu_search.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/other/LyricsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/other/LyricsFragment.kt index e06a7672..dd90cdf2 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/other/LyricsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/other/LyricsFragment.kt @@ -97,6 +97,7 @@ class LyricsFragment : AbsMusicServiceFragment(R.layout.fragment_lyrics) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + setHasOptionsMenu(true) enterTransition = Fade() exitTransition = Fade() lyricsSectionsAdapter = LyricsSectionsAdapter(requireActivity()) diff --git a/app/src/main/res/menu/menu_search.xml b/app/src/main/res/menu/menu_search.xml index 683dbb51..11607532 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 From 652a79f14ed137dfdb0db889e5f11ca40caeed39 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Thu, 2 Dec 2021 16:42:31 +0530 Subject: [PATCH 11/17] [ViewModel] Fixed long loading times for most played playlist --- .../retromusic/fragments/LibraryViewModel.kt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) 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 dcf116c2..171983cd 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 { From e02e99ed027f3aa0ce921f57ee760706fdeb52cf Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Thu, 2 Dec 2021 17:04:49 +0530 Subject: [PATCH 12/17] [Glide] Added placeholder images for song, album & artist --- .../retromusic/glide/RetroGlideExtension.kt | 17 ++++++++++------- .../retromusic/glide/RetroMusicColoredTarget.kt | 3 +-- .../util/color/MediaNotificationProcessor.java | 8 ++++++++ 3 files changed, 19 insertions(+), 9 deletions(-) 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 5f54bb94..9db98366 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 195f7010..6e92597f 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/util/color/MediaNotificationProcessor.java b/app/src/main/java/code/name/monkey/retromusic/util/color/MediaNotificationProcessor.java index 58a8aad1..9a380d74 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; + } } From 91a428258154c52cd80d6072c81f03dc7c9fca5c Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Thu, 2 Dec 2021 23:56:07 +0530 Subject: [PATCH 13/17] [BottomNavigation] Better animations for BottomNavigationView --- app/build.gradle | 2 +- .../retromusic/activities/MainActivity.kt | 2 - .../base/AbsSlidingMusicPanelActivity.kt | 48 ++++++++----------- .../retromusic/extensions/ViewExtensions.kt | 11 +++-- build.gradle | 2 +- 5 files changed, 27 insertions(+), 38 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 28e61e8a..887f0a64 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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" 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 632cf71f..68c87e46 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 @@ -134,8 +134,6 @@ class MainActivity : AbsCastActivity(), OnSharedPreferenceChangeListener { PreferenceUtil.registerOnSharedPreferenceChangedListener(this) val expand = extra(EXPAND_PANEL).value ?: false if (expand && PreferenceUtil.isExpandPanel) { - setBottomNavVisibility(false) - fromNotification = true expandPanel() intent.removeExtra(EXPAND_PANEL) } 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 5c800900..e0af3082 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 @@ -67,11 +66,9 @@ 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 } 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 @@ -96,15 +93,6 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { } STATE_COLLAPSED -> { onPanelCollapsed() - if (fromNotification) { - hideBottomSheet(MusicPlayerRemote.playingQueue.isEmpty()) - fromNotification = false - } - } - STATE_SETTLING, STATE_DRAGGING -> { - if (fromNotification) { - bottomNavigationView.isVisible = true - } } else -> { println("Do something") @@ -319,53 +307,55 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { } fun setBottomNavVisibility(visible: Boolean, animate: Boolean = false) { - binding.bottomNavigationView.isVisible = visible - hideBottomSheet(MusicPlayerRemote.playingQueue.isEmpty(), animate) + binding.bottomNavigationView.translateYAnimate(if (visible) 0F else dip(R.dimen.bottom_nav_height).toFloat() + windowInsets.safeGetBottomInsets()) + .apply { + doOnEnd { + 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/extensions/ViewExtensions.kt b/app/src/main/java/code/name/monkey/retromusic/extensions/ViewExtensions.kt index 0641ab94..1f5c946e 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,21 @@ fun View.translateYAnimate(value: Float): Animator { .apply { duration = 300 doOnStart { - if (value == 0f) { - show() - } + show() } 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() diff --git a/build.gradle b/build.gradle index 95e66612..8a6bcb45 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ buildscript { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" def nav_version = "2.4.0-beta02" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" - classpath "com.diffplug.spotless:spotless-plugin-gradle:6.0.0" + classpath "com.diffplug.spotless:spotless-plugin-gradle:6.0.1" } } From 93277b8de7922af7d4a7d97ae86e3e0d0a54557c Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Fri, 3 Dec 2021 00:03:04 +0530 Subject: [PATCH 14/17] [Settings] Code Cleanup --- .../fragments/settings/AbsSettingsFragment.kt | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) 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 7e6ed914..afdd8a9b 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,11 +67,14 @@ 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() } From ba9c928588af519eae96f5e79f38119f742eb85d Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Fri, 3 Dec 2021 19:53:43 +0530 Subject: [PATCH 15/17] [Player] Fixed Show now playing not working --- .../retromusic/activities/MainActivity.kt | 2 + .../base/AbsSlidingMusicPanelActivity.kt | 42 +++++++++++++------ .../retromusic/extensions/InsetsExtensions.kt | 4 +- .../retromusic/extensions/ViewExtensions.kt | 1 + .../notification/PlayingNotificationImpl.kt | 21 ++++++---- 5 files changed, 48 insertions(+), 22 deletions(-) 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 68c87e46..72b1910e 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 @@ -134,6 +134,8 @@ class MainActivity : AbsCastActivity(), OnSharedPreferenceChangeListener { PreferenceUtil.registerOnSharedPreferenceChangedListener(this) val expand = extra(EXPAND_PANEL).value ?: false if (expand && PreferenceUtil.isExpandPanel) { + fromNotification = true + slidingPanel.bringToFront() expandPanel() intent.removeExtra(EXPAND_PANEL) } 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 e0af3082..8034362b 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 @@ -24,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 @@ -68,6 +69,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { val TAG: String = AbsSlidingMusicPanelActivity::class.java.simpleName } + var fromNotification = false private var windowInsets: WindowInsetsCompat? = null protected val libraryViewModel by viewModel() private lateinit var bottomSheetBehavior: RetroBottomSheetBehavior @@ -90,12 +92,19 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { when (newState) { STATE_EXPANDED -> { onPanelExpanded() + } STATE_COLLAPSED -> { onPanelCollapsed() } + STATE_SETTLING, STATE_DRAGGING -> { + if (fromNotification) { + binding.bottomNavigationView.bringToFront() + fromNotification = false + } + } else -> { - println("Do something") + println("Do a flip") } } } @@ -163,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 @@ -205,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()) { @@ -239,7 +250,6 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { collapsePanel() return true } - return false } @@ -307,17 +317,26 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { } fun setBottomNavVisibility(visible: Boolean, animate: Boolean = false) { - binding.bottomNavigationView.translateYAnimate(if (visible) 0F else dip(R.dimen.bottom_nav_height).toFloat() + windowInsets.safeGetBottomInsets()) - .apply { - doOnEnd { + 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() } - hideBottomSheet( - hide = MusicPlayerRemote.playingQueue.isEmpty(), - animate = animate, - isBottomNavVisible = visible - ) } + } 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( @@ -346,7 +365,6 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { } else { bottomSheetBehavior.peekHeight = heightOfBarWithTabs } - binding.bottomNavigationView.bringToFront() libraryViewModel.setFabMargin(dip(R.dimen.mini_player_height_expanded)) } else { println("Details") 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 b24168a3..8b6606b4 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 1f5c946e..141540da 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 @@ -69,6 +69,7 @@ fun View.translateYAnimate(value: Float): Animator { duration = 300 doOnStart { show() + bringToFront() } doOnEnd { if (value != 0f) { 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 3cca67a2..f7f58667 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 @@ -71,10 +71,13 @@ class PlayingNotificationImpl : PlayingNotification(), KoinComponent { 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 - ) + service, + 0, + action, + PendingIntent.FLAG_UPDATE_CURRENT or if (VersionUtils.hasMarshmallow()) + PendingIntent.FLAG_IMMUTABLE + else 0 + ) val serviceName = ComponentName(service, MusicService::class.java) val intent = Intent(ACTION_QUIT) @@ -83,9 +86,9 @@ class PlayingNotificationImpl : PlayingNotification(), KoinComponent { service, 0, intent, - if (VersionUtils.hasMarshmallow()) + PendingIntent.FLAG_UPDATE_CURRENT or (if (VersionUtils.hasMarshmallow()) PendingIntent.FLAG_IMMUTABLE - else 0 or PendingIntent.FLAG_UPDATE_CURRENT + else 0) ) val bigNotificationImageSize = service.resources .getDimensionPixelSize(R.dimen.notification_big_image_size) @@ -201,9 +204,9 @@ class PlayingNotificationImpl : PlayingNotification(), KoinComponent { 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 + service, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or + if (VersionUtils.hasMarshmallow()) PendingIntent.FLAG_IMMUTABLE + else 0 ) } } \ No newline at end of file From 1df50491fcb1223684e49bc5fcd24db116dc896e Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Sun, 5 Dec 2021 14:52:03 +0530 Subject: [PATCH 16/17] [Notification] Fixed and improved playing notification --- .../retromusic/service/MusicService.java | 71 ++- .../notification/PlayingNotification.kt | 110 ++--- .../notification/PlayingNotificationImpl.kt | 320 ++++++------- .../notification/PlayingNotificationOreo.kt | 424 +++++++++--------- 4 files changed, 482 insertions(+), 443 deletions(-) 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 99067cd4..d9946b82 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; @@ -106,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 @@ -280,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 = @@ -363,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(); @@ -424,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); @@ -474,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 @@ -772,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() { @@ -844,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; @@ -889,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(); @@ -1049,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, () -> { @@ -1170,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); @@ -1333,7 +1344,8 @@ public class MusicService extends MediaBrowserServiceCompat public void updateNotification() { if (playingNotification != null && getCurrentSong().getId() != -1) { - playingNotification.update(); + stopForegroundAndNotification(); + initNotification(); } } @@ -1407,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(); @@ -1435,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 { @@ -1600,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 5557a285..162775f0 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 f7f58667..49d43a87 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,180 +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, - PendingIntent.FLAG_UPDATE_CURRENT or if (VersionUtils.hasMarshmallow()) - PendingIntent.FLAG_IMMUTABLE - else 0 - ) - - val serviceName = ComponentName(service, MusicService::class.java) - val intent = Intent(ACTION_QUIT) - intent.component = serviceName - val deleteIntent = PendingIntent.getService( - service, - 0, - intent, - PendingIntent.FLAG_UPDATE_CURRENT or (if (VersionUtils.hasMarshmallow()) - PendingIntent.FLAG_IMMUTABLE - else 0) - ) - 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, PendingIntent.FLAG_UPDATE_CURRENT or + 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 29ff5287..a314ca2e 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) + } + } } From 996506c44a358720544f20bd2840372a6ffdb8d9 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Sun, 5 Dec 2021 14:56:31 +0530 Subject: [PATCH 17/17] Updated versionCode & versionName --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 887f0a64..ddb85632 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')}\"") }