parent
c33081b909
commit
d697fab7eb
@ -749,8 +749,8 @@ public class PlaybackService extends Service {
|
|||||||
final int smallIcon = ClientConfig.playbackServiceCallbacks.getNotificationIconResource(getApplicationContext());
|
final int smallIcon = ClientConfig.playbackServiceCallbacks.getNotificationIconResource(getApplicationContext());
|
||||||
|
|
||||||
if (!isCancelled() &&
|
if (!isCancelled() &&
|
||||||
started == true &&
|
started &&
|
||||||
info.playable != null) {
|
info.playable != null) {
|
||||||
String contentText = info.playable.getFeedTitle();
|
String contentText = info.playable.getFeedTitle();
|
||||||
String contentTitle = info.playable.getEpisodeTitle();
|
String contentTitle = info.playable.getEpisodeTitle();
|
||||||
Notification notification = null;
|
Notification notification = null;
|
||||||
@ -791,7 +791,7 @@ public class PlaybackService extends Service {
|
|||||||
.setLargeIcon(icon)
|
.setLargeIcon(icon)
|
||||||
.setSmallIcon(smallIcon)
|
.setSmallIcon(smallIcon)
|
||||||
.setPriority(UserPreferences.getNotifyPriority()); // set notification priority
|
.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
|
notificationBuilder.addAction(android.R.drawable.ic_media_pause, //pause action
|
||||||
getString(R.string.pause_label),
|
getString(R.string.pause_label),
|
||||||
pauseButtonPendingIntent);
|
pauseButtonPendingIntent);
|
||||||
@ -800,11 +800,20 @@ public class PlaybackService extends Service {
|
|||||||
getString(R.string.play_label),
|
getString(R.string.play_label),
|
||||||
playButtonPendingIntent);
|
playButtonPendingIntent);
|
||||||
}
|
}
|
||||||
if(UserPreferences.isPersistNotify()) {
|
if (UserPreferences.isPersistNotify()) {
|
||||||
notificationBuilder.addAction(android.R.drawable.ic_menu_close_clear_cancel, // stop action
|
notificationBuilder.addAction(android.R.drawable.ic_menu_close_clear_cancel, // stop action
|
||||||
getString(R.string.stop_label),
|
getString(R.string.stop_label),
|
||||||
stopButtonPendingIntent);
|
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();
|
notification = notificationBuilder.build();
|
||||||
} else {
|
} else {
|
||||||
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(
|
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(
|
||||||
@ -813,7 +822,7 @@ public class PlaybackService extends Service {
|
|||||||
.setContentText(contentText).setOngoing(true)
|
.setContentText(contentText).setOngoing(true)
|
||||||
.setContentIntent(pIntent).setLargeIcon(icon)
|
.setContentIntent(pIntent).setLargeIcon(icon)
|
||||||
.setSmallIcon(smallIcon);
|
.setSmallIcon(smallIcon);
|
||||||
notification = notificationBuilder.getNotification();
|
notification = notificationBuilder.build();
|
||||||
}
|
}
|
||||||
startForeground(NOTIFICATION_ID, notification);
|
startForeground(NOTIFICATION_ID, notification);
|
||||||
if (BuildConfig.DEBUG)
|
if (BuildConfig.DEBUG)
|
||||||
|
@ -6,6 +6,9 @@ import android.media.AudioManager;
|
|||||||
import android.media.RemoteControlClient;
|
import android.media.RemoteControlClient;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.PowerManager;
|
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.telephony.TelephonyManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
@ -48,6 +51,10 @@ public class PlaybackServiceMediaPlayer {
|
|||||||
private volatile PlayerStatus statusBeforeSeeking;
|
private volatile PlayerStatus statusBeforeSeeking;
|
||||||
private volatile IPlayer mediaPlayer;
|
private volatile IPlayer mediaPlayer;
|
||||||
private volatile Playable media;
|
private volatile Playable media;
|
||||||
|
/**
|
||||||
|
* Only used for Lollipop notifications.
|
||||||
|
*/
|
||||||
|
private final MediaSessionCompat mediaSession;
|
||||||
|
|
||||||
private volatile boolean stream;
|
private volatile boolean stream;
|
||||||
private volatile MediaType mediaType;
|
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;
|
mediaPlayer = null;
|
||||||
statusBeforeSeeking = null;
|
statusBeforeSeeking = null;
|
||||||
pausedBecauseOfTransientAudiofocusLoss = false;
|
pausedBecauseOfTransientAudiofocusLoss = false;
|
||||||
@ -181,6 +192,7 @@ public class PlaybackServiceMediaPlayer {
|
|||||||
setPlayerStatus(PlayerStatus.INITIALIZING, media);
|
setPlayerStatus(PlayerStatus.INITIALIZING, media);
|
||||||
try {
|
try {
|
||||||
media.loadMetadata();
|
media.loadMetadata();
|
||||||
|
mediaSession.setMetadata(getMediaSessionMetadata(media));
|
||||||
if (stream) {
|
if (stream) {
|
||||||
mediaPlayer.setDataSource(media.getStreamUrl());
|
mediaPlayer.setDataSource(media.getStreamUrl());
|
||||||
} else {
|
} 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.
|
* 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) {
|
if (mediaPlayer != null) {
|
||||||
mediaPlayer.release();
|
mediaPlayer.release();
|
||||||
}
|
}
|
||||||
|
if (mediaSession != null) {
|
||||||
|
mediaSession.release();
|
||||||
|
}
|
||||||
releaseWifiLockIfNecessary();
|
releaseWifiLockIfNecessary();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,6 +688,16 @@ public class PlaybackServiceMediaPlayer {
|
|||||||
return new PSMPInfo(playerStatus, media);
|
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
|
* 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).
|
* 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.playerStatus = newStatus;
|
||||||
this.media = newMedia;
|
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));
|
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…
x
Reference in New Issue
Block a user