feat(widget): add 4x1 AppWidgetProvider with play/pause and track info
This commit is contained in:
79
app/src/main/java/com/radiola/widget/PlayerWidgetProvider.kt
Normal file
79
app/src/main/java/com/radiola/widget/PlayerWidgetProvider.kt
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
package com.radiola.widget
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.appwidget.AppWidgetManager
|
||||||
|
import android.appwidget.AppWidgetProvider
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.widget.RemoteViews
|
||||||
|
import com.radiola.MainActivity
|
||||||
|
import com.radiola.R
|
||||||
|
import com.radiola.service.PlayerService
|
||||||
|
|
||||||
|
class PlayerWidgetProvider : AppWidgetProvider() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val ACTION_PLAY_PAUSE = "com.radiola.widget.ACTION_PLAY_PAUSE"
|
||||||
|
|
||||||
|
fun updateWidget(
|
||||||
|
context: Context,
|
||||||
|
appWidgetManager: AppWidgetManager,
|
||||||
|
appWidgetId: Int,
|
||||||
|
stationName: String,
|
||||||
|
trackTitle: String,
|
||||||
|
isPlaying: Boolean
|
||||||
|
) {
|
||||||
|
val views = RemoteViews(context.packageName, R.layout.widget_player)
|
||||||
|
|
||||||
|
views.setTextViewText(R.id.widget_station_name, stationName)
|
||||||
|
views.setTextViewText(R.id.widget_track_title, trackTitle)
|
||||||
|
views.setImageViewResource(
|
||||||
|
R.id.widget_play_pause,
|
||||||
|
if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play
|
||||||
|
)
|
||||||
|
|
||||||
|
// Open app on click
|
||||||
|
val openAppIntent = Intent(context, MainActivity::class.java).apply {
|
||||||
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||||
|
}
|
||||||
|
val openAppPendingIntent = PendingIntent.getActivity(
|
||||||
|
context, 0, openAppIntent,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.widget_root, openAppPendingIntent)
|
||||||
|
|
||||||
|
// Play/Pause button
|
||||||
|
val playPauseIntent = Intent(context, PlayerWidgetProvider::class.java).apply {
|
||||||
|
action = ACTION_PLAY_PAUSE
|
||||||
|
}
|
||||||
|
val playPausePendingIntent = PendingIntent.getBroadcast(
|
||||||
|
context, 1, playPauseIntent,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.widget_play_pause, playPausePendingIntent)
|
||||||
|
|
||||||
|
appWidgetManager.updateAppWidget(appWidgetId, views)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUpdate(
|
||||||
|
context: Context,
|
||||||
|
appWidgetManager: AppWidgetManager,
|
||||||
|
appWidgetIds: IntArray
|
||||||
|
) {
|
||||||
|
for (appWidgetId in appWidgetIds) {
|
||||||
|
updateWidget(context, appWidgetManager, appWidgetId, "radiOLA", "", false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
super.onReceive(context, intent)
|
||||||
|
if (intent.action == ACTION_PLAY_PAUSE) {
|
||||||
|
// Start service to handle play/pause
|
||||||
|
val serviceIntent = Intent(context, PlayerService::class.java).apply {
|
||||||
|
action = ACTION_PLAY_PAUSE
|
||||||
|
}
|
||||||
|
context.startService(serviceIntent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
app/src/main/res/drawable/ic_pause.xml
Normal file
10
app/src/main/res/drawable/ic_pause.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="#FFFFFF">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M6,19h4L10,5L6,5v14zM14,5v14h4L18,5h-4z" />
|
||||||
|
</vector>
|
||||||
10
app/src/main/res/drawable/ic_play.xml
Normal file
10
app/src/main/res/drawable/ic_play.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="#FFFFFF">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M8,5v14l11,-7z" />
|
||||||
|
</vector>
|
||||||
6
app/src/main/res/drawable/widget_background.xml
Normal file
6
app/src/main/res/drawable/widget_background.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="#1E1E1E" />
|
||||||
|
<corners android:radius="16dp" />
|
||||||
|
</shape>
|
||||||
9
app/src/main/res/drawable/widget_cover_placeholder.xml
Normal file
9
app/src/main/res/drawable/widget_cover_placeholder.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<gradient
|
||||||
|
android:startColor="#667eea"
|
||||||
|
android:endColor="#764ba2"
|
||||||
|
android:angle="135" />
|
||||||
|
<corners android:radius="8dp" />
|
||||||
|
</shape>
|
||||||
52
app/src/main/res/layout/widget_player.xml
Normal file
52
app/src/main/res/layout/widget_player.xml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/widget_root"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/widget_background"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="12dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/widget_cover"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:background="@drawable/widget_cover_placeholder"
|
||||||
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/widget_station_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:ellipsize="end" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/widget_track_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="#AAAAAA"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:ellipsize="end" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/widget_play_pause"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/ic_play"
|
||||||
|
android:contentDescription="@string/player_play" />
|
||||||
|
</LinearLayout>
|
||||||
9
app/src/main/res/xml/player_widget_info.xml
Normal file
9
app/src/main/res/xml/player_widget_info.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:initialLayout="@layout/widget_player"
|
||||||
|
android:minWidth="250dp"
|
||||||
|
android:minHeight="40dp"
|
||||||
|
android:previewImage="@drawable/widget_cover_placeholder"
|
||||||
|
android:resizeMode="horizontal"
|
||||||
|
android:updatePeriodMillis="0"
|
||||||
|
android:widgetCategory="home_screen" />
|
||||||
Reference in New Issue
Block a user