Put playback speed in widget (#5774)

This commit is contained in:
Nicolas Araujo 2022-04-24 17:36:37 -03:00 committed by GitHub
parent 1b2102d753
commit 9b78d4c3f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 218 additions and 74 deletions

View File

@ -43,6 +43,17 @@
android:allowAudioPlaybackCapture="true"
android:networkSecurityConfig="@xml/network_security_config">
<activity
android:name=".activity.PlaybackSpeedDialogActivity"
android:noHistory="true"
android:exported="false"
android:excludeFromRecents="true"
android:theme="@style/Theme.AntennaPod.Light.Translucent">
<intent-filter>
<action android:name="de.danoeh.antennapod.intents.PLAYBACK_SPEED" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<meta-data android:name="android.webkit.WebView.MetricsOptOut"
android:value="true"/>

View File

@ -0,0 +1,29 @@
package de.danoeh.antennapod.activity;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.DialogInterface;
import android.os.Bundle;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
public class PlaybackSpeedDialogActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getTranslucentTheme());
super.onCreate(savedInstanceState);
VariableSpeedDialog speedDialog = new InnerVariableSpeedDialog();
speedDialog.show(getSupportFragmentManager(), null);
}
public static class InnerVariableSpeedDialog extends VariableSpeedDialog {
@Override
public void onDismiss(@NonNull DialogInterface dialog) {
super.onDismiss(dialog);
getActivity().finish();
}
}
}

View File

@ -20,6 +20,7 @@ public class WidgetConfigActivity extends AppCompatActivity {
private SeekBar opacitySeekBar;
private TextView opacityTextView;
private View widgetPreview;
private CheckBox ckPlaybackSpeed;
private CheckBox ckRewind;
private CheckBox ckFastForward;
private CheckBox ckSkip;
@ -75,6 +76,8 @@ public class WidgetConfigActivity extends AppCompatActivity {
progress.setVisibility(View.VISIBLE);
progress.setText(R.string.position_default_label);
ckPlaybackSpeed = findViewById(R.id.ckPlaybackSpeed);
ckPlaybackSpeed.setOnClickListener(v -> displayPreviewPanel());
ckRewind = findViewById(R.id.ckRewind);
ckRewind.setOnClickListener(v -> displayPreviewPanel());
ckFastForward = findViewById(R.id.ckFastForward);
@ -84,10 +87,13 @@ public class WidgetConfigActivity extends AppCompatActivity {
}
private void displayPreviewPanel() {
boolean showExtendedPreview = ckRewind.isChecked() || ckFastForward.isChecked() || ckSkip.isChecked();
boolean showExtendedPreview =
ckPlaybackSpeed.isChecked() || ckRewind.isChecked() || ckFastForward.isChecked() || ckSkip.isChecked();
widgetPreview.findViewById(R.id.extendedButtonsContainer)
.setVisibility(showExtendedPreview ? View.VISIBLE : View.GONE);
widgetPreview.findViewById(R.id.butPlay).setVisibility(showExtendedPreview ? View.GONE : View.VISIBLE);
widgetPreview.findViewById(R.id.butPlaybackSpeed)
.setVisibility(ckPlaybackSpeed.isChecked() ? View.VISIBLE : View.GONE);
widgetPreview.findViewById(R.id.butFastForward)
.setVisibility(ckFastForward.isChecked() ? View.VISIBLE : View.GONE);
widgetPreview.findViewById(R.id.butSkip).setVisibility(ckSkip.isChecked() ? View.VISIBLE : View.GONE);
@ -100,6 +106,7 @@ public class WidgetConfigActivity extends AppCompatActivity {
SharedPreferences prefs = getSharedPreferences(PlayerWidget.PREFS_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(PlayerWidget.KEY_WIDGET_COLOR + appWidgetId, backgroundColor);
editor.putBoolean(PlayerWidget.KEY_WIDGET_PLAYBACK_SPEED + appWidgetId, ckPlaybackSpeed.isChecked());
editor.putBoolean(PlayerWidget.KEY_WIDGET_SKIP + appWidgetId, ckSkip.isChecked());
editor.putBoolean(PlayerWidget.KEY_WIDGET_REWIND + appWidgetId, ckRewind.isChecked());
editor.putBoolean(PlayerWidget.KEY_WIDGET_FAST_FORWARD + appWidgetId, ckFastForward.isChecked());

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
@ -16,91 +17,108 @@
android:id="@+id/widget_config_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:srcCompat="@drawable/teaser"
android:scaleType="centerCrop" />
android:scaleType="centerCrop"
app:srcCompat="@drawable/teaser" />
<include
android:id="@+id/widget_config_preview"
layout="@layout/player_widget"
android:layout_width="match_parent"
android:layout_height="96dp"
android:layout_gravity="center"
android:layout_margin="16dp" />
android:layout_margin="16dp"
layout="@layout/player_widget" />
</FrameLayout>
<LinearLayout
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/widget_opacity"
android:textSize="16sp"
android:textColor="?android:attr/textColorPrimary" />
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/widget_opacity_textView"
android:layout_width="0dp"
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/widget_opacity"
android:textSize="16sp"
android:textColor="?android:attr/textColorPrimary" />
<TextView
android:id="@+id/widget_opacity_textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="end"
android:text="100%"
android:textSize="16sp"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<SeekBar
android:id="@+id/widget_opacity_seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="end"
android:text="100%"
android:textSize="16sp"
android:textColor="?android:attr/textColorSecondary" />
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:max="100"
android:progress="100" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<CheckBox
android:id="@+id/ckPlaybackSpeed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Playback Speed" />
<CheckBox
android:id="@+id/ckRewind"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Rewind" />
<CheckBox
android:id="@+id/ckFastForward"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Forward" />
<CheckBox
android:id="@+id/ckSkip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Skip" />
</LinearLayout>
<Button
android:id="@+id/butConfirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/widget_create_button" />
</LinearLayout>
<SeekBar
android:id="@+id/widget_opacity_seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:max="100"
android:progress="100" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<CheckBox
android:id="@+id/ckRewind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Rewind" />
<CheckBox
android:id="@+id/ckFastForward"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Forward" />
<CheckBox
android:id="@+id/ckSkip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Skip" />
</LinearLayout>
<Button
android:id="@+id/butConfirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/widget_create_button" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>

View File

@ -14,6 +14,7 @@ public class PlayerWidget extends AppWidgetProvider {
public static final String PREFS_NAME = "PlayerWidgetPrefs";
private static final String KEY_ENABLED = "WidgetEnabled";
public static final String KEY_WIDGET_COLOR = "widget_color";
public static final String KEY_WIDGET_PLAYBACK_SPEED = "widget_playback_speed";
public static final String KEY_WIDGET_SKIP = "widget_skip";
public static final String KEY_WIDGET_FAST_FORWARD = "widget_fast_forward";
public static final String KEY_WIDGET_REWIND = "widget_rewind";
@ -47,6 +48,7 @@ public class PlayerWidget extends AppWidgetProvider {
for (int appWidgetId : appWidgetIds) {
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
prefs.edit().remove(KEY_WIDGET_COLOR + appWidgetId).apply();
prefs.edit().remove(KEY_WIDGET_PLAYBACK_SPEED + appWidgetId).apply();
prefs.edit().remove(KEY_WIDGET_REWIND + appWidgetId).apply();
prefs.edit().remove(KEY_WIDGET_FAST_FORWARD + appWidgetId).apply();
prefs.edit().remove(KEY_WIDGET_SKIP + appWidgetId).apply();

View File

@ -31,6 +31,7 @@ import de.danoeh.antennapod.core.util.TimeSpeedConverter;
import de.danoeh.antennapod.model.playback.Playable;
import de.danoeh.antennapod.playback.base.PlayerStatus;
import de.danoeh.antennapod.ui.appstartintent.MainActivityStarter;
import de.danoeh.antennapod.ui.appstartintent.PlaybackSpeedActivityStarter;
import de.danoeh.antennapod.ui.appstartintent.VideoPlayerActivityStarter;
/**
@ -73,6 +74,9 @@ public abstract class WidgetUpdater {
} else {
startMediaPlayer = new MainActivityStarter(context).withOpenPlayer().getPendingIntent();
}
PendingIntent startPlaybackSpeedDialog = new PlaybackSpeedActivityStarter(context).getPendingIntent();
RemoteViews views;
views = new RemoteViews(context.getPackageName(), R.layout.player_widget);
@ -81,6 +85,7 @@ public abstract class WidgetUpdater {
int iconSize = context.getResources().getDimensionPixelSize(android.R.dimen.app_icon_size);
views.setOnClickPendingIntent(R.id.layout_left, startMediaPlayer);
views.setOnClickPendingIntent(R.id.imgvCover, startMediaPlayer);
views.setOnClickPendingIntent(R.id.butPlaybackSpeed, startPlaybackSpeedDialog);
try {
icon = Glide.with(context)
@ -165,13 +170,15 @@ public abstract class WidgetUpdater {
} else {
views.setViewVisibility(R.id.layout_center, View.VISIBLE);
}
boolean showPlaybackSpeed = prefs.getBoolean(PlayerWidget.KEY_WIDGET_PLAYBACK_SPEED + id, false);
boolean showRewind = prefs.getBoolean(PlayerWidget.KEY_WIDGET_REWIND + id, false);
boolean showFastForward = prefs.getBoolean(PlayerWidget.KEY_WIDGET_FAST_FORWARD + id, false);
boolean showSkip = prefs.getBoolean(PlayerWidget.KEY_WIDGET_SKIP + id, false);
if (showRewind || showSkip || showFastForward) {
if (showPlaybackSpeed || showRewind || showSkip || showFastForward) {
views.setInt(R.id.extendedButtonsContainer, "setVisibility", View.VISIBLE);
views.setInt(R.id.butPlay, "setVisibility", View.GONE);
views.setInt(R.id.butPlaybackSpeed, "setVisibility", showPlaybackSpeed ? View.VISIBLE : View.GONE);
views.setInt(R.id.butRew, "setVisibility", showRewind ? View.VISIBLE : View.GONE);
views.setInt(R.id.butFastForward, "setVisibility", showFastForward ? View.VISIBLE : View.GONE);
views.setInt(R.id.butSkip, "setVisibility", showSkip ? View.VISIBLE : View.GONE);

View File

@ -88,6 +88,16 @@
android:orientation="horizontal"
android:visibility="gone">
<ImageButton
android:id="@+id/butPlaybackSpeed"
android:layout_width="36dp"
android:layout_height="36dp"
android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/playback_speed"
android:layout_marginEnd="2dp"
android:scaleType="fitXY"
android:src="@drawable/ic_widget_playback_speed" />
<ImageButton
android:id="@+id/butRew"
android:layout_width="36dp"

View File

@ -110,32 +110,35 @@
</style>
<style name="Theme.AntennaPod.Light.Translucent" parent="Theme.AntennaPod.Light.NoTitle">
<item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
<item name="android:windowLightStatusBar" tools:targetApi="M">false</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:windowAnimationStyle">@style/AnimationFade</item>
<item name="android:windowTranslucentStatus" tools:targetApi="kitkat">true</item>
<item name="android:fitsSystemWindows">true</item>
</style>
<style name="Theme.AntennaPod.Dark.Translucent" parent="Theme.AntennaPod.Dark.NoTitle">
<item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
<item name="android:windowLightStatusBar" tools:targetApi="M">false</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:windowAnimationStyle">@style/AnimationFade</item>
<item name="android:windowTranslucentStatus" tools:targetApi="kitkat">true</item>
<item name="android:fitsSystemWindows">true</item>
</style>
<style name="Theme.AntennaPod.TrueBlack.Translucent" parent="Theme.AntennaPod.TrueBlack">
<style name="Theme.AntennaPod.TrueBlack.Translucent" parent="Theme.AntennaPod.TrueBlack.NoTitle">
<item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
<item name="android:windowLightStatusBar" tools:targetApi="M">false</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:windowAnimationStyle">@style/AnimationFade</item>
<item name="android:windowTranslucentStatus" tools:targetApi="kitkat">true</item>
<item name="android:fitsSystemWindows">true</item>
</style>

View File

@ -0,0 +1,40 @@
package de.danoeh.antennapod.ui.appstartintent;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
/**
* Launches the playback speed dialog activity of the app with specific arguments.
* Does not require a dependency on the actual implementation of the activity.
*/
public class PlaybackSpeedActivityStarter {
public static final String INTENT = "de.danoeh.antennapod.intents.PLAYBACK_SPEED";
private final Intent intent;
private final Context context;
public PlaybackSpeedActivityStarter(Context context) {
this.context = context;
intent = new Intent(INTENT);
intent.setPackage(context.getPackageName());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
} else {
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
}
}
public Intent getIntent() {
return intent;
}
public PendingIntent getPendingIntent() {
return PendingIntent.getActivity(context, R.id.pending_intent_playback_speed, getIntent(),
PendingIntent.FLAG_UPDATE_CURRENT | (Build.VERSION.SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0));
}
public void start() {
context.startActivity(getIntent());
}
}

View File

@ -6,6 +6,7 @@
<item name="pending_intent_download_service_autodownload_report" type="id"/>
<item name="pending_intent_allow_stream_always" type="id"/>
<item name="pending_intent_allow_stream_this_time" type="id"/>
<item name="pending_intent_playback_speed" type="id"/>
<item name="pending_intent_player_activity" type="id"/>
<item name="pending_intent_video_player" type="id"/>
<item name="pending_intent_sync_error" type="id"/>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="48dp"
android:width="48dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:pivotX="12"
android:pivotY="12"
android:scaleX="0.8"
android:scaleY="0.8">
<path android:fillColor="#ffffff" android:pathData="M 12 15.98 A 2.98 2.98 0 0 1 9.02 12.99 c 0 -1.11 0.61 -2.09 1.49 -2.6 L 20.17 4.81 L 14.67 14.34 C 14.17 15.31 13.16 15.98 12 15.98 M 12 3.05 c 1.8 0 3.48 0.5 4.94 1.31 l -2.09 1.2 C 13.99 5.22 12.99 5.04 12 5.04 a 7.96 7.96 0 0 0 -7.96 7.96 c 0 2.2 0.89 4.19 2.33 5.62 h 0.01 c 0.39 0.39 0.39 1.01 0 1.4 c -0.39 0.39 -1.02 0.39 -1.41 0.01 v 0 C 3.17 18.22 2.05 15.74 2.05 12.99 A 9.95 9.95 0 0 1 12 3.05 m 9.95 9.95 c 0 2.75 -1.11 5.23 -2.91 7.03 v 0 c -0.39 0.38 -1.01 0.38 -1.4 -0.01 c -0.39 -0.39 -0.39 -1.01 0 -1.4 v 0 c 1.44 -1.44 2.33 -3.42 2.33 -5.62 c 0 -0.99 -0.19 -1.99 -0.54 -2.88 L 20.62 8.02 c 0.83 1.49 1.32 3.16 1.32 4.97 z" />
</group>
</vector>