From 451483180f3e3cc8e258ed83156f2ed7ef758f67 Mon Sep 17 00:00:00 2001 From: daniel Date: Tue, 5 Jun 2012 13:46:26 +0200 Subject: [PATCH] Expanded MediaplayerActivity + Bugfixes --- AndroidManifest.xml | 1 + res/layout/mediaplayer_activity.xml | 17 +- res/values/strings.xml | 6 +- .../podfetcher/activity/ItemviewActivity.java | 5 + .../activity/MediaplayerActivity.java | 227 ++++++++++++++++++ .../podfetcher/service/PlaybackService.java | 35 ++- src/de/podfetcher/service/PlayerStatus.java | 5 + 7 files changed, 290 insertions(+), 6 deletions(-) create mode 100644 src/de/podfetcher/activity/MediaplayerActivity.java create mode 100644 src/de/podfetcher/service/PlayerStatus.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 25a9aa890..3dbb90c94 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -29,6 +29,7 @@ + diff --git a/res/layout/mediaplayer_activity.xml b/res/layout/mediaplayer_activity.xml index b5b4d0a58..d6ee82733 100644 --- a/res/layout/mediaplayer_activity.xml +++ b/res/layout/mediaplayer_activity.xml @@ -6,7 +6,7 @@ android:orientation="vertical" > + + diff --git a/res/values/strings.xml b/res/values/strings.xml index f59baec12..092b376f2 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -30,5 +30,9 @@ No feeds added yet. - + + Paused + Error! + Stopped + Preparing... diff --git a/src/de/podfetcher/activity/ItemviewActivity.java b/src/de/podfetcher/activity/ItemviewActivity.java index eae35ac5b..84b70a67f 100644 --- a/src/de/podfetcher/activity/ItemviewActivity.java +++ b/src/de/podfetcher/activity/ItemviewActivity.java @@ -57,10 +57,15 @@ public class ItemviewActivity extends SherlockActivity { butPlay.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + // Start playback Service Intent launchIntent = new Intent(v.getContext(), PlaybackService.class); launchIntent.putExtra(PlaybackService.EXTRA_MEDIA_ID, item.getMedia().getId()); launchIntent.putExtra(PlaybackService.EXTRA_FEED_ID, item.getFeed().getId()); v.getContext().startService(launchIntent); + + // Launch Mediaplayer + Intent playerIntent = new Intent(v.getContext(), MediaplayerActivity.class); + v.getContext().startActivity(playerIntent); } }); } diff --git a/src/de/podfetcher/activity/MediaplayerActivity.java b/src/de/podfetcher/activity/MediaplayerActivity.java new file mode 100644 index 000000000..37a645cb0 --- /dev/null +++ b/src/de/podfetcher/activity/MediaplayerActivity.java @@ -0,0 +1,227 @@ +package de.podfetcher.activity; + +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.ServiceConnection; +import android.media.MediaPlayer; +import android.os.AsyncTask; +import android.os.Bundle; +import android.os.IBinder; +import android.util.Log; +import android.view.View; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.SeekBar; +import android.widget.TextView; + +import com.actionbarsherlock.app.SherlockActivity; +import com.actionbarsherlock.view.Menu; + +import de.podfetcher.R; +import de.podfetcher.feed.FeedMedia; +import de.podfetcher.service.PlaybackService; +import de.podfetcher.service.PlayerStatus; +import de.podfetcher.util.Converter; + +public class MediaplayerActivity extends SherlockActivity { + private final String TAG = "MediaplayerActivity"; + + private PlaybackService playbackService; + private MediaPositionObserver positionObserver; + + private FeedMedia media; + private PlayerStatus status; + + private boolean guiSetup; + + + // Widgets + private ImageView imgvCover; + private TextView txtvStatus; + private TextView txtvPosition; + private TextView txtvLength; + private SeekBar sbPosition; + private ImageButton butPlay; + private ImageButton butRev; + private ImageButton butFF; + + @Override + protected void onStop() { + super.onStop(); + Log.d(TAG, "Activity stopped"); + unregisterReceiver(statusUpdate); + unbindService(mConnection); + if (positionObserver != null) { + positionObserver.cancel(true); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // TODO Auto-generated method stub + return super.onCreateOptionsMenu(menu); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + this.setContentView(R.layout.mediaplayer_activity); + + guiSetup = false; + setupGUI(); + if(!bindService(new Intent(this, PlaybackService.class), mConnection, 0)) { + status = PlayerStatus.STOPPED; + handleStatus(); + } + IntentFilter filter = new IntentFilter(PlaybackService.ACTION_PLAYER_STATUS_CHANGED); + registerReceiver(statusUpdate, filter); + } + + private void handleStatus() { + switch (status) { + + case ERROR: + setStatusMsg(R.string.player_error_msg, View.VISIBLE); + handleError(); + break; + case PAUSED: + setStatusMsg(R.string.player_paused_msg, View.VISIBLE); + loadMediaInfo(); + break; + case PLAYING: + setStatusMsg(0, View.INVISIBLE); + loadMediaInfo(); + setupPositionObserver(); + break; + case PREPARING: + setStatusMsg(R.string.player_preparing_msg, View.VISIBLE); + break; + } + } + + private void setStatusMsg(int resId, int visibility) { + if(visibility == View.VISIBLE) { + txtvStatus.setText(resId); + } + txtvStatus.setVisibility(visibility); + } + + private void setupPositionObserver() { + if (positionObserver == null) { + positionObserver = new MediaPositionObserver() { + + @Override + protected void onProgressUpdate(Long... values) { + super.onProgressUpdate(values); + txtvPosition.setText( + Integer.toString(playbackService.getPlayer().getCurrentPosition())); + } + + }; + positionObserver.execute(playbackService); + } + } + + private void loadMediaInfo() { + if (media != null) { + MediaPlayer player = playbackService.getPlayer(); + + getSupportActionBar().setTitle(media.getItem().getTitle()); + getSupportActionBar().setSubtitle( + media.getItem().getFeed().getTitle()); + + imgvCover.setImageBitmap( + media.getItem().getFeed().getImage().getImageBitmap()); + + txtvPosition.setText(Integer.toString(player.getCurrentPosition())); + txtvLength.setText(Integer.toString(player.getDuration())); + } + } + + private void setupGUI() { + imgvCover = (ImageView) findViewById(R.id.imgvCover); + txtvPosition = (TextView) findViewById(R.id.txtvPosition); + txtvLength = (TextView) findViewById(R.id.txtvLength); + txtvStatus = (TextView) findViewById(R.id.txtvStatus); + sbPosition = (SeekBar) findViewById(R.id.sbPosition); + butPlay = (ImageButton) findViewById(R.id.butPlay); + butRev = (ImageButton) findViewById(R.id.butRev); + butFF = (ImageButton) findViewById(R.id.butFF); + + this.guiSetup = true; + } + + + private void handleError() { + // TODO implement + } + + private ServiceConnection mConnection = new ServiceConnection() { + public void onServiceConnected(ComponentName className, IBinder service) { + playbackService = ((PlaybackService.LocalBinder)service).getService(); + status = playbackService.getStatus(); + media = playbackService.getMedia(); + handleStatus(); + Log.d(TAG, "Connection to Service established"); + } + + @Override + 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."); + status = playbackService.getStatus(); + } + }; + + + public class MediaPositionObserver extends AsyncTask { + + private static final int WAITING_INTERVALL = 1000; + private long position; + private long length; + private PlaybackService service; + + @Override + protected void onCancelled(Long result) { + Log.d(TAG, "Task was cancelled"); + } + + protected Long doInBackground(PlaybackService... services) { + Log.d(TAG, "Background Task started"); + service = services[0]; + getProgress(); + while(!isCancelled()) { + try { + Thread.sleep(WAITING_INTERVALL); + } catch(InterruptedException e) { + Log.d(TAG, "Thread was interrupted while waiting"); + } + + getProgress(); + publishProgress(position); + } + Log.d(TAG, "Background Task finished"); + return Long.valueOf(position); + } + + private void getProgress() { + FeedMedia media = service.getMedia(); + position = media.getPosition(); + length = media.getLength(); + } + } + + + +} diff --git a/src/de/podfetcher/service/PlaybackService.java b/src/de/podfetcher/service/PlaybackService.java index a4043f6f4..4d02db308 100644 --- a/src/de/podfetcher/service/PlaybackService.java +++ b/src/de/podfetcher/service/PlaybackService.java @@ -7,6 +7,7 @@ import android.content.Intent; import android.media.MediaPlayer; import android.util.Log; import android.net.Uri; +import android.os.Binder; import android.os.IBinder; import de.podfetcher.feed.FeedMedia; @@ -22,11 +23,23 @@ public class PlaybackService extends Service { /** Contains the id of the Feed object of the FeedMedia. */ public static final String EXTRA_FEED_ID = "extra.de.podfetcher.service.feedId"; + public static final String ACTION_PLAYER_STATUS_CHANGED = + "action.de.podfetcher.service.playerStatusChanged"; + private MediaPlayer player; private FeedMedia media; private Feed feed; private FeedManager manager; + private PlayerStatus status; + private final IBinder mBinder = new LocalBinder(); + + public class LocalBinder extends Binder { + public PlaybackService getService() { + return PlaybackService.this; + } + } + @Override public void onCreate() { super.onCreate(); @@ -37,7 +50,7 @@ public class PlaybackService extends Service { @Override public IBinder onBind(Intent intent) { - return null; + return mBinder; } @Override @@ -52,7 +65,9 @@ public class PlaybackService extends Service { } else { feed = manager.getFeed(feedId); media = manager.getFeedMedia(mediaId, feed); + player = MediaPlayer.create(this, Uri.fromFile(new File(media.getFile_url()))); + setStatus(PlayerStatus.PREPARING); player.setOnPreparedListener(preparedListener); Log.d(TAG, "Preparing to play file"); //player.prepareAsync(); @@ -65,7 +80,25 @@ public class PlaybackService extends Service { public void onPrepared(MediaPlayer mp) { Log.d(TAG, "Resource prepared"); mp.start(); + setStatus(PlayerStatus.PLAYING); } }; + + private void setStatus(PlayerStatus newStatus) { + status = newStatus; + sendBroadcast(new Intent(ACTION_PLAYER_STATUS_CHANGED)); + } + + public PlayerStatus getStatus() { + return status; + } + + public FeedMedia getMedia() { + return media; + } + + public MediaPlayer getPlayer() { + return player; + } } diff --git a/src/de/podfetcher/service/PlayerStatus.java b/src/de/podfetcher/service/PlayerStatus.java new file mode 100644 index 000000000..8f1d1d696 --- /dev/null +++ b/src/de/podfetcher/service/PlayerStatus.java @@ -0,0 +1,5 @@ +package de.podfetcher.service; + +public enum PlayerStatus { + ERROR, PREPARING, PAUSED, PLAYING, STOPPED +}