summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorByteHamster <info@bytehamster.com>2018-05-05 14:04:12 +0200
committerByteHamster <info@bytehamster.com>2018-05-05 14:04:12 +0200
commit7107819a6aa61c6f171e43fe582133302d5f260b (patch)
treee93278e731e5eebf326ccdc9993398242ab7d726 /core
parent0b54d97a0a9a2caeb51c85a68749df9afe0dbdb3 (diff)
downloadAntennaPod-7107819a6aa61c6f171e43fe582133302d5f260b.zip
Moved widget from app to core
Diffstat (limited to 'core')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java56
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java179
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java5
-rw-r--r--core/src/main/res/layout/player_widget.xml52
4 files changed, 290 insertions, 2 deletions
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
new file mode 100644
index 000000000..edc2ea3e0
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java
@@ -0,0 +1,56 @@
+package de.danoeh.antennapod.core.receiver;
+
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProvider;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.util.Log;
+import de.danoeh.antennapod.core.service.PlayerWidgetJobService;
+
+import java.util.Arrays;
+
+
+public class PlayerWidget extends AppWidgetProvider {
+ private static final String TAG = "PlayerWidget";
+ private static final String PREFS_NAME = "PlayerWidgetPrefs";
+ private static final String KEY_ENABLED = "WidgetEnabled";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d(TAG, "onReceive");
+ super.onReceive(context, intent);
+ PlayerWidgetJobService.updateWidget(context);
+ }
+
+ @Override
+ public void onEnabled(Context context) {
+ super.onEnabled(context);
+ Log.d(TAG, "Widget enabled");
+ setEnabled(context, true);
+ PlayerWidgetJobService.updateWidget(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);
+ }
+
+ @Override
+ public void onDisabled(Context context) {
+ super.onDisabled(context);
+ Log.d(TAG, "Widget disabled");
+ setEnabled(context, false);
+ }
+
+ public static boolean isEnabled(Context context) {
+ SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
+ return prefs.getBoolean(KEY_ENABLED, false);
+ }
+
+ private void setEnabled(Context context, boolean enabled) {
+ SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
+ prefs.edit().putBoolean(KEY_ENABLED, enabled).apply();
+ }
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java b/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java
new file mode 100644
index 000000000..49f3058ef
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java
@@ -0,0 +1,179 @@
+package de.danoeh.antennapod.core.service;
+
+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.os.Build;
+import android.os.IBinder;
+import android.support.annotation.NonNull;
+import android.support.v4.app.JobIntentService;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.RemoteViews;
+import de.danoeh.antennapod.core.R;
+import de.danoeh.antennapod.core.receiver.MediaButtonReceiver;
+import de.danoeh.antennapod.core.service.playback.PlaybackService;
+import de.danoeh.antennapod.core.service.playback.PlayerStatus;
+import de.danoeh.antennapod.core.util.Converter;
+import de.danoeh.antennapod.core.util.playback.Playable;
+import de.danoeh.antennapod.core.receiver.PlayerWidget;
+
+/**
+ * Updates the state of the player widget
+ */
+public class PlayerWidgetJobService extends JobIntentService {
+ private static final String TAG = "PlayerWidgetJobService";
+
+ private PlaybackService playbackService;
+ private final Object waitForService = new Object();
+
+ public PlayerWidgetJobService() {
+ }
+
+ public static void updateWidget(Context context) {
+ enqueueWork(context, PlayerWidgetJobService.class, 0, new Intent(context, PlayerWidgetJobService.class));
+ }
+
+ @Override
+ protected void onHandleWork(@NonNull Intent intent) {
+ if (!PlayerWidget.isEnabled(getApplicationContext())) {
+ return;
+ }
+
+ if (PlaybackService.isRunning && playbackService == null) {
+ synchronized (waitForService) {
+ bindService(new Intent(this, PlaybackService.class), mConnection, 0);
+ while (playbackService == null) {
+ try {
+ waitForService.wait();
+ } catch (InterruptedException e) {
+ return;
+ }
+ }
+ }
+ }
+
+ updateViews();
+
+ if (playbackService != null) {
+ try {
+ unbindService(mConnection);
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "IllegalArgumentException when trying to unbind service");
+ }
+ }
+ }
+
+ private void updateViews() {
+
+ ComponentName playerWidget = new ComponentName(this, PlayerWidget.class);
+ AppWidgetManager manager = AppWidgetManager.getInstance(this);
+ RemoteViews views = new RemoteViews(getPackageName(), R.layout.player_widget);
+ PendingIntent startMediaplayer = PendingIntent.getActivity(this, 0,
+ PlaybackService.getPlayerActivityIntent(this), 0);
+
+ final PendingIntent startAppPending = PendingIntent.getActivity(this, 0,
+ PlaybackService.getPlayerActivityIntent(this),
+ PendingIntent.FLAG_UPDATE_CURRENT);
+
+ boolean nothingPlaying = false;
+ 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) {
+ views.setOnClickPendingIntent(R.id.layout_left, startMediaplayer);
+
+ views.setTextViewText(R.id.txtvTitle, media.getEpisodeTitle());
+
+ String progressString;
+ if (playbackService != null) {
+ progressString = getProgressString(playbackService.getCurrentPosition(), playbackService.getDuration());
+ } else {
+ progressString = getProgressString(media.getPosition(), media.getDuration());
+ }
+
+ if (progressString != null) {
+ views.setViewVisibility(R.id.txtvProgress, View.VISIBLE);
+ views.setTextViewText(R.id.txtvProgress, progressString);
+ }
+
+ if (status == PlayerStatus.PLAYING) {
+ views.setImageViewResource(R.id.butPlay, R.drawable.ic_pause_white_24dp);
+ if (Build.VERSION.SDK_INT >= 15) {
+ views.setContentDescription(R.id.butPlay, getString(R.string.pause_label));
+ }
+ } else {
+ views.setImageViewResource(R.id.butPlay, R.drawable.ic_play_arrow_white_24dp);
+ if (Build.VERSION.SDK_INT >= 15) {
+ views.setContentDescription(R.id.butPlay, getString(R.string.play_label));
+ }
+ }
+ views.setOnClickPendingIntent(R.id.butPlay, createMediaButtonIntent());
+ } else {
+ nothingPlaying = true;
+ }
+
+ if (nothingPlaying) {
+ // start the app if they click anything
+ views.setOnClickPendingIntent(R.id.layout_left, startAppPending);
+ views.setOnClickPendingIntent(R.id.butPlay, startAppPending);
+ views.setViewVisibility(R.id.txtvProgress, View.INVISIBLE);
+ views.setTextViewText(R.id.txtvTitle,
+ this.getString(R.string.no_media_playing_label));
+ views.setImageViewResource(R.id.butPlay, R.drawable.ic_play_arrow_white_24dp);
+ }
+
+ manager.updateAppWidget(playerWidget, views);
+ }
+
+ /**
+ * Creates an intent which fakes a mediabutton press
+ */
+ private PendingIntent createMediaButtonIntent() {
+ KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
+ Intent startingIntent = new Intent(getBaseContext(), MediaButtonReceiver.class);
+ startingIntent.setAction(MediaButtonReceiver.NOTIFY_BUTTON_RECEIVER);
+ startingIntent.putExtra(Intent.EXTRA_KEY_EVENT, event);
+
+ return PendingIntent.getBroadcast(this, 0, startingIntent, 0);
+ }
+
+ private String getProgressString(int position, int duration) {
+ if (position > 0 && duration > 0) {
+ return Converter.getDurationStringLong(position) + " / "
+ + Converter.getDurationStringLong(duration);
+ } else {
+ 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) {
+ playbackService = null;
+ Log.d(TAG, "Disconnected from service");
+ }
+
+ };
+}
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 a34ce4943..9643b9cd3 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
@@ -62,6 +62,7 @@ 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;
@@ -630,7 +631,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
@Override
public void onWidgetUpdaterTick() {
- //PlayerWidgetJobService.updateWidget(getBaseContext()); // TODO: Not accessible from core module
+ PlayerWidgetJobService.updateWidget(getBaseContext());
}
@Override
@@ -692,7 +693,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
Intent statusUpdate = new Intent(ACTION_PLAYER_STATUS_CHANGED);
// statusUpdate.putExtra(EXTRA_NEW_PLAYER_STATUS, newInfo.playerStatus.ordinal());
sendBroadcast(statusUpdate);
- //PlayerWidgetJobService.updateWidget(getBaseContext()); // TODO: Not accessible from core module
+ PlayerWidgetJobService.updateWidget(getBaseContext());
bluetoothNotifyChange(newInfo, AVRCP_ACTION_PLAYER_STATUS_CHANGED);
bluetoothNotifyChange(newInfo, AVRCP_ACTION_META_CHANGED);
}
diff --git a/core/src/main/res/layout/player_widget.xml b/core/src/main/res/layout/player_widget.xml
new file mode 100644
index 000000000..4c98895a0
--- /dev/null
+++ b/core/src/main/res/layout/player_widget.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="@dimen/widget_margin" >
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#262C31" >
+
+ <ImageButton
+ android:id="@+id/butPlay"
+ android:contentDescription="@string/play_label"
+ android:layout_width="56dp"
+ android:layout_height="match_parent"
+ android:layout_alignParentRight="true"
+ android:layout_margin="12dp"
+ android:background="@drawable/borderless_button_dark"
+ android:src="@drawable/ic_play_arrow_white_24dp" />
+
+ <LinearLayout
+ android:id="@+id/layout_left"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_alignParentLeft="true"
+ android:layout_toLeftOf="@id/butPlay"
+ android:background="@drawable/borderless_button_dark"
+ android:gravity="center_vertical"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/txtvTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="8dp"
+ android:maxLines="1"
+ android:text="@string/no_media_playing_label"
+ android:textColor="@color/white"
+ android:textSize="@dimen/text_size_medium"
+ android:textStyle="bold" />
+
+ <TextView
+ android:id="@+id/txtvProgress"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="8dp"
+ android:textColor="@color/white" />
+ </LinearLayout>
+ </RelativeLayout>
+
+</FrameLayout> \ No newline at end of file