Added splash screen

This commit is contained in:
h4h13 2019-11-15 23:38:57 +05:30
parent e455684544
commit 19d30f247e
10 changed files with 896 additions and 572 deletions

View file

@ -27,7 +27,8 @@
tools:ignore="AllowBackup,GoogleAppIndexingWarning"> tools:ignore="AllowBackup,GoogleAppIndexingWarning">
<activity <activity
android:name=".activities.MainActivity" android:name=".activities.MainActivity"
android:label="@string/app_name"> android:label="@string/app_name"
android:theme="@style/SplashTheme">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.MUSIC_PLAYER" /> <action android:name="android.intent.action.MUSIC_PLAYER" />

View file

@ -15,9 +15,7 @@
package code.name.monkey.retromusic.appwidgets package code.name.monkey.retromusic.appwidgets
import android.app.PendingIntent import android.app.PendingIntent
import android.content.ComponentName import android.content.*
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.text.TextUtils import android.text.TextUtils
@ -33,147 +31,201 @@ import code.name.monkey.retromusic.service.MusicService.*
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget import com.bumptech.glide.request.target.*
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
class AppWidgetBig : BaseAppWidget() { class AppWidgetBig : BaseAppWidget() {
private var target: Target<Bitmap>? = null // for cancellation private var target: Target<Bitmap>? = null // for cancellation
/** /**
* Initialize given widgets to default state, where we launch Music on default click and hide * Initialize given widgets to default state, where we launch Music on default click and hide
* actions if service not running. * actions if service not running.
*/ */
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) { override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
val appWidgetView = RemoteViews(context.packageName, val appWidgetView = RemoteViews(
code.name.monkey.retromusic.R.layout.app_widget_big) context.packageName, code.name.monkey.retromusic.R.layout.app_widget_big
)
appWidgetView.setViewVisibility(code.name.monkey.retromusic.R.id.media_titles, View.INVISIBLE) appWidgetView.setViewVisibility(
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art) code.name.monkey.retromusic.R.id.media_titles,
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.createBitmap( View.INVISIBLE
RetroUtil.getTintedVectorDrawable(context, code.name.monkey.retromusic.R.drawable.ic_skip_next_white_24dp, )
MaterialValueHelper.getPrimaryTextColor(context, false))!!, 1f)) appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art)
appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.Companion.createBitmap( appWidgetView.setImageViewBitmap(
RetroUtil.getTintedVectorDrawable(context, code.name.monkey.retromusic.R.drawable.ic_skip_previous_white_24dp, R.id.button_next, BaseAppWidget.createBitmap(
MaterialValueHelper.getPrimaryTextColor(context, false))!!, 1f)) RetroUtil.getTintedVectorDrawable(
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.Companion.createBitmap( context,
RetroUtil.getTintedVectorDrawable(context, code.name.monkey.retromusic.R.drawable.ic_play_arrow_white_32dp, code.name.monkey.retromusic.R.drawable.ic_skip_next_white_24dp,
MaterialValueHelper.getPrimaryTextColor(context, false))!!, 1f)) MaterialValueHelper.getPrimaryTextColor(context, false)
)!!, 1f
)
)
appWidgetView.setImageViewBitmap(
R.id.button_prev, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(
context,
code.name.monkey.retromusic.R.drawable.ic_skip_previous_white_24dp,
MaterialValueHelper.getPrimaryTextColor(context, false)
)!!, 1f
)
)
appWidgetView.setImageViewBitmap(
R.id.button_toggle_play_pause, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(
context,
code.name.monkey.retromusic.R.drawable.ic_play_arrow_white_32dp,
MaterialValueHelper.getPrimaryTextColor(context, false)
)!!, 1f
)
)
linkButtons(context, appWidgetView) linkButtons(context, appWidgetView)
pushUpdate(context, appWidgetIds, appWidgetView) pushUpdate(context, appWidgetIds, appWidgetView)
} }
/** /**
* Update all active widget instances by pushing changes * Update all active widget instances by pushing changes
*/ */
override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) { override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
val appWidgetView = RemoteViews(service.packageName, val appWidgetView = RemoteViews(
code.name.monkey.retromusic.R.layout.app_widget_big) service.packageName, code.name.monkey.retromusic.R.layout.app_widget_big
)
val isPlaying = service.isPlaying val isPlaying = service.isPlaying
val song = service.currentSong val song = service.currentSong
// Set the titles and artwork // Set the titles and artwork
if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) { if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
appWidgetView.setViewVisibility(code.name.monkey.retromusic.R.id.media_titles, View.INVISIBLE) appWidgetView.setViewVisibility(
} else { code.name.monkey.retromusic.R.id.media_titles,
appWidgetView.setViewVisibility(code.name.monkey.retromusic.R.id.media_titles, View.VISIBLE) View.INVISIBLE
appWidgetView.setTextViewText(code.name.monkey.retromusic.R.id.title, song.title) )
appWidgetView.setTextViewText(code.name.monkey.retromusic.R.id.text, getSongArtistAndAlbum(song)) } else {
} appWidgetView.setViewVisibility(
code.name.monkey.retromusic.R.id.media_titles,
View.VISIBLE
)
appWidgetView.setTextViewText(code.name.monkey.retromusic.R.id.title, song.title)
appWidgetView.setTextViewText(
code.name.monkey.retromusic.R.id.text,
getSongArtistAndAlbum(song)
)
}
// Set correct drawable for pause state // Set correct drawable for pause state
val playPauseRes = if (isPlaying) code.name.monkey.retromusic.R.drawable.ic_pause_white_24dp else code.name.monkey.retromusic.R.drawable.ic_play_arrow_white_32dp val playPauseRes = if (isPlaying) code.name.monkey.retromusic.R.drawable.ic_pause_white_24dp else code.name.monkey.retromusic.R.drawable.ic_play_arrow_white_32dp
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.createBitmap( appWidgetView.setImageViewBitmap(
RetroUtil.getTintedVectorDrawable(service, playPauseRes, R.id.button_toggle_play_pause, BaseAppWidget.createBitmap(
MaterialValueHelper.getPrimaryTextColor(service, false))!!, 1f)) RetroUtil.getTintedVectorDrawable(
service,
playPauseRes,
MaterialValueHelper.getPrimaryTextColor(service, false)
)!!, 1f
)
)
// Set prev/next button drawables // Set prev/next button drawables
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.Companion.createBitmap( appWidgetView.setImageViewBitmap(
RetroUtil.getTintedVectorDrawable(service, code.name.monkey.retromusic.R.drawable.ic_skip_next_white_24dp, R.id.button_next, BaseAppWidget.Companion.createBitmap(
MaterialValueHelper.getPrimaryTextColor(service, false))!!, 1f)) RetroUtil.getTintedVectorDrawable(
appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.Companion.createBitmap( service,
RetroUtil.getTintedVectorDrawable(service, code.name.monkey.retromusic.R.drawable.ic_skip_previous_white_24dp, code.name.monkey.retromusic.R.drawable.ic_skip_next_white_24dp,
MaterialValueHelper.getPrimaryTextColor(service, false))!!, 1f)) MaterialValueHelper.getPrimaryTextColor(service, false)
)!!, 1f
)
)
appWidgetView.setImageViewBitmap(
R.id.button_prev, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(
service,
code.name.monkey.retromusic.R.drawable.ic_skip_previous_white_24dp,
MaterialValueHelper.getPrimaryTextColor(service, false)
)!!, 1f
)
)
// Link actions buttons to intents // Link actions buttons to intents
linkButtons(service, appWidgetView) linkButtons(service, appWidgetView)
// Load the album cover async and push the update on completion // Load the album cover async and push the update on completion
val p = RetroUtil.getScreenSize(service) val p = RetroUtil.getScreenSize(service)
val widgetImageSize = Math.min(p.x, p.y) val widgetImageSize = Math.min(p.x, p.y)
val appContext = service.applicationContext val appContext = service.applicationContext
service.runOnUiThread { service.runOnUiThread {
if (target != null) { if (target != null) {
Glide.clear(target) Glide.clear(target)
} }
target = SongGlideRequest.Builder.from(Glide.with(appContext), song) target = SongGlideRequest.Builder.from(Glide.with(appContext), song)
.checkIgnoreMediaStore(appContext) .checkIgnoreMediaStore(appContext).asBitmap().build()
.asBitmap().build() .into(object : SimpleTarget<Bitmap>(widgetImageSize, widgetImageSize) {
.into(object : SimpleTarget<Bitmap>(widgetImageSize, widgetImageSize) { override fun onResourceReady(
override fun onResourceReady(resource: Bitmap, glideAnimation: GlideAnimation<in Bitmap>) { resource: Bitmap,
update(resource) glideAnimation: GlideAnimation<in Bitmap>
} ) {
update(resource)
}
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) { override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable) super.onLoadFailed(e, errorDrawable)
update(null) update(null)
} }
private fun update(bitmap: Bitmap?) { private fun update(bitmap: Bitmap?) {
if (bitmap == null) { if (bitmap == null) {
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art) appWidgetView.setImageViewResource(
} else { R.id.image,
appWidgetView.setImageViewBitmap(R.id.image, bitmap) R.drawable.default_album_art
} )
pushUpdate(appContext, appWidgetIds, appWidgetView) } else {
} appWidgetView.setImageViewBitmap(R.id.image, bitmap)
}); }
} pushUpdate(appContext, appWidgetIds, appWidgetView)
} }
});
}
}
/** /**
* Link up various button actions using [PendingIntent]. * Link up various button actions using [PendingIntent].
*/ */
private fun linkButtons(context: Context, views: RemoteViews) { private fun linkButtons(context: Context, views: RemoteViews) {
val action = Intent(context, MainActivity::class.java).putExtra("expand", true) val action = Intent(context, MainActivity::class.java).putExtra("expand", true)
var pendingIntent: PendingIntent var pendingIntent: PendingIntent
val serviceName = ComponentName(context, MusicService::class.java) val serviceName = ComponentName(context, MusicService::class.java)
// Home // Home
action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
pendingIntent = PendingIntent.getActivity(context, 0, action, 0) pendingIntent = PendingIntent.getActivity(context, 0, action, 0)
views.setOnClickPendingIntent(R.id.clickable_area, pendingIntent) views.setOnClickPendingIntent(R.id.clickable_area, pendingIntent)
// Previous track // Previous track
pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName) pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName)
views.setOnClickPendingIntent(R.id.button_prev, pendingIntent) views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
// Play and pause // Play and pause
pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName) pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName)
views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent) views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
// Next track // Next track
pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName) pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName)
views.setOnClickPendingIntent(R.id.button_next, pendingIntent) views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
} }
companion object { companion object {
const val NAME: String = "app_widget_big" const val NAME: String = "app_widget_big"
private var mInstance: AppWidgetBig? = null private var mInstance: AppWidgetBig? = null
val instance: AppWidgetBig val instance: AppWidgetBig
@Synchronized get() { @Synchronized get() {
if (mInstance == null) { if (mInstance == null) {
mInstance = AppWidgetBig() mInstance = AppWidgetBig()
} }
return mInstance!! return mInstance!!
} }
} }
} }

View file

@ -15,9 +15,7 @@
package code.name.monkey.retromusic.appwidgets package code.name.monkey.retromusic.appwidgets
import android.app.PendingIntent import android.app.PendingIntent
import android.content.ComponentName import android.content.*
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.text.TextUtils import android.text.TextUtils
@ -31,156 +29,231 @@ import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper 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.service.MusicService.* import code.name.monkey.retromusic.service.MusicService.*
import code.name.monkey.retromusic.util.ImageUtil import code.name.monkey.retromusic.util.*
import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget import com.bumptech.glide.request.target.*
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
class AppWidgetCard : BaseAppWidget() { class AppWidgetCard : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
/** /**
* Initialize given widgets to default state, where we launch Music on default click and hide * Initialize given widgets to default state, where we launch Music on default click and hide
* actions if service not running. * actions if service not running.
*/ */
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) { override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_card) val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_card)
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE) appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art) appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art)
appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f)) appWidgetView.setImageViewBitmap(
appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_previous_white_24dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f)) R.id.button_next, createBitmap(
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_play_arrow_white_32dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f)) RetroUtil.getTintedVectorDrawable(
context,
R.drawable.ic_skip_next_white_24dp,
MaterialValueHelper.getSecondaryTextColor(
context, true
)
)!!, 1f
)
)
appWidgetView.setImageViewBitmap(
R.id.button_prev, createBitmap(
RetroUtil.getTintedVectorDrawable(
context,
R.drawable.ic_skip_previous_white_24dp,
MaterialValueHelper.getSecondaryTextColor(
context, true
)
)!!, 1f
)
)
appWidgetView.setImageViewBitmap(
R.id.button_toggle_play_pause, createBitmap(
RetroUtil.getTintedVectorDrawable(
context,
R.drawable.ic_play_arrow_white_32dp,
MaterialValueHelper.getSecondaryTextColor(
context, true
)
)!!, 1f
)
)
linkButtons(context, appWidgetView) linkButtons(context, appWidgetView)
pushUpdate(context, appWidgetIds, appWidgetView) pushUpdate(context, appWidgetIds, appWidgetView)
} }
/** /**
* Update all active widget instances by pushing changes * Update all active widget instances by pushing changes
*/ */
override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) { override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_card) val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_card)
val isPlaying = service.isPlaying val isPlaying = service.isPlaying
val song = service.currentSong val song = service.currentSong
// Set the titles and artwork // Set the titles and artwork
if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) { if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE) appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
} else { } else {
appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE) appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE)
appWidgetView.setTextViewText(R.id.title, song.title) appWidgetView.setTextViewText(R.id.title, song.title)
appWidgetView.setTextViewText(R.id.text, getSongArtistAndAlbum(song)) appWidgetView.setTextViewText(R.id.text, getSongArtistAndAlbum(song))
} }
// Set correct drawable for pause state // Set correct drawable for pause state
val playPauseRes = if (isPlaying) R.drawable.ic_pause_white_24dp else R.drawable.ic_play_arrow_white_32dp val playPauseRes = if (isPlaying) R.drawable.ic_pause_white_24dp else R.drawable.ic_play_arrow_white_32dp
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, createBitmap( appWidgetView.setImageViewBitmap(
RetroUtil.getTintedVectorDrawable(service, playPauseRes, R.id.button_toggle_play_pause, createBitmap(
MaterialValueHelper.getSecondaryTextColor(service, true))!!, 1f)) RetroUtil.getTintedVectorDrawable(
service,
playPauseRes,
MaterialValueHelper.getSecondaryTextColor(service, true)
)!!, 1f
)
)
// Set prev/next button drawables // Set prev/next button drawables
appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap( appWidgetView.setImageViewBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp, R.id.button_next, createBitmap(
MaterialValueHelper.getSecondaryTextColor(service, true))!!, 1f)) RetroUtil.getTintedVectorDrawable(
appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap( service,
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, R.drawable.ic_skip_next_white_24dp,
MaterialValueHelper.getSecondaryTextColor(service, true))!!, 1f)) MaterialValueHelper.getSecondaryTextColor(service, true)
)!!, 1f
)
)
appWidgetView.setImageViewBitmap(
R.id.button_prev, createBitmap(
RetroUtil.getTintedVectorDrawable(
service,
R.drawable.ic_skip_previous_white_24dp,
MaterialValueHelper.getSecondaryTextColor(service, true)
)!!, 1f
)
)
// Link actions buttons to intents // Link actions buttons to intents
linkButtons(service, appWidgetView) linkButtons(service, appWidgetView)
if (imageSize == 0) { if (imageSize == 0) {
imageSize = service.resources.getDimensionPixelSize(code.name.monkey.retromusic.R.dimen.app_widget_card_image_size) imageSize = service.resources.getDimensionPixelSize(code.name.monkey.retromusic.R.dimen.app_widget_card_image_size)
} }
if (cardRadius == 0f) { if (cardRadius == 0f) {
cardRadius = service.resources.getDimension(code.name.monkey.retromusic.R.dimen.app_widget_card_radius) cardRadius = service.resources.getDimension(code.name.monkey.retromusic.R.dimen.app_widget_card_radius)
} }
val appContext = service.applicationContext val appContext = service.applicationContext
// Load the album cover async and push the update on completion // Load the album cover async and push the update on completion
service.runOnUiThread { service.runOnUiThread {
if (target != null) { if (target != null) {
Glide.clear(target) Glide.clear(target)
} }
target = SongGlideRequest.Builder.from(Glide.with(service), song) target = SongGlideRequest.Builder.from(Glide.with(service), song)
.checkIgnoreMediaStore(service) .checkIgnoreMediaStore(service).generatePalette(service).build().centerCrop()
.generatePalette(service).build() .into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
.centerCrop() override fun onResourceReady(
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) { resource: BitmapPaletteWrapper,
override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) { glideAnimation: GlideAnimation<in BitmapPaletteWrapper>
val palette = resource.palette ) {
update(resource.bitmap, palette.getVibrantColor(palette.getMutedColor(MaterialValueHelper.getSecondaryTextColor(service, true)))) val palette = resource.palette
} update(
resource.bitmap, palette.getVibrantColor(
palette.getMutedColor(
MaterialValueHelper.getSecondaryTextColor(
service, true
)
)
)
)
}
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) { override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable) super.onLoadFailed(e, errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(service, true)) update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
} }
private fun update(bitmap: Bitmap?, color: Int) { private fun update(bitmap: Bitmap?, color: Int) {
// Set correct drawable for pause state // Set correct drawable for pause state
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(service, playPauseRes, color))) appWidgetView.setImageViewBitmap(
R.id.button_toggle_play_pause, ImageUtil.createBitmap(
ImageUtil.getTintedVectorDrawable(
service, playPauseRes, color
)
)
)
// Set prev/next button drawables // Set prev/next button drawables
appWidgetView.setImageViewBitmap(R.id.button_next, ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp, color))) appWidgetView.setImageViewBitmap(
appWidgetView.setImageViewBitmap(R.id.button_prev, ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, color))) R.id.button_next, ImageUtil.createBitmap(
ImageUtil.getTintedVectorDrawable(
service, R.drawable.ic_skip_next_white_24dp, color
)
)
)
appWidgetView.setImageViewBitmap(
R.id.button_prev, ImageUtil.createBitmap(
ImageUtil.getTintedVectorDrawable(
service, R.drawable.ic_skip_previous_white_24dp, color
)
)
)
val image = getAlbumArtDrawable(service.resources, bitmap) val image = getAlbumArtDrawable(service.resources, bitmap)
val roundedBitmap = createRoundedBitmap(image, imageSize, imageSize, cardRadius, 0F, cardRadius, 0F) val roundedBitmap = createRoundedBitmap(
appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap) image, imageSize, imageSize, cardRadius, 0F, cardRadius, 0F
)
appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap)
pushUpdate(service, appWidgetIds, appWidgetView) pushUpdate(service, appWidgetIds, appWidgetView)
} }
}) })
} }
} }
/** /**
* Link up various button actions using [PendingIntent]. * Link up various button actions using [PendingIntent].
*/ */
private fun linkButtons(context: Context, views: RemoteViews) { private fun linkButtons(context: Context, views: RemoteViews) {
val action: Intent = Intent(context, MainActivity::class.java).putExtra("expand", true) val action: Intent = Intent(context, MainActivity::class.java).putExtra("expand", true)
var pendingIntent: PendingIntent var pendingIntent: PendingIntent
val serviceName = ComponentName(context, MusicService::class.java) val serviceName = ComponentName(context, MusicService::class.java)
// Home // Home
action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
pendingIntent = PendingIntent.getActivity(context, 0, action, 0) pendingIntent = PendingIntent.getActivity(context, 0, action, 0)
views.setOnClickPendingIntent(R.id.image, pendingIntent) views.setOnClickPendingIntent(R.id.image, pendingIntent)
views.setOnClickPendingIntent(R.id.media_titles, pendingIntent) views.setOnClickPendingIntent(R.id.media_titles, pendingIntent)
// Previous track // Previous track
pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName) pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName)
views.setOnClickPendingIntent(R.id.button_prev, pendingIntent) views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
// Play and pause // Play and pause
pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName) pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName)
views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent) views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
// Next track // Next track
pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName) pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName)
views.setOnClickPendingIntent(R.id.button_next, pendingIntent) views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
} }
companion object { companion object {
const val NAME = "app_widget_card" const val NAME = "app_widget_card"
private var mInstance: AppWidgetCard? = null private var mInstance: AppWidgetCard? = null
private var imageSize = 0 private var imageSize = 0
private var cardRadius = 0f private var cardRadius = 0f
val instance: AppWidgetCard val instance: AppWidgetCard
@Synchronized get() { @Synchronized get() {
if (mInstance == null) { if (mInstance == null) {
mInstance = AppWidgetCard() mInstance = AppWidgetCard()
} }
return mInstance!! return mInstance!!
} }
} }
} }

View file

@ -15,9 +15,7 @@
package code.name.monkey.retromusic.appwidgets package code.name.monkey.retromusic.appwidgets
import android.app.PendingIntent import android.app.PendingIntent
import android.content.ComponentName import android.content.*
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.text.TextUtils import android.text.TextUtils
@ -31,147 +29,202 @@ import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper 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.service.MusicService.* import code.name.monkey.retromusic.service.MusicService.*
import code.name.monkey.retromusic.util.ImageUtil import code.name.monkey.retromusic.util.*
import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget import com.bumptech.glide.request.target.*
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
class AppWidgetClassic : BaseAppWidget() { class AppWidgetClassic : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
/** /**
* Initialize given widgets to default state, where we launch Music on default click and hide * Initialize given widgets to default state, where we launch Music on default click and hide
* actions if service not running. * actions if service not running.
*/ */
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) { override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_classic) val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_classic)
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE) appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art) appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art)
appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f)) appWidgetView.setImageViewBitmap(
appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_previous_white_24dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f)) R.id.button_next, createBitmap(
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_play_arrow_white_32dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f)) RetroUtil.getTintedVectorDrawable(
context,
R.drawable.ic_skip_next_white_24dp,
MaterialValueHelper.getSecondaryTextColor(
context, true
)
)!!, 1f
)
)
appWidgetView.setImageViewBitmap(
R.id.button_prev, createBitmap(
RetroUtil.getTintedVectorDrawable(
context,
R.drawable.ic_skip_previous_white_24dp,
MaterialValueHelper.getSecondaryTextColor(
context, true
)
)!!, 1f
)
)
appWidgetView.setImageViewBitmap(
R.id.button_toggle_play_pause, createBitmap(
RetroUtil.getTintedVectorDrawable(
context,
R.drawable.ic_play_arrow_white_32dp,
MaterialValueHelper.getSecondaryTextColor(
context, true
)
)!!, 1f
)
)
linkButtons(context, appWidgetView) linkButtons(context, appWidgetView)
pushUpdate(context, appWidgetIds, appWidgetView) pushUpdate(context, appWidgetIds, appWidgetView)
} }
/** /**
* Update all active widget instances by pushing changes * Update all active widget instances by pushing changes
*/ */
override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) { override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_classic) val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_classic)
val isPlaying = service.isPlaying val isPlaying = service.isPlaying
val song = service.currentSong val song = service.currentSong
// Set the titles and artwork // Set the titles and artwork
if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) { if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE) appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
} else { } else {
appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE) appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE)
appWidgetView.setTextViewText(R.id.title, song.title) appWidgetView.setTextViewText(R.id.title, song.title)
appWidgetView.setTextViewText(R.id.text, getSongArtistAndAlbum(song)) appWidgetView.setTextViewText(R.id.text, getSongArtistAndAlbum(song))
} }
// Link actions buttons to intents // Link actions buttons to intents
linkButtons(service, appWidgetView) linkButtons(service, appWidgetView)
if (imageSize == 0) { if (imageSize == 0) {
imageSize = service.resources imageSize = service.resources.getDimensionPixelSize(R.dimen.app_widget_classic_image_size)
.getDimensionPixelSize(R.dimen.app_widget_classic_image_size) }
} if (cardRadius == 0f) {
if (cardRadius == 0f) { cardRadius = service.resources.getDimension(R.dimen.app_widget_card_radius)
cardRadius = service.resources.getDimension(R.dimen.app_widget_card_radius) }
}
// Load the album cover async and push the update on completion // Load the album cover async and push the update on completion
val appContext = service.applicationContext val appContext = service.applicationContext
service.runOnUiThread { service.runOnUiThread {
if (target != null) { if (target != null) {
Glide.clear(target) Glide.clear(target)
} }
target = SongGlideRequest.Builder.from(Glide.with(service), song) target = SongGlideRequest.Builder.from(Glide.with(service), song)
.checkIgnoreMediaStore(service) .checkIgnoreMediaStore(service).generatePalette(service).build().centerCrop()
.generatePalette(service).build() .into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
.centerCrop() override fun onResourceReady(
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) { resource: BitmapPaletteWrapper,
override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) { glideAnimation: GlideAnimation<in BitmapPaletteWrapper>
val palette = resource.palette ) {
update(resource.bitmap, palette.getVibrantColor(palette.getMutedColor(MaterialValueHelper.getSecondaryTextColor(service, true)))) val palette = resource.palette
} update(
resource.bitmap, palette.getVibrantColor(
palette.getMutedColor(
MaterialValueHelper.getSecondaryTextColor(
service, true
)
)
)
)
}
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) { override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable) super.onLoadFailed(e, errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(service, true)) update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
} }
private fun update(bitmap: Bitmap?, color: Int) {
// Set correct drawable for pause state
val playPauseRes = if (isPlaying) R.drawable.ic_pause_white_24dp else R.drawable.ic_play_arrow_white_24dp
appWidgetView.setImageViewBitmap(
R.id.button_toggle_play_pause, ImageUtil.createBitmap(
ImageUtil.getTintedVectorDrawable(
service, playPauseRes, color
)
)
)
private fun update(bitmap: Bitmap?, color: Int) { // Set prev/next button drawables
// Set correct drawable for pause state appWidgetView.setImageViewBitmap(
val playPauseRes = if (isPlaying) R.drawable.ic_pause_white_24dp else R.drawable.ic_play_arrow_white_24dp R.id.button_next, ImageUtil.createBitmap(
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(service, playPauseRes, color))) ImageUtil.getTintedVectorDrawable(
service, R.drawable.ic_skip_next_white_24dp, color
)
)
)
appWidgetView.setImageViewBitmap(
R.id.button_prev, ImageUtil.createBitmap(
ImageUtil.getTintedVectorDrawable(
service, R.drawable.ic_skip_previous_white_24dp, color
)
)
)
// Set prev/next button drawables val image = getAlbumArtDrawable(service.resources, bitmap)
appWidgetView.setImageViewBitmap(R.id.button_next, ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp, color))) val roundedBitmap = createRoundedBitmap(
appWidgetView.setImageViewBitmap(R.id.button_prev, ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, color))) image, imageSize, imageSize, cardRadius, 0F, cardRadius, 0F
)
appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap)
val image = getAlbumArtDrawable(service.resources, bitmap) pushUpdate(appContext, appWidgetIds, appWidgetView)
val roundedBitmap = createRoundedBitmap(image, imageSize, imageSize, cardRadius, 0F, cardRadius, 0F) }
appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap) })
}
}
pushUpdate(appContext, appWidgetIds, appWidgetView) /**
} * Link up various button actions using [PendingIntent].
}) */
} private fun linkButtons(context: Context, views: RemoteViews) {
} val action = Intent(context, MainActivity::class.java).putExtra("expand", true)
var pendingIntent: PendingIntent
/** val serviceName = ComponentName(context, MusicService::class.java)
* Link up various button actions using [PendingIntent].
*/
private fun linkButtons(context: Context, views: RemoteViews) {
val action = Intent(context, MainActivity::class.java).putExtra("expand", true)
var pendingIntent: PendingIntent
val serviceName = ComponentName(context, MusicService::class.java) // Home
action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
pendingIntent = PendingIntent.getActivity(context, 0, action, 0)
views.setOnClickPendingIntent(R.id.image, pendingIntent)
views.setOnClickPendingIntent(R.id.media_titles, pendingIntent)
// Home // Previous track
action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName)
pendingIntent = PendingIntent.getActivity(context, 0, action, 0) views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
views.setOnClickPendingIntent(R.id.image, pendingIntent)
views.setOnClickPendingIntent(R.id.media_titles, pendingIntent)
// Previous track // Play and pause
pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName) pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName)
views.setOnClickPendingIntent(R.id.button_prev, pendingIntent) views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
// Play and pause // Next track
pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName) pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName)
views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent) views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
}
// Next track companion object {
pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName)
views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
}
companion object { const val NAME = "app_widget_classic"
const val NAME = "app_widget_classic" private var mInstance: AppWidgetClassic? = null
private var imageSize = 0
private var cardRadius = 0f
private var mInstance: AppWidgetClassic? = null val instance: AppWidgetClassic
private var imageSize = 0 @Synchronized get() {
private var cardRadius = 0f if (mInstance == null) {
mInstance = AppWidgetClassic()
val instance: AppWidgetClassic }
@Synchronized get() { return mInstance!!
if (mInstance == null) { }
mInstance = AppWidgetClassic() }
}
return mInstance!!
}
}
} }

View file

@ -15,9 +15,7 @@
package code.name.monkey.retromusic.appwidgets package code.name.monkey.retromusic.appwidgets
import android.app.PendingIntent import android.app.PendingIntent
import android.content.ComponentName import android.content.*
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.text.TextUtils import android.text.TextUtils
@ -34,149 +32,207 @@ import code.name.monkey.retromusic.service.MusicService.*
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget import com.bumptech.glide.request.target.*
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
class AppWidgetSmall : BaseAppWidget() { class AppWidgetSmall : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
/** /**
* Initialize given widgets to default state, where we launch Music on default click and hide * Initialize given widgets to default state, where we launch Music on default click and hide
* actions if service not running. * actions if service not running.
*/ */
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) { override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_small) val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_small)
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE) appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art) appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art)
appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f)) appWidgetView.setImageViewBitmap(
appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_previous_white_24dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f)) R.id.button_next, createBitmap(
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_play_arrow_white_32dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f)) RetroUtil.getTintedVectorDrawable(
context,
R.drawable.ic_skip_next_white_24dp,
MaterialValueHelper.getSecondaryTextColor(
context, true
)
)!!, 1f
)
)
appWidgetView.setImageViewBitmap(
R.id.button_prev, createBitmap(
RetroUtil.getTintedVectorDrawable(
context,
R.drawable.ic_skip_previous_white_24dp,
MaterialValueHelper.getSecondaryTextColor(
context, true
)
)!!, 1f
)
)
appWidgetView.setImageViewBitmap(
R.id.button_toggle_play_pause, createBitmap(
RetroUtil.getTintedVectorDrawable(
context,
R.drawable.ic_play_arrow_white_32dp,
MaterialValueHelper.getSecondaryTextColor(
context, true
)
)!!, 1f
)
)
linkButtons(context, appWidgetView) linkButtons(context, appWidgetView)
pushUpdate(context, appWidgetIds, appWidgetView) pushUpdate(context, appWidgetIds, appWidgetView)
} }
/** /**
* Update all active widget instances by pushing changes * Update all active widget instances by pushing changes
*/ */
override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) { override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
val appWidgetView = RemoteViews(service.packageName, val appWidgetView = RemoteViews(
R.layout.app_widget_small) service.packageName, R.layout.app_widget_small
)
val isPlaying = service.isPlaying val isPlaying = service.isPlaying
val song = service.currentSong val song = service.currentSong
// Set the titles and artwork // Set the titles and artwork
if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) { if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE) appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
} else { } else {
if (TextUtils.isEmpty(song.title) || TextUtils.isEmpty(song.artistName)) { if (TextUtils.isEmpty(song.title) || TextUtils.isEmpty(song.artistName)) {
appWidgetView.setTextViewText(R.id.text_separator, "") appWidgetView.setTextViewText(R.id.text_separator, "")
} else { } else {
appWidgetView.setTextViewText(R.id.text_separator, "") appWidgetView.setTextViewText(R.id.text_separator, "")
} }
appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE) appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE)
appWidgetView.setTextViewText(R.id.title, song.title) appWidgetView.setTextViewText(R.id.title, song.title)
appWidgetView.setTextViewText(R.id.text, song.artistName) appWidgetView.setTextViewText(R.id.text, song.artistName)
} }
// Link actions buttons to intents // Link actions buttons to intents
linkButtons(service, appWidgetView) linkButtons(service, appWidgetView)
if (imageSize == 0) { if (imageSize == 0) {
imageSize = service.resources.getDimensionPixelSize(R.dimen.app_widget_small_image_size) imageSize = service.resources.getDimensionPixelSize(R.dimen.app_widget_small_image_size)
} }
if (cardRadius == 0f) { if (cardRadius == 0f) {
cardRadius = service.resources.getDimension(R.dimen.app_widget_card_radius) cardRadius = service.resources.getDimension(R.dimen.app_widget_card_radius)
} }
// Load the album cover async and push the update on completion // Load the album cover async and push the update on completion
val appContext = service.applicationContext val appContext = service.applicationContext
service.runOnUiThread { service.runOnUiThread {
if (target != null) { if (target != null) {
Glide.clear(target) Glide.clear(target)
} }
target = SongGlideRequest.Builder.from(Glide.with(service), song) target = SongGlideRequest.Builder.from(Glide.with(service), song)
.checkIgnoreMediaStore(service) .checkIgnoreMediaStore(service).generatePalette(service).build().centerCrop()
.generatePalette(service).build() .into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
.centerCrop() override fun onResourceReady(
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) { resource: BitmapPaletteWrapper,
override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) { glideAnimation: GlideAnimation<in BitmapPaletteWrapper>
val palette = resource.palette ) {
update(resource.bitmap, palette.getVibrantColor(palette.getMutedColor(MaterialValueHelper.getSecondaryTextColor(service, true)))) val palette = resource.palette
} update(
resource.bitmap, palette.getVibrantColor(
palette.getMutedColor(
MaterialValueHelper.getSecondaryTextColor(
service, true
)
)
)
)
}
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) { override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable) super.onLoadFailed(e, errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(service, true)) update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
} }
private fun update(bitmap: Bitmap?, color: Int) { private fun update(bitmap: Bitmap?, color: Int) {
// Set correct drawable for pause state // Set correct drawable for pause state
val playPauseRes = if (isPlaying) val playPauseRes = if (isPlaying) R.drawable.ic_pause_white_24dp
R.drawable.ic_pause_white_24dp else R.drawable.ic_play_arrow_white_32dp
else appWidgetView.setImageViewBitmap(
R.drawable.ic_play_arrow_white_32dp R.id.button_toggle_play_pause, createBitmap(
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, createBitmap(RetroUtil.getTintedVectorDrawable(service, playPauseRes, color)!!, 1f)) RetroUtil.getTintedVectorDrawable(
service, playPauseRes, color
)!!, 1f
)
)
// Set prev/next button drawables // Set prev/next button drawables
appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp, color)!!, 1f)) appWidgetView.setImageViewBitmap(
appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, color)!!, 1f)) R.id.button_next, createBitmap(
RetroUtil.getTintedVectorDrawable(
service, R.drawable.ic_skip_next_white_24dp, color
)!!, 1f
)
)
appWidgetView.setImageViewBitmap(
R.id.button_prev, createBitmap(
RetroUtil.getTintedVectorDrawable(
service, R.drawable.ic_skip_previous_white_24dp, color
)!!, 1f
)
)
val image = getAlbumArtDrawable(service.resources, bitmap) val image = getAlbumArtDrawable(service.resources, bitmap)
val roundedBitmap = createRoundedBitmap(image, imageSize, imageSize, cardRadius, 0f, 0f, 0f) val roundedBitmap = createRoundedBitmap(
appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap) image, imageSize, imageSize, cardRadius, 0f, 0f, 0f
)
appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap)
pushUpdate(appContext, appWidgetIds, appWidgetView) pushUpdate(appContext, appWidgetIds, appWidgetView)
} }
}) })
} }
} }
/** /**
* Link up various button actions using [PendingIntent]. * Link up various button actions using [PendingIntent].
*/ */
private fun linkButtons(context: Context, views: RemoteViews) { private fun linkButtons(context: Context, views: RemoteViews) {
val action = Intent(context, MainActivity::class.java).putExtra("expand", true) val action = Intent(context, MainActivity::class.java).putExtra("expand", true)
var pendingIntent: PendingIntent var pendingIntent: PendingIntent
val serviceName = ComponentName(context, MusicService::class.java) val serviceName = ComponentName(context, MusicService::class.java)
// Home // Home
action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
pendingIntent = PendingIntent.getActivity(context, 0, action, 0) pendingIntent = PendingIntent.getActivity(context, 0, action, 0)
views.setOnClickPendingIntent(R.id.image, pendingIntent) views.setOnClickPendingIntent(R.id.image, pendingIntent)
views.setOnClickPendingIntent(R.id.media_titles, pendingIntent) views.setOnClickPendingIntent(R.id.media_titles, pendingIntent)
// Previous track // Previous track
pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName) pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName)
views.setOnClickPendingIntent(R.id.button_prev, pendingIntent) views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
// Play and pause // Play and pause
pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName) pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName)
views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent) views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
// Next track // Next track
pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName) pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName)
views.setOnClickPendingIntent(R.id.button_next, pendingIntent) views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
} }
companion object { companion object {
const val NAME: String = "app_widget_small" const val NAME: String = "app_widget_small"
private var mInstance: AppWidgetSmall? = null private var mInstance: AppWidgetSmall? = null
private var imageSize = 0 private var imageSize = 0
private var cardRadius = 0f private var cardRadius = 0f
val instance: AppWidgetSmall val instance: AppWidgetSmall
@Synchronized get() { @Synchronized get() {
if (mInstance == null) { if (mInstance == null) {
mInstance = AppWidgetSmall() mInstance = AppWidgetSmall()
} }
return mInstance!! return mInstance!!
} }
} }
} }

View file

@ -15,15 +15,12 @@
package code.name.monkey.retromusic.appwidgets package code.name.monkey.retromusic.appwidgets
import android.app.PendingIntent import android.app.PendingIntent
import android.content.ComponentName import android.content.*
import android.content.Context
import android.content.Intent
import android.text.TextUtils import android.text.TextUtils
import android.view.View import android.view.View
import android.widget.RemoteViews import android.widget.RemoteViews
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import code.name.monkey.retromusic.App import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
@ -31,93 +28,146 @@ import code.name.monkey.retromusic.service.MusicService.*
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
class AppWidgetText : BaseAppWidget() { class AppWidgetText : BaseAppWidget() {
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) { override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_text) val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_text)
appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp, ContextCompat.getColor(context, R.color.md_white_1000))!!, 1f)) appWidgetView.setImageViewBitmap(
appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_previous_white_24dp, ContextCompat.getColor(context, R.color.md_white_1000))!!, 1f)) R.id.button_next, createBitmap(
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_play_arrow_white_32dp, ContextCompat.getColor(context, R.color.md_white_1000))!!, 1f)) RetroUtil.getTintedVectorDrawable(
context, R.drawable.ic_skip_next_white_24dp, ContextCompat.getColor(
context, R.color.md_white_1000
)
)!!, 1f
)
)
appWidgetView.setImageViewBitmap(
R.id.button_prev, createBitmap(
RetroUtil.getTintedVectorDrawable(
context, R.drawable.ic_skip_previous_white_24dp, ContextCompat.getColor(
context, R.color.md_white_1000
)
)!!, 1f
)
)
appWidgetView.setImageViewBitmap(
R.id.button_toggle_play_pause, createBitmap(
RetroUtil.getTintedVectorDrawable(
context, R.drawable.ic_play_arrow_white_32dp, ContextCompat.getColor(
context, R.color.md_white_1000
)
)!!, 1f
)
)
appWidgetView.setTextColor(R.id.title, ContextCompat.getColor(context, R.color.md_white_1000)) appWidgetView.setTextColor(
appWidgetView.setTextColor(R.id.text, ContextCompat.getColor(context, R.color.md_white_1000)) R.id.title, ContextCompat.getColor(context, R.color.md_white_1000)
)
appWidgetView.setTextColor(
R.id.text, ContextCompat.getColor(context, R.color.md_white_1000)
)
linkButtons(context, appWidgetView) linkButtons(context, appWidgetView)
pushUpdate(context, appWidgetIds, appWidgetView) pushUpdate(context, appWidgetIds, appWidgetView)
} }
/** /**
* Link up various button actions using [PendingIntent]. * Link up various button actions using [PendingIntent].
*/ */
private fun linkButtons(context: Context, views: RemoteViews) { private fun linkButtons(context: Context, views: RemoteViews) {
val action = Intent(context, MainActivity::class.java).putExtra("expand", true) val action = Intent(context, MainActivity::class.java).putExtra("expand", true)
var pendingIntent: PendingIntent var pendingIntent: PendingIntent
val serviceName = ComponentName(context, MusicService::class.java) val serviceName = ComponentName(context, MusicService::class.java)
// Home // Home
action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
pendingIntent = PendingIntent.getActivity(context, 0, action, 0) pendingIntent = PendingIntent.getActivity(context, 0, action, 0)
views.setOnClickPendingIntent(R.id.image, pendingIntent) views.setOnClickPendingIntent(R.id.image, pendingIntent)
views.setOnClickPendingIntent(R.id.media_titles, pendingIntent) views.setOnClickPendingIntent(R.id.media_titles, pendingIntent)
// Previous track // Previous track
pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName) pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName)
views.setOnClickPendingIntent(R.id.button_prev, pendingIntent) views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
// Play and pause // Play and pause
pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName) pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName)
views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent) views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
// Next track // Next track
pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName) pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName)
views.setOnClickPendingIntent(R.id.button_next, pendingIntent) views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
} }
override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) { override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_text) val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_text)
val isPlaying = service.isPlaying val isPlaying = service.isPlaying
val song = service.currentSong val song = service.currentSong
// Set the titles and artwork // Set the titles and artwork
if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) { if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE) appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
} else { } else {
appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE) appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE)
appWidgetView.setTextViewText(R.id.title, song.title) appWidgetView.setTextViewText(R.id.title, song.title)
appWidgetView.setTextViewText(R.id.text, song.artistName) appWidgetView.setTextViewText(R.id.text, song.artistName)
} }
// Link actions buttons to intents // Link actions buttons to intents
linkButtons(service, appWidgetView) linkButtons(service, appWidgetView)
// Set correct drawable for pause state // Set correct drawable for pause state
val playPauseRes = if (isPlaying) val playPauseRes = if (isPlaying) R.drawable.ic_pause_white_24dp
R.drawable.ic_pause_white_24dp else R.drawable.ic_play_arrow_white_32dp
else appWidgetView.setImageViewBitmap(
R.drawable.ic_play_arrow_white_32dp R.id.button_toggle_play_pause, createBitmap(
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, createBitmap(RetroUtil.getTintedVectorDrawable(App.getContext(), playPauseRes, ContextCompat.getColor(App.getContext(), R.color.md_white_1000))!!, 1f)) RetroUtil.getTintedVectorDrawable(
appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(RetroUtil.getTintedVectorDrawable(App.getContext(), R.drawable.ic_skip_next_white_24dp, ContextCompat.getColor(App.getContext(), R.color.md_white_1000))!!, 1f)) App.getContext(), playPauseRes, ContextCompat.getColor(
appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(RetroUtil.getTintedVectorDrawable(App.getContext(), R.drawable.ic_skip_previous_white_24dp, ContextCompat.getColor(App.getContext(), R.color.md_white_1000))!!, 1f)) App.getContext(), R.color.md_white_1000
)
)!!, 1f
)
)
appWidgetView.setImageViewBitmap(
R.id.button_next, createBitmap(
RetroUtil.getTintedVectorDrawable(
App.getContext(),
R.drawable.ic_skip_next_white_24dp,
ContextCompat.getColor(
App.getContext(), R.color.md_white_1000
)
)!!, 1f
)
)
appWidgetView.setImageViewBitmap(
R.id.button_prev, createBitmap(
RetroUtil.getTintedVectorDrawable(
App.getContext(),
R.drawable.ic_skip_previous_white_24dp,
ContextCompat.getColor(
App.getContext(), R.color.md_white_1000
)
)!!, 1f
)
)
pushUpdate(service.applicationContext, appWidgetIds, appWidgetView) pushUpdate(service.applicationContext, appWidgetIds, appWidgetView)
} }
companion object { companion object {
const val NAME: String = "app_widget_text" const val NAME: String = "app_widget_text"
private var mInstance: AppWidgetText? = null private var mInstance: AppWidgetText? = null
val instance: AppWidgetText
val instance: AppWidgetText @Synchronized get() {
@Synchronized get() { if (mInstance == null) {
if (mInstance == null) { mInstance = AppWidgetText()
mInstance = AppWidgetText() }
} return mInstance!!
return mInstance!! }
} }
}
} }

View file

@ -15,27 +15,36 @@
package code.name.monkey.retromusic.appwidgets package code.name.monkey.retromusic.appwidgets
import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetManager
import android.content.BroadcastReceiver import android.content.*
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Build import android.os.Build
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
class BootReceiver : BroadcastReceiver() { class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
val widgetManager = AppWidgetManager.getInstance(context) val widgetManager = AppWidgetManager.getInstance(context)
// Start music service if there are any existing widgets // Start music service if there are any existing widgets
if (widgetManager.getAppWidgetIds(ComponentName(context, AppWidgetBig::class.java)).isNotEmpty() || if (widgetManager.getAppWidgetIds(
widgetManager.getAppWidgetIds(ComponentName(context, AppWidgetClassic::class.java)).isNotEmpty() || ComponentName(
widgetManager.getAppWidgetIds(ComponentName(context, AppWidgetSmall::class.java)).isNotEmpty() || context, AppWidgetBig::class.java
widgetManager.getAppWidgetIds(ComponentName(context, AppWidgetCard::class.java)).isNotEmpty()) { )
val serviceIntent = Intent(context, MusicService::class.java) ).isNotEmpty() || widgetManager.getAppWidgetIds(
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { // not allowed on Oreo ComponentName(
context.startService(serviceIntent) context, AppWidgetClassic::class.java
} )
} ).isNotEmpty() || widgetManager.getAppWidgetIds(
} ComponentName(
context, AppWidgetSmall::class.java
)
).isNotEmpty() || widgetManager.getAppWidgetIds(
ComponentName(
context, AppWidgetCard::class.java
)
).isNotEmpty()) {
val serviceIntent = Intent(context, MusicService::class.java)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { // not allowed on Oreo
context.startService(serviceIntent)
}
}
}
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (c) 2019 Hemanth Savarala.
~
~ 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.
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?attr/colorPrimary" />
<item>
<bitmap
android:gravity="center"
android:src="@drawable/retro" />
</item>
</layer-list>

View file

@ -174,4 +174,9 @@
<item name="cornerSizeBottomLeft">0dp</item> <item name="cornerSizeBottomLeft">0dp</item>
</style> </style>
<style name="SplashTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="android:windowBackground">@drawable/splash</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
</resources> </resources>