summaryrefslogtreecommitdiff
path: root/src/de/podfetcher
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/podfetcher')
-rw-r--r--src/de/podfetcher/PodcastApp.java2
-rw-r--r--src/de/podfetcher/activity/ItemviewActivity.java2
-rw-r--r--src/de/podfetcher/activity/MediaplayerActivity.java211
-rw-r--r--src/de/podfetcher/feed/FeedManager.java55
-rw-r--r--src/de/podfetcher/service/PlaybackService.java169
-rw-r--r--src/de/podfetcher/syndication/util/FeedItemMenuHandler.java5
6 files changed, 302 insertions, 142 deletions
diff --git a/src/de/podfetcher/PodcastApp.java b/src/de/podfetcher/PodcastApp.java
index ba9e07884..9d53fc7ca 100644
--- a/src/de/podfetcher/PodcastApp.java
+++ b/src/de/podfetcher/PodcastApp.java
@@ -6,6 +6,8 @@ import android.app.Application;
public class PodcastApp extends Application {
private static final String TAG = "PodcastApp";
+ public static final String PREF_NAME = "PodfetcherPrefs";
+
private static PodcastApp singleton;
diff --git a/src/de/podfetcher/activity/ItemviewActivity.java b/src/de/podfetcher/activity/ItemviewActivity.java
index dd6bb05b4..d6cb41b9a 100644
--- a/src/de/podfetcher/activity/ItemviewActivity.java
+++ b/src/de/podfetcher/activity/ItemviewActivity.java
@@ -66,7 +66,7 @@ public class ItemviewActivity extends SherlockActivity {
butPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- manager.playMedia(v.getContext(), item.getMedia());
+ //manager.playMedia(v.getContext(), item.getMedia());
}
});
diff --git a/src/de/podfetcher/activity/MediaplayerActivity.java b/src/de/podfetcher/activity/MediaplayerActivity.java
index 24dc29acc..f5aaab455 100644
--- a/src/de/podfetcher/activity/MediaplayerActivity.java
+++ b/src/de/podfetcher/activity/MediaplayerActivity.java
@@ -6,6 +6,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
+import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -22,7 +23,9 @@ import android.widget.TextView;
import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.Menu;
+import de.podfetcher.PodcastApp;
import de.podfetcher.R;
+import de.podfetcher.feed.FeedManager;
import de.podfetcher.feed.FeedMedia;
import de.podfetcher.service.PlaybackService;
import de.podfetcher.service.PlayerStatus;
@@ -30,16 +33,18 @@ import de.podfetcher.util.Converter;
public class MediaplayerActivity extends SherlockActivity {
private final String TAG = "MediaplayerActivity";
-
- private static final int DEFAULT_SEEK_DELTA = 30000; // Seek-Delta to use when using FF or Rev Buttons
-
+
+ private static final int DEFAULT_SEEK_DELTA = 30000; // Seek-Delta to use
+ // when using FF or
+ // Rev Buttons
+
private PlaybackService playbackService;
private MediaPositionObserver positionObserver;
-
+
private FeedMedia media;
private PlayerStatus status;
-
-
+ private FeedManager manager;
+
// Widgets
private ImageView imgvCover;
private TextView txtvStatus;
@@ -49,7 +54,7 @@ public class MediaplayerActivity extends SherlockActivity {
private ImageButton butPlay;
private ImageButton butRev;
private ImageButton butFF;
-
+
@Override
protected void onStop() {
super.onStop();
@@ -66,15 +71,13 @@ public class MediaplayerActivity extends SherlockActivity {
// TODO Auto-generated method stub
return super.onCreateOptionsMenu(menu);
}
-
-
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "Resuming Activity");
bindToService();
- registerReceiver(statusUpdate, new IntentFilter(PlaybackService.ACTION_PLAYER_STATUS_CHANGED));
+
}
@Override
@@ -82,22 +85,47 @@ public class MediaplayerActivity extends SherlockActivity {
super.onCreate(savedInstanceState);
Log.d(TAG, "Creating Activity");
this.setContentView(R.layout.mediaplayer_activity);
-
+ manager = FeedManager.getInstance();
setupGUI();
bindToService();
- registerReceiver(statusUpdate, new IntentFilter(PlaybackService.ACTION_PLAYER_STATUS_CHANGED));
}
-
+
private void bindToService() {
- if(!bindService(new Intent(this, PlaybackService.class), mConnection, 0)) {
- status = PlayerStatus.STOPPED;
- handleStatus();
+ Intent serviceIntent = new Intent(this, PlaybackService.class);
+ boolean bound = false;
+ if (!PlaybackService.isRunning) {
+ Log.d(TAG, "Trying to restore last played media");
+ SharedPreferences prefs = getApplicationContext()
+ .getSharedPreferences(PodcastApp.PREF_NAME, 0);
+ long mediaId = prefs.getLong(PlaybackService.PREF_LAST_PLAYED_ID,
+ -1);
+ long feedId = prefs.getLong(
+ PlaybackService.PREF_LAST_PLAYED_FEED_ID, -1);
+ if (mediaId != -1 && feedId != -1) {
+ serviceIntent.putExtra(PlaybackService.EXTRA_FEED_ID, feedId);
+ serviceIntent.putExtra(PlaybackService.EXTRA_MEDIA_ID, mediaId);
+ serviceIntent.putExtra(
+ PlaybackService.EXTRA_START_WHEN_PREPARED, false);
+ serviceIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM,
+ prefs.getBoolean(PlaybackService.PREF_LAST_IS_STREAM,
+ true));
+ startService(serviceIntent);
+ bound = bindService(serviceIntent, mConnection,
+ Context.BIND_AUTO_CREATE);
+ } else {
+ Log.d(TAG, "No last played media found");
+ status = PlayerStatus.STOPPED;
+ handleStatus();
+ }
+ } else {
+ bound = bindService(serviceIntent, mConnection, 0);
}
+ Log.d(TAG, "Result for service binding: " + bound);
}
-
+
private void handleStatus() {
switch (status) {
-
+
case ERROR:
setStatusMsg(R.string.player_error_msg, View.VISIBLE);
handleError();
@@ -120,51 +148,73 @@ public class MediaplayerActivity extends SherlockActivity {
case PREPARING:
setStatusMsg(R.string.player_preparing_msg, View.VISIBLE);
break;
+ case STOPPED:
+ setStatusMsg(R.string.player_stopped_msg, View.VISIBLE);
+ imgvCover.setImageBitmap(null);
+ break;
+ case PREPARED:
+ loadMediaInfo();
+ setStatusMsg(R.string.player_ready_msg, View.VISIBLE);
+ butPlay.setImageResource(android.R.drawable.ic_media_play);
}
}
-
+
private void setStatusMsg(int resId, int visibility) {
- if(visibility == View.VISIBLE) {
+ if (visibility == View.VISIBLE) {
txtvStatus.setText(resId);
}
txtvStatus.setVisibility(visibility);
}
-
+
private void setupPositionObserver() {
- if (positionObserver == null) {
+ if (positionObserver == null || positionObserver.isCancelled()) {
positionObserver = new MediaPositionObserver() {
@Override
- protected void onProgressUpdate(Integer... values) {
- super.onProgressUpdate(values);
- txtvPosition.setText(
- Converter.getDurationStringLong(values[0]));
-
- float progress = ((float) values[0]) / getDuration();
- sbPosition.setProgress((int) (progress * 100));
+ protected void onProgressUpdate(Void... v) {
+ super.onProgressUpdate();
+ txtvPosition.setText(Converter
+ .getDurationStringLong(playbackService.getPlayer()
+ .getCurrentPosition()));
+
+ updateProgressbarPosition();
}
-
+
};
positionObserver.execute(playbackService.getPlayer());
}
}
-
+
+ private void updateProgressbarPosition() {
+ MediaPlayer player = playbackService.getPlayer();
+ float progress = ((float) player.getCurrentPosition())
+ / player.getDuration();
+ sbPosition.setProgress((int) (progress * sbPosition.getMax()));
+ }
+
private void loadMediaInfo() {
if (media != null) {
MediaPlayer player = playbackService.getPlayer();
-
+
getSupportActionBar().setSubtitle(media.getItem().getTitle());
- getSupportActionBar().setTitle(
- media.getItem().getFeed().getTitle());
-
- imgvCover.setImageBitmap(
- media.getItem().getFeed().getImage().getImageBitmap());
-
- txtvPosition.setText(Converter.getDurationStringLong((player.getCurrentPosition())));
- txtvLength.setText(Converter.getDurationStringLong(player.getDuration()));
+ getSupportActionBar()
+ .setTitle(media.getItem().getFeed().getTitle());
+
+ imgvCover.setImageBitmap(media.getItem().getFeed().getImage()
+ .getImageBitmap());
+
+ txtvPosition.setText(Converter.getDurationStringLong((player
+ .getCurrentPosition())));
+ txtvLength.setText(Converter.getDurationStringLong(player
+ .getDuration()));
+ if (playbackService != null) {
+ updateProgressbarPosition();
+ } else {
+ sbPosition.setProgress(0);
+ }
}
}
-
+
private void setupGUI() {
imgvCover = (ImageView) findViewById(R.id.imgvCover);
txtvPosition = (TextView) findViewById(R.id.txtvPosition);
@@ -174,22 +224,23 @@ public class MediaplayerActivity extends SherlockActivity {
butPlay = (ImageButton) findViewById(R.id.butPlay);
butRev = (ImageButton) findViewById(R.id.butRev);
butFF = (ImageButton) findViewById(R.id.butFF);
-
+
sbPosition.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
int duration;
float prog;
-
+
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if (fromUser) {
prog = progress / 100.0f;
duration = playbackService.getPlayer().getDuration();
- txtvPosition.setText(Converter.getDurationStringLong((int) (prog * duration)));
+ txtvPosition.setText(Converter
+ .getDurationStringLong((int) (prog * duration)));
}
-
+
}
-
+
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// interrupt position Observer, restart later
@@ -198,25 +249,26 @@ public class MediaplayerActivity extends SherlockActivity {
positionObserver = null;
}
}
-
+
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
playbackService.seek((int) (prog * duration));
setupPositionObserver();
}
});
-
+
butPlay.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (status == PlayerStatus.PLAYING) {
playbackService.pause();
- } else if (status == PlayerStatus.PAUSED) {
+ } else if (status == PlayerStatus.PAUSED
+ || status == PlayerStatus.PREPARED) {
playbackService.play();
}
- }
+ }
});
-
+
butFF.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
@@ -225,7 +277,7 @@ public class MediaplayerActivity extends SherlockActivity {
}
}
});
-
+
butRev.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
@@ -235,17 +287,19 @@ public class MediaplayerActivity extends SherlockActivity {
}
});
}
-
-
+
private void handleError() {
// TODO implement
}
-
+
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
- playbackService = ((PlaybackService.LocalBinder)service).getService();
+ playbackService = ((PlaybackService.LocalBinder) service)
+ .getService();
status = playbackService.getStatus();
media = playbackService.getMedia();
+ registerReceiver(statusUpdate, new IntentFilter(
+ PlaybackService.ACTION_PLAYER_STATUS_CHANGED));
handleStatus();
Log.d(TAG, "Connection to Service established");
}
@@ -254,55 +308,48 @@ public class MediaplayerActivity extends SherlockActivity {
public void onServiceDisconnected(ComponentName name) {
playbackService = null;
Log.d(TAG, "Disconnected from Service");
-
+
}
};
-
+
private BroadcastReceiver statusUpdate = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- Log.d(TAG, "Received statusUpdate Intent.");
+ Log.d(TAG, "Received statusUpdate Intent.");
status = playbackService.getStatus();
handleStatus();
}
};
-
+
/** Refreshes the current position of the media file that is playing. */
- public class MediaPositionObserver extends AsyncTask<MediaPlayer, Integer, Boolean> {
-
+ public class MediaPositionObserver extends
+ AsyncTask<MediaPlayer, Void, Void> {
+
private static final int WAITING_INTERVALL = 1000;
private MediaPlayer player;
- private int duration;
-
+
@Override
- protected void onCancelled(Boolean result) {
+ protected void onCancelled() {
Log.d(TAG, "Task was cancelled");
}
-
+
@Override
- protected Boolean doInBackground(MediaPlayer... p) {
+ protected Void doInBackground(MediaPlayer... p) {
Log.d(TAG, "Background Task started");
player = p[0];
- duration = player.getDuration();
-
- while(player.isPlaying() && !isCancelled()) {
+
+ while (player.isPlaying() && !isCancelled()) {
try {
Thread.sleep(WAITING_INTERVALL);
- } catch(InterruptedException e) {
- Log.d(TAG, "Thread was interrupted while waiting. Finishing now");
- return false;
+ } catch (InterruptedException e) {
+ Log.d(TAG,
+ "Thread was interrupted while waiting. Finishing now");
}
- publishProgress(player.getCurrentPosition());
+ publishProgress();
}
Log.d(TAG, "Background Task finished");
- return true;
- }
-
- public int getDuration() {
- return duration;
+ return null;
}
}
-
-
-
+
}
diff --git a/src/de/podfetcher/feed/FeedManager.java b/src/de/podfetcher/feed/FeedManager.java
index 0968980e7..938b94bd6 100644
--- a/src/de/podfetcher/feed/FeedManager.java
+++ b/src/de/podfetcher/feed/FeedManager.java
@@ -34,7 +34,7 @@ public class FeedManager {
/** Contains completed Download status entries */
private ArrayList<DownloadStatus> downloadLog;
-
+
/** Contains the queue of items to be played. */
private ArrayList<FeedItem> queue;
@@ -59,18 +59,31 @@ public class FeedManager {
/**
* Play FeedMedia and start the playback service + launch Mediaplayer
* Activity.
+ *
+ * @param context
+ * for starting the playbackservice
+ * @param media
+ * that shall be played
+ * @param showPlayer
+ * if Mediaplayer activity shall be started
+ * @param startWhenPrepared
+ * if Mediaplayer shall be started after it has been prepared
*/
- public void playMedia(Context context, FeedMedia media) {
+ public void playMedia(Context context, FeedMedia media, boolean showPlayer,
+ boolean startWhenPrepared, boolean shouldStream) {
// Start playback Service
Intent launchIntent = new Intent(context, PlaybackService.class);
launchIntent.putExtra(PlaybackService.EXTRA_MEDIA_ID, media.getId());
launchIntent.putExtra(PlaybackService.EXTRA_FEED_ID, media.getItem()
.getFeed().getId());
+ launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, startWhenPrepared);
+ launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, shouldStream);
context.startService(launchIntent);
-
- // Launch Mediaplayer
- Intent playerIntent = new Intent(context, MediaplayerActivity.class);
- context.startActivity(playerIntent);
+ if (showPlayer) {
+ // Launch Mediaplayer
+ Intent playerIntent = new Intent(context, MediaplayerActivity.class);
+ context.startActivity(playerIntent);
+ }
}
/** Remove media item that has been downloaded. */
@@ -88,14 +101,15 @@ public class FeedManager {
Log.d(TAG, "Deleting File. Result: " + result);
return result;
}
-
+
/** Remove a feed with all its items and media files and its image. */
public boolean deleteFeed(Context context, Feed feed) {
PodDBAdapter adapter = new PodDBAdapter(context);
-
+
// delete image file
if (feed.getImage() != null) {
- if (feed.getImage().isDownloaded() && feed.getImage().getFile_url() == null) {
+ if (feed.getImage().isDownloaded()
+ && feed.getImage().getFile_url() == null) {
File imageFile = new File(feed.getImage().getFile_url());
imageFile.delete();
}
@@ -112,7 +126,7 @@ public class FeedManager {
}
adapter.removeFeed(feed);
return feeds.remove(feed);
-
+
}
/**
@@ -145,13 +159,13 @@ public class FeedManager {
}
return adapter.setDownloadStatus(status);
}
-
+
public void addQueueItem(Context context, FeedItem item) {
PodDBAdapter adapter = new PodDBAdapter(context);
queue.add(item);
adapter.setQueue(queue);
}
-
+
public void removeQueueItem(Context context, FeedItem item) {
boolean removed = queue.remove(item);
if (removed) {
@@ -159,11 +173,15 @@ public class FeedManager {
adapter.setQueue(queue);
}
}
-
+
public boolean isInQueue(FeedItem item) {
return queue.contains(item);
}
+ public FeedItem getFirstQueueItem() {
+ return queue.get(0);
+ }
+
private void addNewFeed(Context context, Feed feed) {
feeds.add(feed);
feed.setId(setFeed(context, feed));
@@ -447,16 +465,19 @@ public class FeedManager {
}
adapter.close();
}
-
+
private void extractQueueFromCursor(Context context) {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
Cursor cursor = adapter.getQueueCursor();
if (cursor.moveToFirst()) {
do {
- int index = cursor.getInt(cursor.getColumnIndex(PodDBAdapter.KEY_ID));
- Feed feed = getFeed(cursor.getLong(cursor.getColumnIndex(PodDBAdapter.KEY_FEED)));
- FeedItem item = getFeedItem(cursor.getColumnIndex(PodDBAdapter.KEY_FEEDITEM), feed);
+ int index = cursor.getInt(cursor
+ .getColumnIndex(PodDBAdapter.KEY_ID));
+ Feed feed = getFeed(cursor.getLong(cursor
+ .getColumnIndex(PodDBAdapter.KEY_FEED)));
+ FeedItem item = getFeedItem(
+ cursor.getColumnIndex(PodDBAdapter.KEY_FEEDITEM), feed);
queue.add(index, item);
} while (cursor.moveToNext());
}
diff --git a/src/de/podfetcher/service/PlaybackService.java b/src/de/podfetcher/service/PlaybackService.java
index ac590d683..13238357f 100644
--- a/src/de/podfetcher/service/PlaybackService.java
+++ b/src/de/podfetcher/service/PlaybackService.java
@@ -9,6 +9,7 @@ import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
@@ -21,6 +22,7 @@ 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.FeedMedia;
import de.podfetcher.feed.Feed;
@@ -28,22 +30,46 @@ import de.podfetcher.feed.FeedManager;
/** Controls the MediaPlayer that plays a FeedMedia-file */
public class PlaybackService extends Service {
+
/** Logging tag */
private static final String TAG = "PlaybackService";
+
+ /** Contains the id of the media that was played last. */
+ public static final String PREF_LAST_PLAYED_ID = "de.podfetcher.preferences.lastPlayedId";
+ /** Contains the feed id of the last played item. */
+ public static final String PREF_LAST_PLAYED_FEED_ID = "de.podfetcher.preferences.lastPlayedFeedId";
+ /** True if last played media was streamed. */
+ public static final String PREF_LAST_IS_STREAM = "de.podfetcher.preferences.lastIsStream";
+
+
/** Contains the id of the FeedMedia object. */
public static final String EXTRA_MEDIA_ID = "extra.de.podfetcher.service.mediaId";
/** Contains the id of the Feed object of the FeedMedia. */
public static final String EXTRA_FEED_ID = "extra.de.podfetcher.service.feedId";
+ /** True if media should be streamed. */
+ public static final String EXTRA_SHOULD_STREAM = "extra.de.podfetcher.service.shouldStream";
+ /**
+ * True if playback should be started immediately after media has been
+ * prepared.
+ */
+ public static final String EXTRA_START_WHEN_PREPARED = "extra.de.podfetcher.service.startWhenPrepared";
public static final String ACTION_PLAYER_STATUS_CHANGED = "action.de.podfetcher.service.playerStatusChanged";
+ /** Is true if service is running. */
+ public static boolean isRunning = false;
+
private static final int NOTIFICATION_ID = 1;
private NotificationCompat.Builder notificationBuilder;
private AudioManager audioManager;
private MediaPlayer player;
+
private FeedMedia media;
private Feed feed;
+ /** True if media should be streamed (Extracted from Intent Extra) . */
+ private boolean shouldStream;
+ private boolean startWhenPrepared;
private FeedManager manager;
private PlayerStatus status;
private PositionSaver positionSaver;
@@ -59,18 +85,28 @@ public class PlaybackService extends Service {
@Override
public void onCreate() {
super.onCreate();
+ isRunning = true;
+ status = PlayerStatus.STOPPED;
Log.d(TAG, "Service created.");
-
+ audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
manager = FeedManager.getInstance();
+ player = new MediaPlayer();
+ player.setOnPreparedListener(preparedListener);
+ player.setOnCompletionListener(completionListener);
}
@Override
- public IBinder onBind(Intent intent) {
- return mBinder;
+ public void onDestroy() {
+ super.onDestroy();
+ isRunning = false;
+ Log.d(TAG, "Service is about to be destroyed");
+ audioManager.abandonAudioFocus(audioFocusChangeListener);
+ player.release();
}
- private void setupAudioManager() {
- audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
}
private final OnAudioFocusChangeListener audioFocusChangeListener = new OnAudioFocusChangeListener() {
@@ -89,7 +125,8 @@ public class PlaybackService extends Service {
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
Log.d(TAG, "Lost audio focus temporarily. Ducking...");
- audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, 0);
+ audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
+ AudioManager.ADJUST_LOWER, 0);
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
Log.d(TAG, "Lost audio focus temporarily. Pausing...");
@@ -102,21 +139,39 @@ public class PlaybackService extends Service {
public int onStartCommand(Intent intent, int flags, int startId) {
long mediaId = intent.getLongExtra(EXTRA_MEDIA_ID, -1);
long feedId = intent.getLongExtra(EXTRA_FEED_ID, -1);
+ boolean playbackType = intent
+ .getBooleanExtra(EXTRA_SHOULD_STREAM, true);
if (mediaId == -1 || feedId == -1) {
Log.e(TAG, "Media ID or Feed ID wasn't provided to the Service.");
- } else {
+ if (media == null || feed == null) {
+ stopSelf();
+ }
// Intent values appear to be valid
- if (audioManager == null) {
- setupAudioManager();
+ // check if already playing and playbackType is the same
+ } else if (media == null || mediaId != media.getId()
+ || playbackType != shouldStream) {
+ pause();
+ player.reset();
+ if (media == null || mediaId != media.getId()) {
+ feed = manager.getFeed(feedId);
+ media = manager.getFeedMedia(mediaId, feed);
}
- Feed newFeed = manager.getFeed(feedId);
- FeedMedia newMedia = manager.getFeedMedia(mediaId, newFeed);
- if (media != null && media != newMedia) {
- pause();
- player.reset();
+
+ if (media != null) {
+ shouldStream = playbackType;
+ startWhenPrepared = intent.getBooleanExtra(
+ EXTRA_START_WHEN_PREPARED, false);
try {
- player.setDataSource(newMedia.getFile_url());
- player.prepare();
+ if (shouldStream) {
+ player.setDataSource(media.getDownload_url());
+ setStatus(PlayerStatus.PREPARING);
+ player.prepareAsync();
+ } else {
+ player.setDataSource(media.getFile_url());
+ setStatus(PlayerStatus.PREPARING);
+ player.prepare();
+ }
+
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
@@ -126,19 +181,16 @@ public class PlaybackService extends Service {
} catch (IOException e) {
e.printStackTrace();
}
- media = newMedia;
- feed = newFeed;
-
- } else if (media == null) {
- media = newMedia;
- feed = newFeed;
- player = MediaPlayer.create(this,
- Uri.fromFile(new File(media.getFile_url())));
- setStatus(PlayerStatus.PREPARING);
- player.setOnPreparedListener(preparedListener);
- Log.d(TAG, "Preparing to play file");
+
+ } else {
+ Log.e(TAG, "Media is null");
}
+ } else if (media != null && status != PlayerStatus.PLAYING) {
+ play();
+ } else {
+ Log.w(TAG, "Something went wrong. Shutting down...");
+ stopSelf();
}
setupNotification();
return Service.START_STICKY;
@@ -168,40 +220,71 @@ public class PlaybackService extends Service {
public void onPrepared(MediaPlayer mp) {
Log.d(TAG, "Resource prepared");
setStatus(PlayerStatus.PREPARED);
- int focusGained = audioManager.requestAudioFocus(
- audioFocusChangeListener, AudioManager.STREAM_MUSIC,
- AudioManager.AUDIOFOCUS_GAIN);
- if (focusGained == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
- Log.d(TAG, "Audiofocus successfully requested");
+ if (startWhenPrepared) {
play();
- } else {
- Log.d(TAG, "Failed to request Audiofocus");
}
}
};
+ private MediaPlayer.OnCompletionListener completionListener = new MediaPlayer.OnCompletionListener() {
+
+ @Override
+ public void onCompletion(MediaPlayer mp) {
+ Log.d(TAG, "Playback completed");
+ positionSaver.cancel(true);
+ media.setPosition(0);
+ manager.markItemRead(PlaybackService.this, media.getItem(), true);
+ if (manager.isInQueue(media.getItem())) {
+ manager.removeQueueItem(PlaybackService.this, media.getItem());
+ }
+ manager.setFeedMedia(PlaybackService.this, media);
+ setStatus(PlayerStatus.STOPPED);
+ stopForeground(true);
+
+ }
+ };
+
public void pause() {
if (player.isPlaying()) {
Log.d(TAG, "Pausing playback.");
player.pause();
saveCurrentPosition();
setStatus(PlayerStatus.PAUSED);
+ stopForeground(true);
}
}
public void play() {
- if (status == PlayerStatus.PAUSED || status == PlayerStatus.PREPARED) {
- Log.d(TAG, "Resuming/Starting playback");
- player.start();
- player.seekTo((int) media.getPosition());
- setStatus(PlayerStatus.PLAYING);
- setupPositionSaver();
- } else if (status == PlayerStatus.STOPPED) {
+ if (status == PlayerStatus.PAUSED || status == PlayerStatus.PREPARED
+ || status == PlayerStatus.STOPPED) {
+ int focusGained = audioManager.requestAudioFocus(
+ audioFocusChangeListener, AudioManager.STREAM_MUSIC,
+ AudioManager.AUDIOFOCUS_GAIN);
+
+ if (focusGained == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
+ Log.d(TAG, "Audiofocus successfully requested");
+ Log.d(TAG, "Resuming/Starting playback");
+ SharedPreferences.Editor editor = getApplicationContext()
+ .getSharedPreferences(PodcastApp.PREF_NAME, 0).edit();
+ editor.putLong(PREF_LAST_PLAYED_ID, media.getId());
+ editor.putLong(PREF_LAST_PLAYED_FEED_ID, feed.getId());
+ editor.putBoolean(PREF_LAST_IS_STREAM, shouldStream);
+ editor.commit();
+
+ player.start();
+ player.seekTo((int) media.getPosition());
+ setStatus(PlayerStatus.PLAYING);
+ setupPositionSaver();
+ setupNotification();
+ } else {
+ Log.d(TAG, "Failed to request Audiofocus");
+ }
}
}
private void setStatus(PlayerStatus newStatus) {
+ Log.d(TAG, "Setting status to " + newStatus);
status = newStatus;
sendBroadcast(new Intent(ACTION_PLAYER_STATUS_CHANGED));
}
@@ -279,4 +362,8 @@ public class PlaybackService extends Service {
}
+ public boolean isShouldStream() {
+ return shouldStream;
+ }
+
}
diff --git a/src/de/podfetcher/syndication/util/FeedItemMenuHandler.java b/src/de/podfetcher/syndication/util/FeedItemMenuHandler.java
index e1aded68e..533062f8f 100644
--- a/src/de/podfetcher/syndication/util/FeedItemMenuHandler.java
+++ b/src/de/podfetcher/syndication/util/FeedItemMenuHandler.java
@@ -25,6 +25,7 @@ public class FeedItemMenuHandler {
menu.findItem(R.id.remove_item).setVisible(true);
} else if (selectedItem.getMedia().getFile_url() == null) {
menu.findItem(R.id.download_item).setVisible(true);
+ menu.findItem(R.id.stream_item).setVisible(true);
} else {
menu.findItem(R.id.cancel_download_item).setVisible(true);
}
@@ -53,7 +54,7 @@ public class FeedItemMenuHandler {
break;
case R.id.play_item:
manager.playMedia(context,
- selectedItem.getMedia());
+ selectedItem.getMedia(), true, true, false);
break;
case R.id.remove_item:
manager.deleteFeedMedia(context,
@@ -75,6 +76,8 @@ public class FeedItemMenuHandler {
case R.id.remove_from_queue_item:
manager.removeQueueItem(context, selectedItem);
break;
+ case R.id.stream_item:
+ manager.playMedia(context, selectedItem.getMedia(), true, true, true);
}
// Refresh menu state