diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 7d69defdd..0778a287d 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -61,6 +61,9 @@ + + + diff --git a/res/layout/player_widget.xml b/res/layout/player_widget.xml index 6e0f96ba4..fc26f2a9d 100644 --- a/res/layout/player_widget.xml +++ b/res/layout/player_widget.xml @@ -1,7 +1,9 @@ + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/white" + android:padding="@dimen/widget_margin" > - - + android:layout_margin="8dp" /> \ No newline at end of file diff --git a/res/values-v14/dimens.xml b/res/values-v14/dimens.xml new file mode 100644 index 000000000..090a476a8 --- /dev/null +++ b/res/values-v14/dimens.xml @@ -0,0 +1,5 @@ + + + 0dp + + \ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml new file mode 100644 index 000000000..e7c34ba70 --- /dev/null +++ b/res/values/dimens.xml @@ -0,0 +1,5 @@ + + + 8dp + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 0e3a4d0cb..0211f08a9 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -77,5 +77,6 @@ Move down Cancel all downloads Download cancelled + No media playing \ No newline at end of file diff --git a/src/de/podfetcher/receiver/MediaButtonReceiver.java b/src/de/podfetcher/receiver/MediaButtonReceiver.java index 8380c27d9..40defba10 100644 --- a/src/de/podfetcher/receiver/MediaButtonReceiver.java +++ b/src/de/podfetcher/receiver/MediaButtonReceiver.java @@ -15,6 +15,8 @@ public class MediaButtonReceiver extends BroadcastReceiver { private static final String TAG = "MediaButtonReceiver"; public static final String EXTRA_KEYCODE = "de.podfetcher.service.extra.MediaButtonReceiver.KEYCODE"; + public static final String NOTIFY_BUTTON_RECEIVER = "de.podfetcher.NOTIFY_BUTTON_RECEIVER"; + @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "Received intent"); diff --git a/src/de/podfetcher/receiver/PlayerWidget.java b/src/de/podfetcher/receiver/PlayerWidget.java index c05ae6099..85083734d 100644 --- a/src/de/podfetcher/receiver/PlayerWidget.java +++ b/src/de/podfetcher/receiver/PlayerWidget.java @@ -1,7 +1,42 @@ package de.podfetcher.receiver; +import de.podfetcher.service.PlayerWidgetService; +import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; +import android.content.Context; +import android.content.Intent; +import android.util.Log; public class PlayerWidget extends AppWidgetProvider { + private static final String TAG = "PlayerWidget"; + public static final String FORCE_WIDGET_UPDATE = "de.podfetcher.FORCE_WIDGET_UPDATE"; + + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(FORCE_WIDGET_UPDATE)) { + startUpdate(context); + } + + } + + + + @Override + public void onEnabled(Context context) { + super.onEnabled(context); + Log.d(TAG, "Widget enabled"); + } + + + + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, + int[] appWidgetIds) { + startUpdate(context); + } + + private void startUpdate(Context context) { + context.startService(new Intent(context, PlayerWidgetService.class)); + } } diff --git a/src/de/podfetcher/service/PlaybackService.java b/src/de/podfetcher/service/PlaybackService.java index 7d3561a3d..de8527fd0 100644 --- a/src/de/podfetcher/service/PlaybackService.java +++ b/src/de/podfetcher/service/PlaybackService.java @@ -1,10 +1,8 @@ package de.podfetcher.service; -import java.io.File; import java.io.IOException; import android.R; -import android.app.Notification; import android.app.PendingIntent; import android.app.Service; import android.content.ComponentName; @@ -16,22 +14,21 @@ import android.graphics.BitmapFactory; import android.media.AudioManager; import android.media.AudioManager.OnAudioFocusChangeListener; import android.media.MediaPlayer; +import android.os.AsyncTask; +import android.os.Binder; +import android.os.IBinder; import android.support.v4.app.NotificationCompat; import android.util.Log; import android.view.KeyEvent; import android.view.SurfaceHolder; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Binder; -import android.os.IBinder; - import de.podfetcher.PodcastApp; import de.podfetcher.activity.MediaplayerActivity; -import de.podfetcher.feed.FeedItem; -import de.podfetcher.feed.FeedMedia; import de.podfetcher.feed.Feed; +import de.podfetcher.feed.FeedItem; import de.podfetcher.feed.FeedManager; +import de.podfetcher.feed.FeedMedia; import de.podfetcher.receiver.MediaButtonReceiver; +import de.podfetcher.receiver.PlayerWidget; /** Controls the MediaPlayer that plays a FeedMedia-file */ public class PlaybackService extends Service { @@ -475,6 +472,7 @@ public class PlaybackService extends Service { Log.d(TAG, "Setting status to " + newStatus); status = newStatus; sendBroadcast(new Intent(ACTION_PLAYER_STATUS_CHANGED)); + sendBroadcast(new Intent(PlayerWidget.FORCE_WIDGET_UPDATE)); } private void sendNotificationBroadcast(int type, int code) { diff --git a/src/de/podfetcher/service/PlayerWidgetService.java b/src/de/podfetcher/service/PlayerWidgetService.java index 97efef9fa..23975c34e 100644 --- a/src/de/podfetcher/service/PlayerWidgetService.java +++ b/src/de/podfetcher/service/PlayerWidgetService.java @@ -1,16 +1,135 @@ package de.podfetcher.service; +import android.app.PendingIntent; import android.app.Service; +import android.appwidget.AppWidgetManager; +import android.content.ComponentName; import android.content.Intent; +import android.content.ServiceConnection; +import android.media.MediaPlayer; import android.os.IBinder; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.widget.RemoteViews; +import de.podfetcher.R; +import de.podfetcher.activity.MediaplayerActivity; +import de.podfetcher.feed.FeedMedia; +import de.podfetcher.receiver.MediaButtonReceiver; +import de.podfetcher.receiver.PlayerWidget; +import de.podfetcher.util.Converter; /** Updates the state of the player widget */ public class PlayerWidgetService extends Service { - public PlayerWidgetService() { - } + private static final String TAG = "PlayerWidgetService"; + + private PlaybackService playbackService; + /** True while service is updating the widget */ + private boolean isUpdating; + + public PlayerWidgetService() { + } + + @Override + public void onCreate() { + super.onCreate(); + Log.d(TAG, "Service created"); + isUpdating = false; + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + if (!isUpdating) { + isUpdating = true; + if (playbackService == null && PlaybackService.isRunning) { + bindService(new Intent(this, PlaybackService.class), + mConnection, 0); + } else { + updateViews(); + isUpdating = false; + } + } else { + Log.d(TAG, + "Service was called while updating. Ignoring update request"); + } + return Service.START_NOT_STICKY; + } + + private void updateViews() { + Log.d(TAG, "Updating widget views"); + 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, + new Intent(this, MediaplayerActivity.class), 0); + + views.setOnClickPendingIntent(R.id.layout_left, startMediaplayer); + if (playbackService != null) { + FeedMedia media = playbackService.getMedia(); + MediaPlayer player = playbackService.getPlayer(); + PlayerStatus status = playbackService.getStatus(); + + views.setTextViewText(R.id.txtvTitle, media.getItem().getTitle()); + + if (status == PlayerStatus.PLAYING) { + views.setTextViewText(R.id.txtvProgress, + getProgressString(player)); + views.setImageViewResource(R.id.butPlay, R.drawable.av_pause); + } else { + views.setImageViewResource(R.id.butPlay, R.drawable.av_play); + } + views.setOnClickPendingIntent(R.id.butPlay, + createMediaButtonIntent()); + } else { + Log.d(TAG, "No media playing. Displaying defaultt views"); + 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.av_play); + + } + + 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( + MediaButtonReceiver.NOTIFY_BUTTON_RECEIVER); + startingIntent.putExtra(Intent.EXTRA_KEY_EVENT, event); + + return PendingIntent.getBroadcast(this, 0, startingIntent, 0); + } + + private String getProgressString(MediaPlayer player) { + + return Converter.getDurationStringLong(player.getCurrentPosition()) + + " / " + Converter.getDurationStringLong(player.getDuration()); + } + + private ServiceConnection mConnection = new ServiceConnection() { + public void onServiceConnected(ComponentName className, IBinder service) { + Log.d(TAG, "Connection to service established"); + playbackService = ((PlaybackService.LocalBinder) service) + .getService(); + updateViews(); + isUpdating = false; + } + + @Override + public void onServiceDisconnected(ComponentName name) { + playbackService = null; + Log.d(TAG, "Disconnected from service"); + } + + }; - @Override - public IBinder onBind(Intent intent) { - return null; - } }