diff options
-rw-r--r-- | app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java | 20 | ||||
-rw-r--r-- | app/src/main/java/de/danoeh/antennapod/activity/WidgetConfigActivity.java | 4 | ||||
-rw-r--r-- | core/src/main/AndroidManifest.xml | 5 | ||||
-rw-r--r-- | core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java | 11 | ||||
-rw-r--r-- | core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java | 9 | ||||
-rw-r--r-- | core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java | 22 | ||||
-rw-r--r-- | core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java | 1 | ||||
-rw-r--r-- | core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdater.java (renamed from core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java) | 197 | ||||
-rw-r--r-- | core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdaterJobService.java | 32 |
9 files changed, 148 insertions, 153 deletions
diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java index f039c8bdf..ddd4fe899 100644 --- a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java +++ b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java @@ -6,6 +6,7 @@ import androidx.test.annotation.UiThreadTest; import androidx.test.filters.LargeTest; import de.danoeh.antennapod.core.preferences.SleepTimerPreferences; +import de.danoeh.antennapod.core.widget.WidgetUpdater; import org.awaitility.Awaitility; import org.greenrobot.eventbus.EventBus; import org.junit.After; @@ -187,8 +188,8 @@ public class PlaybackServiceTaskManagerTest { } @Override - public void onWidgetUpdaterTick() { - + public WidgetUpdater.WidgetState requestWidgetState() { + return null; } @Override @@ -248,8 +249,9 @@ public class PlaybackServiceTaskManagerTest { } @Override - public void onWidgetUpdaterTick() { + public WidgetUpdater.WidgetState requestWidgetState() { countDownLatch.countDown(); + return null; } @Override @@ -348,8 +350,8 @@ public class PlaybackServiceTaskManagerTest { } @Override - public void onWidgetUpdaterTick() { - + public WidgetUpdater.WidgetState requestWidgetState() { + return null; } @Override @@ -391,8 +393,8 @@ public class PlaybackServiceTaskManagerTest { } @Override - public void onWidgetUpdaterTick() { - + public WidgetUpdater.WidgetState requestWidgetState() { + return null; } @Override @@ -449,8 +451,8 @@ public class PlaybackServiceTaskManagerTest { } @Override - public void onWidgetUpdaterTick() { - + public WidgetUpdater.WidgetState requestWidgetState() { + return null; } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/activity/WidgetConfigActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/WidgetConfigActivity.java index 1b4e8b81e..3020aba43 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/WidgetConfigActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/WidgetConfigActivity.java @@ -19,7 +19,7 @@ import androidx.core.content.ContextCompat; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.receiver.PlayerWidget; -import de.danoeh.antennapod.core.service.PlayerWidgetJobService; +import de.danoeh.antennapod.core.widget.WidgetUpdaterJobService; public class WidgetConfigActivity extends AppCompatActivity { private int appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; @@ -127,7 +127,7 @@ public class WidgetConfigActivity extends AppCompatActivity { resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); setResult(RESULT_OK, resultValue); finish(); - PlayerWidgetJobService.updateWidget(this); + WidgetUpdaterJobService.performBackgroundUpdate(this); } private int getColorWithAlpha(int color, int opacity) { diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml index ae5e56e55..59267fa39 100644 --- a/core/src/main/AndroidManifest.xml +++ b/core/src/main/AndroidManifest.xml @@ -45,6 +45,11 @@ android:label="@string/feed_update_receiver_name" android:exported="true" tools:ignore="ExportedReceiver" /> <!-- allow feeds update to be triggered by external apps --> + + <service + android:name=".widget.WidgetUpdaterJobService" + android:permission="android.permission.BIND_JOB_SERVICE" + android:exported="true"/> </application> </manifest> diff --git a/core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java b/core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java index 9e9663205..cf0debed2 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java +++ b/core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java @@ -9,7 +9,7 @@ import android.util.Log; import java.util.Arrays; -import de.danoeh.antennapod.core.service.PlayerWidgetJobService; +import de.danoeh.antennapod.core.widget.WidgetUpdaterJobService; public class PlayerWidget extends AppWidgetProvider { private static final String TAG = "PlayerWidget"; @@ -25,7 +25,7 @@ public class PlayerWidget extends AppWidgetProvider { public void onReceive(Context context, Intent intent) { Log.d(TAG, "onReceive"); super.onReceive(context, intent); - PlayerWidgetJobService.updateWidget(context); + WidgetUpdaterJobService.performBackgroundUpdate(context); } @Override @@ -33,13 +33,14 @@ public class PlayerWidget extends AppWidgetProvider { super.onEnabled(context); Log.d(TAG, "Widget enabled"); setEnabled(context, true); - PlayerWidgetJobService.updateWidget(context); + WidgetUpdaterJobService.performBackgroundUpdate(context); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { - Log.d(TAG, "onUpdate() called with: " + "context = [" + context + "], appWidgetManager = [" + appWidgetManager + "], appWidgetIds = [" + Arrays.toString(appWidgetIds) + "]"); - PlayerWidgetJobService.updateWidget(context); + Log.d(TAG, "onUpdate() called with: " + "context = [" + context + "], appWidgetManager = [" + + appWidgetManager + "], appWidgetIds = [" + Arrays.toString(appWidgetIds) + "]"); + WidgetUpdaterJobService.performBackgroundUpdate(context); } @Override diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java index 495ac40c7..8f0697e24 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java @@ -69,7 +69,6 @@ import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.preferences.SleepTimerPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; -import de.danoeh.antennapod.core.service.PlayerWidgetJobService; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBWriter; @@ -81,6 +80,7 @@ import de.danoeh.antennapod.core.util.gui.NotificationUtils; import de.danoeh.antennapod.core.util.playback.ExternalMedia; import de.danoeh.antennapod.core.util.playback.Playable; import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter; +import de.danoeh.antennapod.core.widget.WidgetUpdater; import io.reactivex.Observable; import io.reactivex.Single; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -801,8 +801,9 @@ public class PlaybackService extends MediaBrowserServiceCompat { } @Override - public void onWidgetUpdaterTick() { - PlayerWidgetJobService.updateWidget(getBaseContext()); + public WidgetUpdater.WidgetState requestWidgetState() { + return new WidgetUpdater.WidgetState(getPlayable(), getStatus(), + getCurrentPosition(), getDuration(), getCurrentPlaybackSpeed()); } @Override @@ -873,9 +874,9 @@ public class PlaybackService extends MediaBrowserServiceCompat { } IntentUtils.sendLocalBroadcast(getApplicationContext(), ACTION_PLAYER_STATUS_CHANGED); - PlayerWidgetJobService.updateWidget(getBaseContext()); bluetoothNotifyChange(newInfo, AVRCP_ACTION_PLAYER_STATUS_CHANGED); bluetoothNotifyChange(newInfo, AVRCP_ACTION_META_CHANGED); + taskManager.requestWidgetUpdate(); } @Override diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java index 05d64ea3e..b9bc0c712 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java @@ -8,6 +8,7 @@ import androidx.annotation.NonNull; import android.util.Log; import de.danoeh.antennapod.core.preferences.SleepTimerPreferences; +import de.danoeh.antennapod.core.widget.WidgetUpdater; import io.reactivex.disposables.Disposable; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -199,11 +200,10 @@ public class PlaybackServiceTaskManager { */ public synchronized void startWidgetUpdater() { if (!isWidgetUpdaterActive() && !schedExecutor.isShutdown()) { - Runnable widgetUpdater = callback::onWidgetUpdaterTick; + Runnable widgetUpdater = this::requestWidgetUpdate; widgetUpdater = useMainThreadIfNecessary(widgetUpdater); - widgetUpdaterFuture = schedExecutor.scheduleWithFixedDelay(widgetUpdater, WIDGET_UPDATER_NOTIFICATION_INTERVAL, - WIDGET_UPDATER_NOTIFICATION_INTERVAL, TimeUnit.MILLISECONDS); - + widgetUpdaterFuture = schedExecutor.scheduleWithFixedDelay(widgetUpdater, + WIDGET_UPDATER_NOTIFICATION_INTERVAL, WIDGET_UPDATER_NOTIFICATION_INTERVAL, TimeUnit.MILLISECONDS); Log.d(TAG, "Started WidgetUpdater"); } else { Log.d(TAG, "Call to startWidgetUpdater was ignored."); @@ -211,6 +211,18 @@ public class PlaybackServiceTaskManager { } /** + * Retrieves information about the widget state in the calling thread and then displays it in a background thread. + */ + public synchronized void requestWidgetUpdate() { + WidgetUpdater.WidgetState state = callback.requestWidgetState(); + if (!schedExecutor.isShutdown()) { + schedExecutor.execute(() -> WidgetUpdater.updateWidget(context, state)); + } else { + Log.d(TAG, "Call to requestWidgetUpdate was ignored."); + } + } + + /** * Starts a new sleep timer with the given waiting time. If another sleep timer is already active, it will be * cancelled first. * After waitingTime has elapsed, onSleepTimerExpired() will be called. @@ -464,7 +476,7 @@ public class PlaybackServiceTaskManager { void onSleepTimerReset(); - void onWidgetUpdaterTick(); + WidgetUpdater.WidgetState requestWidgetState(); void onChapterLoaded(Playable media); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java index 59abdd10a..e2ce86ceb 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java @@ -21,6 +21,7 @@ import java.util.List; */ public interface Playable extends Parcelable, ShownotesProvider, ImageResource { + public static final int INVALID_TIME = -1; /** * Save information about the playable in a preference so that it can be diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java b/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdater.java index 2ed887fbb..1622fcb8f 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdater.java @@ -1,17 +1,13 @@ -package de.danoeh.antennapod.core.service; +package de.danoeh.antennapod.core.widget; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.ServiceConnection; import android.content.SharedPreferences; import android.graphics.Bitmap; import android.os.Bundle; -import android.os.IBinder; -import androidx.annotation.NonNull; -import androidx.core.app.SafeJobIntentService; import android.util.Log; import android.view.KeyEvent; import android.view.View; @@ -24,7 +20,6 @@ import java.util.concurrent.TimeUnit; import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.glide.ApGlideSettings; -import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils; import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; import de.danoeh.antennapod.core.receiver.PlayerWidget; import de.danoeh.antennapod.core.service.playback.PlaybackService; @@ -35,107 +30,65 @@ import de.danoeh.antennapod.core.util.TimeSpeedConverter; import de.danoeh.antennapod.core.util.playback.Playable; /** - * Updates the state of the player widget + * Updates the state of the player widget. */ -public class PlayerWidgetJobService extends SafeJobIntentService { - - private static final String TAG = "PlayerWidgetJobService"; - - private PlaybackService playbackService; - private final Object waitForService = new Object(); - private final Object waitUsingService = new Object(); - - private static final int JOB_ID = -17001; - - public static void updateWidget(Context context) { - enqueueWork(context, PlayerWidgetJobService.class, JOB_ID, new Intent(context, PlayerWidgetJobService.class)); - } - - @Override - protected void onHandleWork(@NonNull Intent intent) { - if (!PlayerWidget.isEnabled(getApplicationContext())) { - return; +public abstract class WidgetUpdater { + private static final String TAG = "WidgetUpdater"; + + public static class WidgetState { + final Playable media; + final PlayerStatus status; + final int position; + final int duration; + final float playbackSpeed; + + public WidgetState(Playable media, PlayerStatus status, int position, int duration, float playbackSpeed) { + this.media = media; + this.status = status; + this.position = position; + this.duration = duration; + this.playbackSpeed = playbackSpeed; } - synchronized (waitForService) { - if (PlaybackService.isRunning && playbackService == null) { - bindService(new Intent(this, PlaybackService.class), mConnection, 0); - while (playbackService == null) { - try { - waitForService.wait(); - } catch (InterruptedException e) { - return; - } - } - } - } - - synchronized (waitUsingService) { - updateViews(); - } - - if (playbackService != null) { - try { - unbindService(mConnection); - } catch (IllegalArgumentException e) { - Log.w(TAG, "IllegalArgumentException when trying to unbind service"); - } + public WidgetState(PlayerStatus status) { + this(null, status, Playable.INVALID_TIME, Playable.INVALID_TIME, 1.0f); } } /** - * Returns number of cells needed for given size of the widget. - * - * @param size Widget size in dp. - * @return Size in number of cells. + * Update the widgets with the given parameters. Must be called in a background thread. */ - private static int getCellsForSize(int size) { - int n = 2; - while (70 * n - 30 < size) { - ++n; + public static void updateWidget(Context context, WidgetState widgetState) { + if (!PlayerWidget.isEnabled(context) || widgetState == null) { + return; } - return n - 1; - } - - private void updateViews() { - - ComponentName playerWidget = new ComponentName(this, PlayerWidget.class); - AppWidgetManager manager = AppWidgetManager.getInstance(this); + ComponentName playerWidget = new ComponentName(context, PlayerWidget.class); + AppWidgetManager manager = AppWidgetManager.getInstance(context); int[] widgetIds = manager.getAppWidgetIds(playerWidget); - final PendingIntent startMediaPlayer = PendingIntent.getActivity(this, R.id.pending_intent_player_activity, - PlaybackService.getPlayerActivityIntent(this), PendingIntent.FLAG_UPDATE_CURRENT); + final PendingIntent startMediaPlayer = PendingIntent.getActivity(context, R.id.pending_intent_player_activity, + PlaybackService.getPlayerActivityIntent(context), PendingIntent.FLAG_UPDATE_CURRENT); RemoteViews views; - views = new RemoteViews(getPackageName(), R.layout.player_widget); + views = new RemoteViews(context.getPackageName(), R.layout.player_widget); - Playable media; - PlayerStatus status; - if (playbackService != null) { - media = playbackService.getPlayable(); - status = playbackService.getStatus(); - } else { - media = Playable.PlayableUtils.createInstanceFromPreferences(getApplicationContext()); - status = PlayerStatus.STOPPED; - } - - if (media != null) { + if (widgetState.media != null) { Bitmap icon; - int iconSize = getResources().getDimensionPixelSize(android.R.dimen.app_icon_size); + int iconSize = context.getResources().getDimensionPixelSize(android.R.dimen.app_icon_size); views.setOnClickPendingIntent(R.id.layout_left, startMediaPlayer); views.setOnClickPendingIntent(R.id.imgvCover, startMediaPlayer); try { - icon = Glide.with(PlayerWidgetJobService.this) + icon = Glide.with(context) .asBitmap() - .load(ImageResourceUtils.getImageLocation(media)) + .load(ImageResourceUtils.getImageLocation(widgetState.media)) .apply(RequestOptions.diskCacheStrategyOf(ApGlideSettings.AP_DISK_CACHE_STRATEGY)) .submit(iconSize, iconSize) .get(500, TimeUnit.MILLISECONDS); views.setImageViewBitmap(R.id.imgvCover, icon); } catch (Throwable tr1) { try { - icon = Glide.with(PlayerWidgetJobService.this) + icon = Glide.with(context) .asBitmap() - .load(ImageResourceUtils.getFallbackImageLocation(media)) + .load(ImageResourceUtils.getFallbackImageLocation(widgetState.media)) .apply(RequestOptions.diskCacheStrategyOf(ApGlideSettings.AP_DISK_CACHE_STRATEGY)) .submit(iconSize, iconSize) .get(500, TimeUnit.MILLISECONDS); @@ -146,50 +99,44 @@ public class PlayerWidgetJobService extends SafeJobIntentService { } } - views.setTextViewText(R.id.txtvTitle, media.getEpisodeTitle()); + views.setTextViewText(R.id.txtvTitle, widgetState.media.getEpisodeTitle()); views.setViewVisibility(R.id.txtvTitle, View.VISIBLE); views.setViewVisibility(R.id.txtNoPlaying, View.GONE); - String progressString; - if (playbackService != null) { - progressString = getProgressString(playbackService.getCurrentPosition(), - playbackService.getDuration(), playbackService.getCurrentPlaybackSpeed()); - } else { - progressString = getProgressString(media.getPosition(), media.getDuration(), PlaybackSpeedUtils.getCurrentPlaybackSpeed(media)); - } - + String progressString = getProgressString(widgetState.position, + widgetState.duration, widgetState.playbackSpeed); if (progressString != null) { views.setViewVisibility(R.id.txtvProgress, View.VISIBLE); views.setTextViewText(R.id.txtvProgress, progressString); } - if (status == PlayerStatus.PLAYING) { + if (widgetState.status == PlayerStatus.PLAYING) { views.setImageViewResource(R.id.butPlay, R.drawable.ic_av_pause_white_48dp); - views.setContentDescription(R.id.butPlay, getString(R.string.pause_label)); + views.setContentDescription(R.id.butPlay, context.getString(R.string.pause_label)); views.setImageViewResource(R.id.butPlayExtended, R.drawable.ic_av_pause_white_48dp); - views.setContentDescription(R.id.butPlayExtended, getString(R.string.pause_label)); + views.setContentDescription(R.id.butPlayExtended, context.getString(R.string.pause_label)); } else { views.setImageViewResource(R.id.butPlay, R.drawable.ic_av_play_white_48dp); - views.setContentDescription(R.id.butPlay, getString(R.string.play_label)); + views.setContentDescription(R.id.butPlay, context.getString(R.string.play_label)); views.setImageViewResource(R.id.butPlayExtended, R.drawable.ic_av_play_white_48dp); - views.setContentDescription(R.id.butPlayExtended, getString(R.string.play_label)); + views.setContentDescription(R.id.butPlayExtended, context.getString(R.string.play_label)); } views.setOnClickPendingIntent(R.id.butPlay, - createMediaButtonIntent(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); + createMediaButtonIntent(context, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); views.setOnClickPendingIntent(R.id.butPlayExtended, - createMediaButtonIntent(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); + createMediaButtonIntent(context, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); views.setOnClickPendingIntent(R.id.butRew, - createMediaButtonIntent(KeyEvent.KEYCODE_MEDIA_REWIND)); + createMediaButtonIntent(context, KeyEvent.KEYCODE_MEDIA_REWIND)); views.setOnClickPendingIntent(R.id.butFastForward, - createMediaButtonIntent(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD)); + createMediaButtonIntent(context, KeyEvent.KEYCODE_MEDIA_FAST_FORWARD)); views.setOnClickPendingIntent(R.id.butSkip, - createMediaButtonIntent(KeyEvent.KEYCODE_MEDIA_NEXT)); + createMediaButtonIntent(context, KeyEvent.KEYCODE_MEDIA_NEXT)); } else { // start the app if they click anything views.setOnClickPendingIntent(R.id.layout_left, startMediaPlayer); views.setOnClickPendingIntent(R.id.butPlay, startMediaPlayer); views.setOnClickPendingIntent(R.id.butPlayExtended, - createMediaButtonIntent(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); + createMediaButtonIntent(context, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); views.setViewVisibility(R.id.txtvProgress, View.GONE); views.setViewVisibility(R.id.txtvTitle, View.GONE); views.setViewVisibility(R.id.txtNoPlaying, View.VISIBLE); @@ -201,7 +148,7 @@ public class PlayerWidgetJobService extends SafeJobIntentService { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { for (int id : widgetIds) { Bundle options = manager.getAppWidgetOptions(id); - SharedPreferences prefs = getSharedPreferences(PlayerWidget.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = context.getSharedPreferences(PlayerWidget.PREFS_NAME, Context.MODE_PRIVATE); int minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH); int columns = getCellsForSize(minWidth); if (columns < 3) { @@ -232,18 +179,32 @@ public class PlayerWidgetJobService extends SafeJobIntentService { } /** - * Creates an intent which fakes a mediabutton press + * Returns number of cells needed for given size of the widget. + * + * @param size Widget size in dp. + * @return Size in number of cells. */ - private PendingIntent createMediaButtonIntent(int eventCode) { + private static int getCellsForSize(int size) { + int n = 2; + while (70 * n - 30 < size) { + ++n; + } + return n - 1; + } + + /** + * Creates an intent which fakes a mediabutton press. + */ + private static PendingIntent createMediaButtonIntent(Context context, int eventCode) { KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, eventCode); - Intent startingIntent = new Intent(getBaseContext(), MediaButtonReceiver.class); + Intent startingIntent = new Intent(context, MediaButtonReceiver.class); startingIntent.setAction(MediaButtonReceiver.NOTIFY_BUTTON_RECEIVER); startingIntent.putExtra(Intent.EXTRA_KEY_EVENT, event); - return PendingIntent.getBroadcast(this, eventCode, startingIntent, 0); + return PendingIntent.getBroadcast(context, eventCode, startingIntent, 0); } - private String getProgressString(int position, int duration, float speed) { + private static String getProgressString(int position, int duration, float speed) { if (position >= 0 && duration > 0) { TimeSpeedConverter converter = new TimeSpeedConverter(speed); position = converter.convert(position); @@ -254,24 +215,4 @@ public class PlayerWidgetJobService extends SafeJobIntentService { return null; } } - - private final ServiceConnection mConnection = new ServiceConnection() { - public void onServiceConnected(ComponentName className, IBinder service) { - Log.d(TAG, "Connection to service established"); - if (service instanceof PlaybackService.LocalBinder) { - synchronized (waitForService) { - playbackService = ((PlaybackService.LocalBinder) service).getService(); - waitForService.notifyAll(); - } - } - } - - @Override - public void onServiceDisconnected(ComponentName name) { - synchronized (waitUsingService) { - playbackService = null; - } - Log.d(TAG, "Disconnected from service"); - } - }; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdaterJobService.java b/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdaterJobService.java new file mode 100644 index 000000000..1db7928b4 --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdaterJobService.java @@ -0,0 +1,32 @@ +package de.danoeh.antennapod.core.widget; + +import android.content.Context; +import android.content.Intent; +import androidx.annotation.NonNull; +import androidx.core.app.SafeJobIntentService; +import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils; +import de.danoeh.antennapod.core.service.playback.PlayerStatus; +import de.danoeh.antennapod.core.util.playback.Playable; + +public class WidgetUpdaterJobService extends SafeJobIntentService { + private static final int JOB_ID = -17001; + + /** + * Loads the current media from the database and updates the widget in a background job. + */ + public static void performBackgroundUpdate(Context context) { + enqueueWork(context, WidgetUpdaterJobService.class, + WidgetUpdaterJobService.JOB_ID, new Intent(context, WidgetUpdaterJobService.class)); + } + + @Override + protected void onHandleWork(@NonNull Intent intent) { + Playable media = Playable.PlayableUtils.createInstanceFromPreferences(getApplicationContext()); + if (media != null) { + WidgetUpdater.updateWidget(this, new WidgetUpdater.WidgetState(media, PlayerStatus.STOPPED, + media.getPosition(), media.getDuration(), PlaybackSpeedUtils.getCurrentPlaybackSpeed(media))); + } else { + WidgetUpdater.updateWidget(this, new WidgetUpdater.WidgetState(PlayerStatus.STOPPED)); + } + } +}
\ No newline at end of file |