parent
c33081b909
commit
d697fab7eb
|
@ -749,7 +749,7 @@ public class PlaybackService extends Service {
|
|||
final int smallIcon = ClientConfig.playbackServiceCallbacks.getNotificationIconResource(getApplicationContext());
|
||||
|
||||
if (!isCancelled() &&
|
||||
started == true &&
|
||||
started &&
|
||||
info.playable != null) {
|
||||
String contentText = info.playable.getFeedTitle();
|
||||
String contentTitle = info.playable.getEpisodeTitle();
|
||||
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -666,6 +688,16 @@ public class PlaybackServiceMediaPlayer {
|
|||
return new PSMPInfo(playerStatus, media);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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).
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue