diff options
author | daniel oeh <daniel.oeh@gmail.com> | 2015-01-02 00:01:53 +0100 |
---|---|---|
committer | daniel oeh <daniel.oeh@gmail.com> | 2015-01-02 00:01:53 +0100 |
commit | d697fab7eb8202fceca52895dd5dee2e4f139247 (patch) | |
tree | f3d10028daa4700d79a797fe92a30e131d845084 /core | |
parent | c33081b909a800aeae138a9ded37f4358e36b66c (diff) | |
download | AntennaPod-d697fab7eb8202fceca52895dd5dee2e4f139247.zip |
Use MediaStyle Notification on Lollipop
fixes #543
Diffstat (limited to 'core')
2 files changed, 135 insertions, 5 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java index 064baae75..866f1cba3 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java @@ -749,8 +749,8 @@ public class PlaybackService extends Service { final int smallIcon = ClientConfig.playbackServiceCallbacks.getNotificationIconResource(getApplicationContext()); if (!isCancelled() && - started == true && - info.playable != null) { + started && + info.playable != null) { String contentText = info.playable.getFeedTitle(); String contentTitle = info.playable.getEpisodeTitle(); Notification notification = null; @@ -791,7 +791,7 @@ public class PlaybackService extends Service { .setLargeIcon(icon) .setSmallIcon(smallIcon) .setPriority(UserPreferences.getNotifyPriority()); // set notification priority - if(newInfo.playerStatus == PlayerStatus.PLAYING){ + if (newInfo.playerStatus == PlayerStatus.PLAYING) { notificationBuilder.addAction(android.R.drawable.ic_media_pause, //pause action getString(R.string.pause_label), pauseButtonPendingIntent); @@ -800,11 +800,20 @@ public class PlaybackService extends Service { getString(R.string.play_label), playButtonPendingIntent); } - if(UserPreferences.isPersistNotify()) { + if (UserPreferences.isPersistNotify()) { notificationBuilder.addAction(android.R.drawable.ic_menu_close_clear_cancel, // stop action getString(R.string.stop_label), stopButtonPendingIntent); } + + if (Build.VERSION.SDK_INT >= 21) { + notificationBuilder.setStyle(new Notification.MediaStyle() + .setMediaSession((android.media.session.MediaSession.Token) mediaPlayer.getSessionToken().getToken()) + .setShowActionsInCompactView(0)) + .setVisibility(Notification.VISIBILITY_PUBLIC) + .setColor(Notification.COLOR_DEFAULT); + } + notification = notificationBuilder.build(); } else { NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder( @@ -813,7 +822,7 @@ public class PlaybackService extends Service { .setContentText(contentText).setOngoing(true) .setContentIntent(pIntent).setLargeIcon(icon) .setSmallIcon(smallIcon); - notification = notificationBuilder.getNotification(); + notification = notificationBuilder.build(); } startForeground(NOTIFICATION_ID, notification); if (BuildConfig.DEBUG) diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java index ad5154faf..c143d7f2c 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java @@ -6,6 +6,9 @@ import android.media.AudioManager; import android.media.RemoteControlClient; import android.net.wifi.WifiManager; import android.os.PowerManager; +import android.support.v4.media.MediaMetadataCompat; +import android.support.v4.media.session.MediaSessionCompat; +import android.support.v4.media.session.PlaybackStateCompat; import android.telephony.TelephonyManager; import android.util.Log; import android.util.Pair; @@ -48,6 +51,10 @@ public class PlaybackServiceMediaPlayer { private volatile PlayerStatus statusBeforeSeeking; private volatile IPlayer mediaPlayer; private volatile Playable media; + /** + * Only used for Lollipop notifications. + */ + private final MediaSessionCompat mediaSession; private volatile boolean stream; private volatile MediaType mediaType; @@ -89,6 +96,10 @@ public class PlaybackServiceMediaPlayer { } ); + mediaSession = new MediaSessionCompat(context, TAG); + mediaSession.setCallback(sessionCallback); + mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); + mediaPlayer = null; statusBeforeSeeking = null; pausedBecauseOfTransientAudiofocusLoss = false; @@ -181,6 +192,7 @@ public class PlaybackServiceMediaPlayer { setPlayerStatus(PlayerStatus.INITIALIZING, media); try { media.loadMetadata(); + mediaSession.setMetadata(getMediaSessionMetadata(media)); if (stream) { mediaPlayer.setDataSource(media.getStreamUrl()); } else { @@ -211,6 +223,13 @@ public class PlaybackServiceMediaPlayer { } } + private MediaMetadataCompat getMediaSessionMetadata(Playable p) { + MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); + builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, p.getEpisodeTitle()); + builder.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, p.getFeedTitle()); + return builder.build(); + } + /** * Resumes playback if the PSMP object is in PREPARED or PAUSED state. If the PSMP object is in an invalid state. @@ -603,6 +622,9 @@ public class PlaybackServiceMediaPlayer { if (mediaPlayer != null) { mediaPlayer.release(); } + if (mediaSession != null) { + mediaSession.release(); + } releaseWifiLockIfNecessary(); } @@ -667,6 +689,16 @@ public class PlaybackServiceMediaPlayer { } /** + * Returns a token to this object's MediaSession. The MediaSession should only be used for notifications + * at the moment. + * + * @return The MediaSessionCompat.Token object. + */ + public MediaSessionCompat.Token getSessionToken() { + return mediaSession.getSessionToken(); + } + + /** * Sets the player status of the PSMP object. PlayerStatus and media attributes have to be set at the same time * so that getPSMPInfo can't return an invalid state (e.g. status is PLAYING, but media is null). * <p/> @@ -683,6 +715,45 @@ public class PlaybackServiceMediaPlayer { this.playerStatus = newStatus; this.media = newMedia; + + PlaybackStateCompat.Builder sessionState = new PlaybackStateCompat.Builder(); + + int state; + if (playerStatus != null) { + switch (playerStatus) { + case PLAYING: + state = PlaybackStateCompat.STATE_PLAYING; + break; + case PREPARED: + case PAUSED: + state = PlaybackStateCompat.STATE_PAUSED; + break; + case STOPPED: + state = PlaybackStateCompat.STATE_STOPPED; + break; + case SEEKING: + state = PlaybackStateCompat.STATE_FAST_FORWARDING; + break; + case PREPARING: + case INITIALIZING: + state = PlaybackStateCompat.STATE_CONNECTING; + break; + case INITIALIZED: + case INDETERMINATE: + state = PlaybackStateCompat.STATE_NONE; + break; + case ERROR: + state = PlaybackStateCompat.STATE_ERROR; + break; + default: + state = PlaybackStateCompat.STATE_NONE; + break; + } + } else { + state = PlaybackStateCompat.STATE_NONE; + } + sessionState.setState(state, PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN, getPlaybackSpeed()); + callback.statusChanged(new PSMPInfo(playerStatus, media)); } @@ -980,4 +1051,54 @@ public class PlaybackServiceMediaPlayer { } }); } + + private final MediaSessionCompat.Callback sessionCallback = new MediaSessionCompat.Callback() { + + @Override + public void onPlay() { + if (playerStatus == PlayerStatus.PAUSED || playerStatus == PlayerStatus.PREPARED) { + resume(); + } else if (playerStatus == PlayerStatus.INITIALIZED) { + setStartWhenPrepared(true); + prepare(); + } + } + + @Override + public void onPause() { + super.onPause(); + if (playerStatus == PlayerStatus.PLAYING) { + pause(false, true); + } + if (UserPreferences.isPersistNotify()) { + pause(false, true); + } else { + pause(true, true); + } + } + + @Override + public void onSkipToNext() { + super.onSkipToNext(); + endPlayback(); + } + + @Override + public void onFastForward() { + super.onFastForward(); + seekDelta(UserPreferences.getSeekDeltaMs()); + } + + @Override + public void onRewind() { + super.onRewind(); + seekDelta(-UserPreferences.getSeekDeltaMs()); + } + + @Override + public void onSeekTo(long pos) { + super.onSeekTo(pos); + seekTo((int) pos); + } + }; } |