Skip to content

Instantly share code, notes, and snippets.

@JesusM
Created November 13, 2021 11:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JesusM/617e5c531de1e305c11072c6ba6d4afd to your computer and use it in GitHub Desktop.
Save JesusM/617e5c531de1e305c11072c6ba6d4afd to your computer and use it in GitHub Desktop.
Initial implementation of App Widget using Glance API
package com.jesusmc.spotifysample.mobile.ui.widgets.compose
import android.graphics.Bitmap
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.glance.GlanceModifier
import androidx.glance.Image
import androidx.glance.ImageProvider
import androidx.glance.action.*
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.background
import androidx.glance.background
import androidx.glance.layout.*
import androidx.glance.text.Text
import androidx.glance.text.TextAlign
import androidx.glance.text.TextStyle
import androidx.glance.unit.ColorProvider
import com.jesusmc.spotifysample.mobile.R
import com.jesusmc.spotifysample.mobile.domain.player.model.AudioTrackItem
import com.jesusmc.spotifysample.mobile.domain.player.model.PlaybackState
import com.jesusmc.spotifysample.mobile.domain.player.service.AudioPlayerService
import com.jesusmc.spotifysample.mobile.ui.home.compose.HomeActivityCompose
import com.jesusmc.spotifysample.mobile.ui.player.AudioPlayerActivity
class PlayerGlanceWidget(
private val playerWidgetData: PlayerWidgetData = PlayerWidgetData()
) : GlanceAppWidget() {
@Composable
override fun Content() {
val colors = playerWidgetData.colors
val currentTrackImage = playerWidgetData.currentTrackImage
Row(
modifier = GlanceModifier
.fillMaxSize()
.background(colors.dayColor, colors.nightColor)
.padding(0.dp)
.clickable(
onClick = actionLaunchActivity(
when (playerWidgetData.playbackState) {
PlaybackState.STOPPED -> {
HomeActivityCompose::class.java
}
else -> {
AudioPlayerActivity::class.java
}
}
)
)
) {
currentTrackImage?.let { image ->
Image(
modifier = GlanceModifier
.fillMaxHeight()
.width(100.dp)
.background(colors.textColor),
provider = ImageProvider(image),
contentDescription = "app widget image description",
contentScale = ContentScale.FillBounds
)
}
val currentTrack = playerWidgetData.currentTrack
Column(modifier = GlanceModifier.fillMaxSize().padding(8.dp)) {
// Usage of raw text is because atm stringResources is not supported.
Text(
text = currentTrack?.name ?: "Touch to start playback",
modifier = GlanceModifier.defaultWeight().fillMaxWidth(),
style = TextStyle(
color = ColorProvider(colors.textColor),
textAlign = TextAlign.Center
),
)
Row(
modifier = GlanceModifier.defaultWeight().fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Image(
provider = ImageProvider(R.drawable.media_session_service_notification_ic_skip_to_previous),
contentDescription = "app widget image description",
modifier = GlanceModifier.defaultWeight().clickable(
onClick = actionRunCallback<PlayerRunnable>(parameters = mutableActionParametersOf().apply {
set(
ActionParameters.Key(ACTION_KEY),
AudioPlayerService.ACTION_PREVIOUS
)
})
)
)
val playbackState = playerWidgetData.playbackState
Image(
provider = ImageProvider(
when (playbackState) {
PlaybackState.PLAYING -> R.drawable.ic_pause_white_audio_player
else -> R.drawable.ic_play_arrow
}
),
contentDescription = "app widget image description",
modifier = GlanceModifier.defaultWeight().clickable(
onClick = actionRunCallback<PlayerRunnable>(parameters = mutableActionParametersOf().apply {
set(
ActionParameters.Key(ACTION_KEY), when (playbackState) {
PlaybackState.PLAYING -> AudioPlayerService.ACTION_PAUSE
else -> AudioPlayerService.ACTION_PLAY
}
)
})
)
)
Image(
provider = ImageProvider(R.drawable.ic_skip_next_24dp),
contentDescription = "app widget image description",
modifier = GlanceModifier.defaultWeight().clickable(
onClick = actionRunCallback<PlayerRunnable>(parameters = mutableActionParametersOf().apply {
set(
ActionParameters.Key(ACTION_KEY),
AudioPlayerService.ACTION_NEXT
)
})
)
)
}
}
}
}
}
data class PlayerWidgetData(
val playbackState: PlaybackState = PlaybackState.STOPPED,
val currentTrack: AudioTrackItem? = null,
val currentTrackImage: Bitmap? = null,
val colors: Background = Background(Color.LightGray, Color.DarkGray, Color.White)
)
data class Background(val dayColor: Color, val nightColor: Color, val textColor: Color)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment