how to show previous and next button on lockscreen with MediaSession extension for ExoPlayer
I am using
https://github.com/google/ExoPlayer/tree/release-v2/extensions/mediasession
implementation 'com.google.android.exoplayer:exoplayer-core:2.8.1'
implementation 'com.google.android.exoplayer:exoplayer-ui:2.8.1'
implementation 'com.google.android.exoplayer:extension-mediasession:2.8.1'
and code is from
https://www.youtube.com/watch?v=svdq1BWl4r8
and
https://github.com/google/Exoplayer/tree/io18
the media sessions code is
mediaSession = new MediaSessionCompat(context, MEDIA_SESSION_TAG);
mediaSession.setActive(true);
playerNotificationManager.setMediaSessionToken(mediaSession.getSessionToken());
mediaSessionConnector = new MediaSessionConnector(mediaSession);
mediaSessionConnector.setQueueNavigator(new TimelineQueueNavigator(mediaSession) {
@Override
public MediaDescriptionCompat getMediaDescription(Player player, int windowIndex) {
return Samples.getMediaDescription(context, SAMPLES[windowIndex]);
}
});
mediaSessionConnector.setPlayer(player, null);
what i want is to show previous and next button like this
https://cdn-images-1.medium.com/max/800/1*xgjqZoP67CVMAGCtOLhCPA.png
from this
https://medium.com/google-exoplayer/the-mediasession-extension-for-exoplayer-82b9619deb2d
but what i get is

The code has been tested on lenovo A7000 OS marshmallow
and
moto c OS nougat
how to show previous and next button on lockscreen with MediaSession extension for ExoPlayer
This issue does not seem to follow the issue template. Make sure you provide all the required information.
@marcbaechinger would you kindly look at this?
This is not determined by the MediaSession but by the MediaStyle notification to which the mediaSession is attached.
The MediaStyle object has a method mediaStyle.setShowActionsInCompactView(int... actionIndex)which lets us define which actions should be shown in compact view. Please note that this changes the look of both the NotificationCompat in the drawer and the notification in the lock screen.
When doing a notification with ExoPlayer I'd recommend to use the PlayerNotificationManager of the ui module. By default the PlayerNotificationManager only sets the play or pause button to be shown in compact mode. You can customize this behaviour by overriding the method getActionIndicesForCompactView(List<String> actionNames, Player player):int[].
You need to be careful though that you only return indices of actions which are actually in the list of actionNames at that very moment. Specifically for the next/previous actions. If you are using an index which is not valid, your app crashes. I haven't tested this in-depth but it's possibly something like this:
@Overrride
protected int[] getActionIndicesForCompactView(List<String> actionNames, Player player) {
int pauseActionIndex = actionNames.indexOf(ACTION_PAUSE);
int playActionIndex = actionNames.indexOf(ACTION_PLAY);
int skipNextActionIndex = actionNames.indexOf(ACTION_NEXT);
int skipPreviousActionIndex = actionNames.indexOf(ACTION_PREVIOUS);
int numberOfActionIndices = (pauseActionIndex != -1 || playActionIndex != -1) ? 1 : 0;
if (skipNextActionIndex != -1) {
numberOfActionIndices++;
}
if (skipPreviousActionIndex != -1) {
numberOfActionIndices++;
}
int[] actionIndices = new int[numberOfActionIndices];
int actionCounter = 0;
if (skipPreviousActionIndex != -1) {
actionIndices[actionCounter++] = skipPreviousActionIndex;
}
if (pauseActionIndex != -1) {
actionIndices[actionCounter++] = pauseActionIndex;
}
if (playActionIndex != -1) {
actionIndices[actionCounter++] = playActionIndex;
}
if (skipNextActionIndex != -1) {
actionIndices[actionCounter] = skipNextActionIndex;
}
return actionIndices;
}
since you have not tried the code, this is my code
final Context context = this;
player = ExoPlayerFactory.newSimpleInstance(context, new DefaultTrackSelector());
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(
context, Util.getUserAgent(context, getString(R.string.application_name)));
CacheDataSourceFactory cacheDataSourceFactory = new CacheDataSourceFactory(
DownloadUtil.getCache(context),
dataSourceFactory,
CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR);
ConcatenatingMediaSource concatenatingMediaSource = new ConcatenatingMediaSource();
for (Samples.Sample sample : SAMPLES) {
MediaSource mediaSource = new ExtractorMediaSource.Factory(cacheDataSourceFactory)
.createMediaSource(sample.uri);
concatenatingMediaSource.addMediaSource(mediaSource);
}
player.prepare(concatenatingMediaSource);
player.setPlayWhenReady(true);
playerNotificationManager = customAction.createWithNotificationChannel(
context,
PLAYBACK_CHANNEL_ID,
R.string.playback_channel_name,
PLAYBACK_NOTIFICATION_ID,
new PlayerNotificationManager.MediaDescriptionAdapter() {
@Override
public String getCurrentContentTitle(Player player) {
return SAMPLES[player.getCurrentWindowIndex()].title;
}
@Nullable
@Override
public PendingIntent createCurrentContentIntent(Player player) {
return null;
}
@Nullable
@Override
public String getCurrentContentText(Player player) {
return SAMPLES[player.getCurrentWindowIndex()].description;
}
@Nullable
@Override
public Bitmap getCurrentLargeIcon(Player player, PlayerNotificationManager.BitmapCallback callback) {
return Samples.getBitmap(
context, SAMPLES[player.getCurrentWindowIndex()].bitmapResource);
}
}
);
playerNotificationManager.setNotificationListener(new
NotificationListener() {
@Override
public void onNotificationStarted ( int notificationId, Notification notification){
startForeground(notificationId, notification);
}
@Override
public void onNotificationCancelled ( int notificationId){
stopSelf();
}
}
);
playerNotificationManager.setPlayer(player);
playerNotificationManager.setUseChronometer(false);
playerNotificationManager.setUseNavigationActions(true);
mediaSession =new MediaSessionCompat(context, MEDIA_SESSION_TAG);
mediaSession.setActive(true);
playerNotificationManager.setMediaSessionToken(mediaSession.getSessionToken());
mediaSessionConnector =new
MediaSessionConnector(mediaSession);
mediaSessionConnector.setQueueNavigator(new
TimelineQueueNavigator(mediaSession) {
@Override
public MediaDescriptionCompat getMediaDescription (Player player,int windowIndex){
return Samples.getMediaDescription(context, SAMPLES[windowIndex]);
}
});
mediaSessionConnector.setPlayer(player,null,null);
private class customAction extends PlayerNotificationManager {
public customAction(Context context, String channelId, int notificationId, MediaDescriptionAdapter mediaDescriptionAdapter) {
super(context, channelId, notificationId, mediaDescriptionAdapter);
}
@Override
protected int[] getActionIndicesForCompactView(List<String> actionNames, Player player) {
int pauseActionIndex = actionNames.indexOf(ACTION_PAUSE);
int playActionIndex = actionNames.indexOf(ACTION_PLAY);
int skipNextActionIndex = actionNames.indexOf(ACTION_NEXT);
int skipPreviousActionIndex = actionNames.indexOf(ACTION_PREVIOUS);
int numberOfActionIndices = (pauseActionIndex != -1 || playActionIndex != -1) ? 1 : 0;
if (skipNextActionIndex != -1) {
numberOfActionIndices++;
}
if (skipPreviousActionIndex != -1) {
numberOfActionIndices++;
}
int[] actionIndices = new int[3];
int actionCounter = 0;
if (skipPreviousActionIndex != -1) {
actionIndices[actionCounter++] = skipPreviousActionIndex;
}
if (pauseActionIndex != -1) {
actionIndices[actionCounter++] = pauseActionIndex;
}
if (playActionIndex != -1) {
actionIndices[actionCounter++] = playActionIndex;
}
if (skipNextActionIndex != -1) {
actionIndices[actionCounter] = skipNextActionIndex;
}
return actionIndices;
}
}
How ever still it doesnot return all the 3 buttons required, it just returns only play/pause button
for the original project code you can try
https://github.com/google/Exoplayer/tree/io18
can you please provide a solution, can it be added as a feature in future release to customize
getActionIndicesForCompactView(List
What enhancement is this issue tracking? It's unclear from the thread above. Could we rename the title to better reflect this, also? Thanks!
I marked this issue as an enhancement.
We should think about providing an option which lets developer include prev/next button in compact mode of the notification without needing to override the getActionIndicesForCompactView(List<String> actionNames, Player player):int[] method.
This would improve the interplay between PlayerNotifciationManager and MediaSessionConnector specifically for the lock screen use case which appears to be an important bit for media app usability.
any time line when this will be included in future releases
This was in the 2.10.0 release.
Most helpful comment
I marked this issue as an enhancement.
We should think about providing an option which lets developer include prev/next button in compact mode of the notification without needing to override the
getActionIndicesForCompactView(List<String> actionNames, Player player):int[]method.This would improve the interplay between
PlayerNotifciationManagerandMediaSessionConnectorspecifically for the lock screen use case which appears to be an important bit for media app usability.