summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authordaniel oeh <daniel.oeh@gmail.com>2015-01-02 00:01:53 +0100
committerdaniel oeh <daniel.oeh@gmail.com>2015-01-02 00:01:53 +0100
commitd697fab7eb8202fceca52895dd5dee2e4f139247 (patch)
treef3d10028daa4700d79a797fe92a30e131d845084 /core
parentc33081b909a800aeae138a9ded37f4358e36b66c (diff)
downloadAntennaPod-d697fab7eb8202fceca52895dd5dee2e4f139247.zip
Use MediaStyle Notification on Lollipop
fixes #543
Diffstat (limited to 'core')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java19
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java121
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);
+ }
+ };
}