mirror of
https://github.com/home-assistant/android
synced 2024-10-15 20:43:06 +00:00
Add volume up/down buttons on media player widget (#2139)
This commit is contained in:
parent
e21d095195
commit
5d9a9df0bb
|
@ -48,9 +48,14 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() {
|
|||
"io.homeassistant.companion.android.widgets.media_player_controls.MediaPlayerControlsWidget.CALL_FASTFORWARD"
|
||||
internal const val CALL_NEXT_TRACK =
|
||||
"io.homeassistant.companion.android.widgets.media_player_controls.MediaPlayerControlsWidget.CALL_NEXT_TRACK"
|
||||
internal const val CALL_VOLUME_DOWN =
|
||||
"io.homeassistant.companion.android.widgets.media_player_controls.MediaPlayerControlsWidget.CALL_VOLUME_DOWN"
|
||||
internal const val CALL_VOLUME_UP =
|
||||
"io.homeassistant.companion.android.widgets.media_player_controls.MediaPlayerControlsWidget.CALL_VOLUME_UP"
|
||||
|
||||
internal const val EXTRA_ENTITY_ID = "EXTRA_ENTITY_ID"
|
||||
internal const val EXTRA_LABEL = "EXTRA_LABEL"
|
||||
internal const val EXTRA_SHOW_VOLUME = "EXTRA_SHOW_VOLUME"
|
||||
internal const val EXTRA_SHOW_SKIP = "EXTRA_INCLUDE_SKIP"
|
||||
internal const val EXTRA_SHOW_SEEK = "EXTRA_INCLUDE_SEEK"
|
||||
}
|
||||
|
@ -122,11 +127,22 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() {
|
|||
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
|
||||
}
|
||||
|
||||
val volumeDownIntent = Intent(context, MediaPlayerControlsWidget::class.java).apply {
|
||||
action = CALL_VOLUME_DOWN
|
||||
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
|
||||
}
|
||||
|
||||
val volumeUpIntent = Intent(context, MediaPlayerControlsWidget::class.java).apply {
|
||||
action = CALL_VOLUME_UP
|
||||
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
|
||||
}
|
||||
|
||||
return RemoteViews(context.packageName, R.layout.widget_media_controls).apply {
|
||||
val widget = mediaPlayCtrlWidgetDao.get(appWidgetId)
|
||||
if (widget != null) {
|
||||
val entityId: String = widget.entityId
|
||||
var label: String? = widget.label
|
||||
val showVolume: Boolean = widget.showVolume
|
||||
val showSkip: Boolean = widget.showSkip
|
||||
val showSeek: Boolean = widget.showSeek
|
||||
val entity = getEntity(context, widget.entityId, suggestedEntity)
|
||||
|
@ -284,6 +300,32 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() {
|
|||
)
|
||||
)
|
||||
|
||||
if (showVolume) {
|
||||
setOnClickPendingIntent(
|
||||
R.id.widgetVolumeDownButton,
|
||||
PendingIntent.getBroadcast(
|
||||
context,
|
||||
appWidgetId,
|
||||
volumeDownIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
)
|
||||
setOnClickPendingIntent(
|
||||
R.id.widgetVolumeUpButton,
|
||||
PendingIntent.getBroadcast(
|
||||
context,
|
||||
appWidgetId,
|
||||
volumeUpIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
)
|
||||
setViewVisibility(R.id.widgetVolumeDownButton, View.VISIBLE)
|
||||
setViewVisibility(R.id.widgetVolumeUpButton, View.VISIBLE)
|
||||
} else {
|
||||
setViewVisibility(R.id.widgetVolumeDownButton, View.GONE)
|
||||
setViewVisibility(R.id.widgetVolumeUpButton, View.GONE)
|
||||
}
|
||||
|
||||
if (showSkip) {
|
||||
setOnClickPendingIntent(
|
||||
R.id.widgetPrevTrackButton,
|
||||
|
@ -390,6 +432,8 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() {
|
|||
CALL_PLAYPAUSE -> callPlayPauseService(appWidgetId)
|
||||
CALL_FASTFORWARD -> callFastForwardService(context, appWidgetId)
|
||||
CALL_NEXT_TRACK -> callNextTrackService(appWidgetId)
|
||||
CALL_VOLUME_DOWN -> callVolumeDownService(appWidgetId)
|
||||
CALL_VOLUME_UP -> callVolumeUpService(appWidgetId)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -400,8 +444,9 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() {
|
|||
val labelSelection: String? = extras.getString(EXTRA_LABEL)
|
||||
val showSkip: Boolean? = extras.getBoolean(EXTRA_SHOW_SKIP)
|
||||
val showSeek: Boolean? = extras.getBoolean(EXTRA_SHOW_SEEK)
|
||||
val showVolume: Boolean? = extras.getBoolean(EXTRA_SHOW_VOLUME)
|
||||
|
||||
if (entitySelection == null || showSkip == null || showSeek == null) {
|
||||
if (entitySelection == null || showSkip == null || showSeek == null || showVolume == null) {
|
||||
Log.e(TAG, "Did not receive complete configuration data")
|
||||
return
|
||||
}
|
||||
|
@ -418,7 +463,8 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() {
|
|||
entitySelection,
|
||||
labelSelection,
|
||||
showSkip,
|
||||
showSeek
|
||||
showSeek,
|
||||
showVolume
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -600,6 +646,56 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun callVolumeDownService(appWidgetId: Int) {
|
||||
mainScope.launch {
|
||||
Log.d(TAG, "Retrieving media player entity for app widget $appWidgetId")
|
||||
val entity: MediaPlayerControlsWidgetEntity? = mediaPlayCtrlWidgetDao.get(appWidgetId)
|
||||
|
||||
if (entity == null) {
|
||||
Log.d(TAG, "Failed to retrieve media player entity")
|
||||
return@launch
|
||||
}
|
||||
|
||||
Log.d(
|
||||
TAG,
|
||||
"Calling volume down service:" + System.lineSeparator() +
|
||||
"entity id: " + entity.entityId + System.lineSeparator()
|
||||
)
|
||||
|
||||
val domain = "media_player"
|
||||
val service = "volume_down"
|
||||
|
||||
val serviceDataMap: HashMap<String, Any> = hashMapOf("entity_id" to entity.entityId)
|
||||
|
||||
integrationUseCase.callService(domain, service, serviceDataMap)
|
||||
}
|
||||
}
|
||||
|
||||
private fun callVolumeUpService(appWidgetId: Int) {
|
||||
mainScope.launch {
|
||||
Log.d(TAG, "Retrieving media player entity for app widget $appWidgetId")
|
||||
val entity: MediaPlayerControlsWidgetEntity? = mediaPlayCtrlWidgetDao.get(appWidgetId)
|
||||
|
||||
if (entity == null) {
|
||||
Log.d(TAG, "Failed to retrieve media player entity")
|
||||
return@launch
|
||||
}
|
||||
|
||||
Log.d(
|
||||
TAG,
|
||||
"Calling volume up service:" + System.lineSeparator() +
|
||||
"entity id: " + entity.entityId + System.lineSeparator()
|
||||
)
|
||||
|
||||
val domain = "media_player"
|
||||
val service = "volume_up"
|
||||
|
||||
val serviceDataMap: HashMap<String, Any> = hashMapOf("entity_id" to entity.entityId)
|
||||
|
||||
integrationUseCase.callService(domain, service, serviceDataMap)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDeleted(context: Context, appWidgetIds: IntArray) {
|
||||
mediaPlayCtrlWidgetDao = AppDatabase.getInstance(context).mediaPlayCtrlWidgetDao()
|
||||
// When the user deletes the widget, delete the preference associated with it.
|
||||
|
|
|
@ -103,6 +103,7 @@ class MediaPlayerControlsWidgetConfigureActivity : BaseActivity() {
|
|||
if (mediaPlayerWidget != null) {
|
||||
binding.label.setText(mediaPlayerWidget.label)
|
||||
binding.widgetTextConfigEntityId.setText(mediaPlayerWidget.entityId)
|
||||
binding.widgetShowVolumeButtonCheckbox.isChecked = mediaPlayerWidget.showVolume
|
||||
binding.widgetShowSeekButtonsCheckbox.isChecked = mediaPlayerWidget.showSeek
|
||||
binding.widgetShowSkipButtonsCheckbox.isChecked = mediaPlayerWidget.showSkip
|
||||
val entity = runBlocking {
|
||||
|
@ -187,6 +188,10 @@ class MediaPlayerControlsWidgetConfigureActivity : BaseActivity() {
|
|||
MediaPlayerControlsWidget.EXTRA_LABEL,
|
||||
binding.label.text.toString()
|
||||
)
|
||||
intent.putExtra(
|
||||
MediaPlayerControlsWidget.EXTRA_SHOW_VOLUME,
|
||||
binding.widgetShowVolumeButtonCheckbox.isChecked
|
||||
)
|
||||
intent.putExtra(
|
||||
MediaPlayerControlsWidget.EXTRA_SHOW_SKIP,
|
||||
binding.widgetShowSkipButtonsCheckbox.isChecked
|
||||
|
|
8
app/src/main/res/drawable/ic_volume_down.xml
Normal file
8
app/src/main/res/drawable/ic_volume_down.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path android:fillColor="#000" android:pathData="M19,13H5V11H19V13Z" />
|
||||
</vector>
|
8
app/src/main/res/drawable/ic_volume_up.xml
Normal file
8
app/src/main/res/drawable/ic_volume_up.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path android:fillColor="#000" android:pathData="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" />
|
||||
</vector>
|
|
@ -118,6 +118,30 @@
|
|||
android:layout_alignParentBottom="true"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/widgetVolumeDownButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:contentDescription="@string/widget_media_volume_down_button"
|
||||
android:padding="4dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_volume_down"
|
||||
android:tint="@color/colorIcon" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/widgetVolumeUpButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:contentDescription="@string/widget_media_volume_up_button"
|
||||
android:padding="4dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_volume_up"
|
||||
android:tint="@color/colorIcon" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/widgetPrevTrackButton"
|
||||
android:layout_width="0dp"
|
||||
|
|
|
@ -38,6 +38,16 @@
|
|||
android:inputType="text" />
|
||||
</LinearLayout>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/widget_show_volume_button_checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:layout_margin="5dp"
|
||||
android:checked="true"
|
||||
android:layoutDirection="rtl"
|
||||
android:text="@string/widget_media_show_volume" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/widget_show_skip_buttons_checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -65,7 +65,7 @@ import io.homeassistant.companion.android.common.R as commonR
|
|||
Favorites::class,
|
||||
Setting::class
|
||||
],
|
||||
version = 22,
|
||||
version = 23,
|
||||
exportSchema = false
|
||||
)
|
||||
@TypeConverters(
|
||||
|
@ -129,7 +129,8 @@ abstract class AppDatabase : RoomDatabase() {
|
|||
MIGRATION_18_19,
|
||||
MIGRATION_19_20,
|
||||
MIGRATION_20_21,
|
||||
MIGRATION_21_22
|
||||
MIGRATION_21_22,
|
||||
MIGRATION_22_23
|
||||
)
|
||||
.fallbackToDestructiveMigration()
|
||||
.build()
|
||||
|
@ -476,6 +477,12 @@ abstract class AppDatabase : RoomDatabase() {
|
|||
}
|
||||
}
|
||||
|
||||
private val MIGRATION_22_23 = object : Migration(22, 23) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE `mediaplayctrls_widgets` ADD `showVolume` INTEGER NOT NULL DEFAULT '0'")
|
||||
}
|
||||
}
|
||||
|
||||
private fun createNotificationChannel() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val notificationManager = appContext.getSystemService<NotificationManager>()!!
|
||||
|
|
|
@ -15,5 +15,7 @@ data class MediaPlayerControlsWidgetEntity(
|
|||
@ColumnInfo(name = "showSkip")
|
||||
val showSkip: Boolean,
|
||||
@ColumnInfo(name = "showSeek")
|
||||
val showSeek: Boolean
|
||||
val showSeek: Boolean,
|
||||
@ColumnInfo(name = "showVolume")
|
||||
val showVolume: Boolean
|
||||
)
|
||||
|
|
|
@ -722,7 +722,10 @@
|
|||
<string name="widget_media_player_description">Media Player Widget</string>
|
||||
<string name="widget_media_playpause_button">Play/Pause</string>
|
||||
<string name="widget_media_prev_track_button">Previous Track</string>
|
||||
<string name="widget_media_volume_down_button">Volume Down</string>
|
||||
<string name="widget_media_volume_up_button">Volume Up</string>
|
||||
<string name="widget_media_rewind_button">Rewind</string>
|
||||
<string name="widget_media_show_volume">Show Volume Buttons</string>
|
||||
<string name="widget_media_show_seek">Show Seek Buttons</string>
|
||||
<string name="widget_media_show_skip">Show Skip Buttons</string>
|
||||
<string name="widget_separator_input_hint">No separator</string>
|
||||
|
|
Loading…
Reference in a new issue