Implemented PlayerWidgetService

This commit is contained in:
daniel oeh 2012-07-07 15:05:35 +02:00
parent 897516aa88
commit e498216378
9 changed files with 190 additions and 30 deletions

View File

@ -61,6 +61,9 @@
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
<intent-filter>
<action android:name="de.podfetcher.NOTIFY_BUTTON_RECEIVER"/>
</intent-filter>
</receiver>
<activity android:name=".activity.FeedInfoActivity" >

View File

@ -1,7 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="294dp"
android:layout_height="74dp" >
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:padding="@dimen/widget_margin" >
<ImageButton
android:id="@+id/butPlay"
@ -12,37 +14,27 @@
android:background="@drawable/borderless_button"
android:src="@drawable/av_play" />
<View
android:id="@+id/divider"
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:layout_toLeftOf="@id/butPlay"
android:background="@color/gray" />
<LinearLayout
android:id="@+id/layout_left"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@id/divider"
android:layout_toLeftOf="@id/butPlay"
android:orientation="vertical" >
<TextView
android:id="@+id/txtvTitle"
android:textColor="@color/black"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="Test Titel"
android:textStyle="bold" />
<TextView
android:id="@+id/txtvProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="Test progress" />
android:layout_margin="8dp" />
</LinearLayout>
</RelativeLayout>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="widget_margin">0dp</dimen>
</resources>

5
res/values/dimens.xml Normal file
View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="widget_margin">8dp</dimen>
</resources>

View File

@ -77,5 +77,6 @@
<string name="move_down_label">Move down</string>
<string name="cancel_all_downloads_label">Cancel all downloads</string>
<string name="download_cancelled_msg">Download cancelled</string>
<string name="no_media_playing_label">No media playing</string>
</resources>

View File

@ -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");

View File

@ -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));
}
}

View File

@ -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) {

View File

@ -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;
}
}