widget: fix widget failing to update
Turns out WidgetProvider doesn't support Hilt. Of course, it let me know by silently failing on an exception for no reason.
This commit is contained in:
parent
055d25e3e1
commit
9c7fa86ead
3 changed files with 58 additions and 55 deletions
|
@ -25,6 +25,8 @@ import androidx.core.content.ContextCompat
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import org.oxycblt.auxio.playback.state.PlaybackStateManager
|
import org.oxycblt.auxio.playback.state.PlaybackStateManager
|
||||||
|
import org.oxycblt.auxio.util.logD
|
||||||
|
import org.oxycblt.auxio.util.logE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A [BroadcastReceiver] that forwards [Intent.ACTION_MEDIA_BUTTON] [Intent]s to [PlaybackService].
|
* A [BroadcastReceiver] that forwards [Intent.ACTION_MEDIA_BUTTON] [Intent]s to [PlaybackService].
|
||||||
|
@ -35,6 +37,7 @@ class MediaButtonReceiver : BroadcastReceiver() {
|
||||||
@Inject lateinit var playbackManager: PlaybackStateManager
|
@Inject lateinit var playbackManager: PlaybackStateManager
|
||||||
|
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
super.onRecieve()
|
||||||
if (playbackManager.queue.currentSong != null) {
|
if (playbackManager.queue.currentSong != null) {
|
||||||
// We have a song, so we can assume that the service will start a foreground state.
|
// We have a song, so we can assume that the service will start a foreground state.
|
||||||
// At least, I hope. Again, *this is why we don't do this*. I cannot describe how
|
// At least, I hope. Again, *this is why we don't do this*. I cannot describe how
|
||||||
|
|
|
@ -65,7 +65,7 @@ constructor(
|
||||||
val song = playbackManager.queue.currentSong
|
val song = playbackManager.queue.currentSong
|
||||||
if (song == null) {
|
if (song == null) {
|
||||||
logD("No song, resetting widget")
|
logD("No song, resetting widget")
|
||||||
widgetProvider.update(context, null)
|
widgetProvider.update(context, uiSettings, null)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ constructor(
|
||||||
|
|
||||||
override fun onCompleted(bitmap: Bitmap?) {
|
override fun onCompleted(bitmap: Bitmap?) {
|
||||||
val state = PlaybackState(song, bitmap, isPlaying, repeatMode, isShuffled)
|
val state = PlaybackState(song, bitmap, isPlaying, repeatMode, isShuffled)
|
||||||
widgetProvider.update(context, state)
|
widgetProvider.update(context, uiSettings, state)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,6 @@ import android.os.Bundle
|
||||||
import android.util.SizeF
|
import android.util.SizeF
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.RemoteViews
|
import android.widget.RemoteViews
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
|
||||||
import javax.inject.Inject
|
|
||||||
import org.oxycblt.auxio.BuildConfig
|
import org.oxycblt.auxio.BuildConfig
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
import org.oxycblt.auxio.music.resolveNames
|
import org.oxycblt.auxio.music.resolveNames
|
||||||
|
@ -42,10 +40,7 @@ import org.oxycblt.auxio.util.*
|
||||||
* state alongside actions to control it.
|
* state alongside actions to control it.
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
|
||||||
class WidgetProvider : AppWidgetProvider() {
|
class WidgetProvider : AppWidgetProvider() {
|
||||||
@Inject lateinit var uiSettings: UISettings
|
|
||||||
|
|
||||||
override fun onUpdate(
|
override fun onUpdate(
|
||||||
context: Context,
|
context: Context,
|
||||||
appWidgetManager: AppWidgetManager,
|
appWidgetManager: AppWidgetManager,
|
||||||
|
@ -75,9 +70,10 @@ class WidgetProvider : AppWidgetProvider() {
|
||||||
/**
|
/**
|
||||||
* Update the currently shown layout based on the given [WidgetComponent.PlaybackState]
|
* Update the currently shown layout based on the given [WidgetComponent.PlaybackState]
|
||||||
* @param context [Context] required to update the widget layout.
|
* @param context [Context] required to update the widget layout.
|
||||||
|
* @param uiSettings [UISettings] to obtain round mode configuration
|
||||||
* @param state [WidgetComponent.PlaybackState] to show, or null if no playback is going on.
|
* @param state [WidgetComponent.PlaybackState] to show, or null if no playback is going on.
|
||||||
*/
|
*/
|
||||||
fun update(context: Context, state: WidgetComponent.PlaybackState?) {
|
fun update(context: Context, uiSettings: UISettings, state: WidgetComponent.PlaybackState?) {
|
||||||
if (state == null) {
|
if (state == null) {
|
||||||
// No state, use the default widget.
|
// No state, use the default widget.
|
||||||
reset(context)
|
reset(context)
|
||||||
|
@ -89,11 +85,11 @@ class WidgetProvider : AppWidgetProvider() {
|
||||||
// the widget elements, plus some leeway for text sizing.
|
// the widget elements, plus some leeway for text sizing.
|
||||||
val views =
|
val views =
|
||||||
mapOf(
|
mapOf(
|
||||||
SizeF(180f, 100f) to newThinLayout(context, state),
|
SizeF(180f, 100f) to newThinLayout(context, uiSettings, state),
|
||||||
SizeF(180f, 152f) to newSmallLayout(context, state),
|
SizeF(180f, 152f) to newSmallLayout(context, uiSettings, state),
|
||||||
SizeF(272f, 152f) to newWideLayout(context, state),
|
SizeF(272f, 152f) to newWideLayout(context, uiSettings, state),
|
||||||
SizeF(180f, 272f) to newMediumLayout(context, state),
|
SizeF(180f, 272f) to newMediumLayout(context, uiSettings, state),
|
||||||
SizeF(272f, 272f) to newLargeLayout(context, state))
|
SizeF(272f, 272f) to newLargeLayout(context, uiSettings, state))
|
||||||
|
|
||||||
// Manually update AppWidgetManager with the new views.
|
// Manually update AppWidgetManager with the new views.
|
||||||
val awm = AppWidgetManager.getInstance(context)
|
val awm = AppWidgetManager.getInstance(context)
|
||||||
|
@ -131,66 +127,66 @@ class WidgetProvider : AppWidgetProvider() {
|
||||||
|
|
||||||
// --- LAYOUTS ---
|
// --- LAYOUTS ---
|
||||||
|
|
||||||
/**
|
|
||||||
* Create and configure a [RemoteViews] for [R.layout.widget_default], intended for situations
|
|
||||||
* where no other widget layout is applicable.
|
|
||||||
* @param context [Context] required to create the [RemoteViews].
|
|
||||||
*/
|
|
||||||
private fun newDefaultLayout(context: Context) =
|
private fun newDefaultLayout(context: Context) =
|
||||||
newRemoteViews(context, R.layout.widget_default)
|
newRemoteViews(context, R.layout.widget_default)
|
||||||
|
|
||||||
/**
|
private fun newThinLayout(
|
||||||
* Create and configure a [RemoteViews] for [R.layout.widget_thin], intended for extremely small
|
context: Context,
|
||||||
* grid sizes on phones in landscape mode.
|
uiSettings: UISettings,
|
||||||
* @param context [Context] required to create the [RemoteViews].
|
state: WidgetComponent.PlaybackState
|
||||||
*/
|
) =
|
||||||
private fun newThinLayout(context: Context, state: WidgetComponent.PlaybackState) =
|
|
||||||
newRemoteViews(context, R.layout.widget_thin)
|
newRemoteViews(context, R.layout.widget_thin)
|
||||||
.setupBackground()
|
.setupBackground(
|
||||||
|
uiSettings,
|
||||||
|
)
|
||||||
.setupPlaybackState(context, state)
|
.setupPlaybackState(context, state)
|
||||||
.setupTimelineControls(context, state)
|
.setupTimelineControls(context, state)
|
||||||
|
|
||||||
/**
|
private fun newSmallLayout(
|
||||||
* Create and configure a [RemoteViews] for [R.layout.widget_small], intended to be a
|
context: Context,
|
||||||
* modestly-sized default layout for most devices.
|
uiSettings: UISettings,
|
||||||
* @param context [Context] required to create the [RemoteViews].
|
state: WidgetComponent.PlaybackState
|
||||||
*/
|
) =
|
||||||
private fun newSmallLayout(context: Context, state: WidgetComponent.PlaybackState) =
|
|
||||||
newRemoteViews(context, R.layout.widget_small)
|
newRemoteViews(context, R.layout.widget_small)
|
||||||
.setupBar()
|
.setupBar(
|
||||||
|
uiSettings,
|
||||||
|
)
|
||||||
.setupCover(context, state)
|
.setupCover(context, state)
|
||||||
.setupTimelineControls(context, state)
|
.setupTimelineControls(context, state)
|
||||||
|
|
||||||
/**
|
private fun newMediumLayout(
|
||||||
* Create and configure a [RemoteViews] for [R.layout.widget_medium], intended to be a taller
|
context: Context,
|
||||||
* widget that shows more information about the currently playing song.
|
uiSettings: UISettings,
|
||||||
* @param context [Context] required to create the [RemoteViews].
|
state: WidgetComponent.PlaybackState
|
||||||
*/
|
) =
|
||||||
private fun newMediumLayout(context: Context, state: WidgetComponent.PlaybackState) =
|
|
||||||
newRemoteViews(context, R.layout.widget_medium)
|
newRemoteViews(context, R.layout.widget_medium)
|
||||||
.setupBackground()
|
.setupBackground(
|
||||||
|
uiSettings,
|
||||||
|
)
|
||||||
.setupPlaybackState(context, state)
|
.setupPlaybackState(context, state)
|
||||||
.setupTimelineControls(context, state)
|
.setupTimelineControls(context, state)
|
||||||
|
|
||||||
/**
|
private fun newWideLayout(
|
||||||
* Create and configure a [RemoteViews] for [R.layout.widget_wide], intended to be a wider
|
context: Context,
|
||||||
* version of [R.layout.widget_small] that shows additional controls.
|
uiSettings: UISettings,
|
||||||
* @param context [Context] required to create the [RemoteViews].
|
state: WidgetComponent.PlaybackState
|
||||||
*/
|
) =
|
||||||
private fun newWideLayout(context: Context, state: WidgetComponent.PlaybackState) =
|
|
||||||
newRemoteViews(context, R.layout.widget_wide)
|
newRemoteViews(context, R.layout.widget_wide)
|
||||||
.setupBar()
|
.setupBar(
|
||||||
|
uiSettings,
|
||||||
|
)
|
||||||
.setupCover(context, state)
|
.setupCover(context, state)
|
||||||
.setupFullControls(context, state)
|
.setupFullControls(context, state)
|
||||||
|
|
||||||
/**
|
private fun newLargeLayout(
|
||||||
* Create and configure a [RemoteViews] for [R.layout.widget_large], intended to be a wider
|
context: Context,
|
||||||
* version of [R.layout.widget_medium] that shows additional controls.
|
uiSettings: UISettings,
|
||||||
* @param context [Context] required to create the [RemoteViews].
|
state: WidgetComponent.PlaybackState
|
||||||
*/
|
) =
|
||||||
private fun newLargeLayout(context: Context, state: WidgetComponent.PlaybackState) =
|
|
||||||
newRemoteViews(context, R.layout.widget_large)
|
newRemoteViews(context, R.layout.widget_large)
|
||||||
.setupBackground()
|
.setupBackground(
|
||||||
|
uiSettings,
|
||||||
|
)
|
||||||
.setupPlaybackState(context, state)
|
.setupPlaybackState(context, state)
|
||||||
.setupFullControls(context, state)
|
.setupFullControls(context, state)
|
||||||
|
|
||||||
|
@ -198,7 +194,9 @@ class WidgetProvider : AppWidgetProvider() {
|
||||||
* Set up the control bar in a [RemoteViews] layout that contains one. This is a kind of
|
* Set up the control bar in a [RemoteViews] layout that contains one. This is a kind of
|
||||||
* "floating" drawable that sits in front of the cover and contains the controls.
|
* "floating" drawable that sits in front of the cover and contains the controls.
|
||||||
*/
|
*/
|
||||||
private fun RemoteViews.setupBar(): RemoteViews {
|
private fun RemoteViews.setupBar(
|
||||||
|
uiSettings: UISettings,
|
||||||
|
): RemoteViews {
|
||||||
// Below API 31, enable a rounded bar only if round mode is enabled.
|
// Below API 31, enable a rounded bar only if round mode is enabled.
|
||||||
// On API 31+, the bar should always be round in order to fit in with other widgets.
|
// On API 31+, the bar should always be round in order to fit in with other widgets.
|
||||||
val background =
|
val background =
|
||||||
|
@ -215,7 +213,9 @@ class WidgetProvider : AppWidgetProvider() {
|
||||||
* Set up the background in a [RemoteViews] layout that contains one. This is largely
|
* Set up the background in a [RemoteViews] layout that contains one. This is largely
|
||||||
* self-explanatory, being a solid-color background that sits behind the cover and controls.
|
* self-explanatory, being a solid-color background that sits behind the cover and controls.
|
||||||
*/
|
*/
|
||||||
private fun RemoteViews.setupBackground(): RemoteViews {
|
private fun RemoteViews.setupBackground(
|
||||||
|
uiSettings: UISettings,
|
||||||
|
): RemoteViews {
|
||||||
// Below API 31, enable a rounded background only if round mode is enabled.
|
// Below API 31, enable a rounded background only if round mode is enabled.
|
||||||
// On API 31+, the background should always be round in order to fit in with other
|
// On API 31+, the background should always be round in order to fit in with other
|
||||||
// widgets.
|
// widgets.
|
||||||
|
|
Loading…
Reference in a new issue