diff --git a/res/values/strings.xml b/res/values/strings.xml index f86a755b4..c2cafeeb5 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -69,5 +69,7 @@ Connection error Type in the URL of the Feed here: Cover + Server died + Unknown Error \ No newline at end of file diff --git a/src/de/podfetcher/activity/MediaplayerActivity.java b/src/de/podfetcher/activity/MediaplayerActivity.java index 62f6dde80..d74833446 100644 --- a/src/de/podfetcher/activity/MediaplayerActivity.java +++ b/src/de/podfetcher/activity/MediaplayerActivity.java @@ -1,8 +1,10 @@ package de.podfetcher.activity; +import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; @@ -50,6 +52,8 @@ import de.podfetcher.fragment.ItemDescriptionFragment; import de.podfetcher.service.PlaybackService; import de.podfetcher.service.PlayerStatus; import de.podfetcher.util.Converter; +import de.podfetcher.util.DownloadError; +import de.podfetcher.util.MediaPlayerError; public class MediaplayerActivity extends SherlockFragmentActivity implements SurfaceHolder.Callback { @@ -100,6 +104,13 @@ public class MediaplayerActivity extends SherlockFragmentActivity implements } catch (IllegalArgumentException e) { // ignore } + + try { + unregisterReceiver(notificationReceiver); + } catch (IllegalArgumentException e) { + // ignore + } + try { unbindService(mConnection); } catch (IllegalArgumentException e) { @@ -207,7 +218,6 @@ public class MediaplayerActivity extends SherlockFragmentActivity implements case ERROR: setStatusMsg(R.string.player_error_msg, View.VISIBLE); - handleError(); break; case PAUSED: setStatusMsg(R.string.player_paused_msg, View.VISIBLE); @@ -264,7 +274,9 @@ public class MediaplayerActivity extends SherlockFragmentActivity implements txtvPosition.setText(Converter .getDurationStringLong(playbackService.getPlayer() .getCurrentPosition())); - + txtvLength.setText(Converter + .getDurationStringLong(playbackService.getPlayer() + .getDuration())); updateProgressbarPosition(); } @@ -447,8 +459,19 @@ public class MediaplayerActivity extends SherlockFragmentActivity implements videoControlsShowing = !videoControlsShowing; } - private void handleError() { - // TODO implement + private void handleError(int errorCode) { + final AlertDialog errorDialog = new AlertDialog.Builder(this).create(); + errorDialog.setTitle(R.string.error_label); + errorDialog + .setMessage(MediaPlayerError.getErrorString(this, errorCode)); + errorDialog.setButton("OK", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + errorDialog.dismiss(); + finish(); + } + }); + errorDialog.show(); } private ServiceConnection mConnection = new ServiceConnection() { @@ -458,8 +481,13 @@ public class MediaplayerActivity extends SherlockFragmentActivity implements int requestedOrientation; status = playbackService.getStatus(); media = playbackService.getMedia(); + registerReceiver(statusUpdate, new IntentFilter( PlaybackService.ACTION_PLAYER_STATUS_CHANGED)); + + registerReceiver(notificationReceiver, new IntentFilter( + PlaybackService.ACTION_PLAYER_NOTIFICATION)); + if (playbackService.isPlayingVideo()) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; @@ -497,6 +525,27 @@ public class MediaplayerActivity extends SherlockFragmentActivity implements } }; + private BroadcastReceiver notificationReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(Context context, Intent intent) { + Log.d(TAG, "Received notification intent"); + int type = intent.getIntExtra( + PlaybackService.EXTRA_NOTIFICATION_TYPE, -1); + int code = intent.getIntExtra( + PlaybackService.EXTRA_NOTIFICATION_CODE, -1); + if (code != -1 && type != -1) { + if (type == PlaybackService.NOTIFICATION_TYPE_ERROR) { + handleError(code); + } + } else { + Log.d(TAG, "Bad arguments. Won't handle intent"); + } + + } + + }; + /** Refreshes the current position of the media file that is playing. */ public class MediaPositionObserver extends AsyncTask { diff --git a/src/de/podfetcher/service/PlaybackService.java b/src/de/podfetcher/service/PlaybackService.java index 3496e0beb..a852050df 100644 --- a/src/de/podfetcher/service/PlaybackService.java +++ b/src/de/podfetcher/service/PlaybackService.java @@ -56,6 +56,15 @@ public class PlaybackService extends Service { 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"; + + public static final String ACTION_PLAYER_NOTIFICATION = "action.de.podfetcher.service.playerNotification"; + public static final String EXTRA_NOTIFICATION_CODE = "extra.de.podfetcher.service.notificationCode"; + public static final String EXTRA_NOTIFICATION_TYPE = "extra.de.podfetcher.service.notificationType"; + + public static final int NOTIFICATION_TYPE_ERROR = 0; + public static final int NOTIFICATION_TYPE_INFO = 1; + public static final int NOTIFICATION_TYPE_BUFFER_UPDATE = 2; + /** Is true if service is running. */ public static boolean isRunning = false; @@ -100,6 +109,7 @@ public class PlaybackService extends Service { player.setOnPreparedListener(preparedListener); player.setOnCompletionListener(completionListener); player.setOnSeekCompleteListener(onSeekCompleteListener); + player.setOnErrorListener(onErrorListener); mediaButtonReceiver = new ComponentName(getPackageName(), MediaButtonReceiver.class.getName()); audioManager.registerMediaButtonEventReceiver(mediaButtonReceiver); @@ -266,6 +276,7 @@ public class PlaybackService extends Service { player.setOnPreparedListener(preparedListener); player.setOnCompletionListener(completionListener); player.setOnSeekCompleteListener(onSeekCompleteListener); + player.setOnErrorListener(onErrorListener); status = PlayerStatus.STOPPED; setupMediaplayer(); } @@ -342,6 +353,20 @@ public class PlaybackService extends Service { } }; + + private MediaPlayer.OnErrorListener onErrorListener = new MediaPlayer.OnErrorListener() { + private static final String TAG = "PlaybackService.onErrorListener"; + @Override + public boolean onError(MediaPlayer mp, int what, int extra) { + Log.w(TAG, "An error has occured: " + what); + if (mp.isPlaying()) { + pause(); + } + sendNotificationBroadcast(NOTIFICATION_TYPE_ERROR, what); + stopSelf(); + return true; + } + }; private MediaPlayer.OnCompletionListener completionListener = new MediaPlayer.OnCompletionListener() { @@ -413,6 +438,13 @@ public class PlaybackService extends Service { status = newStatus; sendBroadcast(new Intent(ACTION_PLAYER_STATUS_CHANGED)); } + + private void sendNotificationBroadcast(int type, int code) { + Intent intent = new Intent(ACTION_PLAYER_NOTIFICATION); + intent.putExtra(EXTRA_NOTIFICATION_TYPE, type); + intent.putExtra(EXTRA_NOTIFICATION_CODE, code); + sendBroadcast(intent); + } /** Prepares notification and starts the service in the foreground. */ private void setupNotification() { diff --git a/src/de/podfetcher/util/MediaPlayerError.java b/src/de/podfetcher/util/MediaPlayerError.java new file mode 100644 index 000000000..6b39762a6 --- /dev/null +++ b/src/de/podfetcher/util/MediaPlayerError.java @@ -0,0 +1,23 @@ +package de.podfetcher.util; + +import de.podfetcher.R; +import android.content.Context; +import android.media.MediaPlayer; + +/** Utility class for MediaPlayer errors. */ +public class MediaPlayerError { + + /** Get a human-readable string for a specific error code. */ + public static String getErrorString(Context context, int code) { + int resId; + switch(code) { + case MediaPlayer.MEDIA_ERROR_SERVER_DIED: + resId = R.string.playback_error_server_died; + break; + default: + resId = R.string.playback_error_unknown; + break; + } + return context.getString(resId); + } +}