Class ServiceMediaApi
MediaServiceController.Builder.serviceMediaApi(ServiceMediaApi) (or
MediaServiceController.enable(androidx.appcompat.app.AppCompatActivity, com.jwplayer.pub.api.JWPlayer, com.jwplayer.pub.api.background.ServiceMediaApi)) to change what the notification, lock screen and media
buttons do: onPlay(), onPause(), onSeekTo(long), onSkipToNext(),
onSkipToPrevious(), onStop(), onSkipToQueueItem(long),
onFastForward() and onRewind() are called, and
getNotificationCapabilities() decides which transport controls are offered.
To add buttons to the notification, override getNotificationButtons(Context) and
onNotificationButtonClick(String):
public List<NotificationButton> getNotificationButtons(Context context) {
List<NotificationButton> buttons = new ArrayList<>(super.getNotificationButtons(context));
buttons.add(new NotificationButton.Builder("like", R.drawable.ic_like, "Like").build());
return buttons;
}
public void onNotificationButtonClick(String id) {
if ("like".equals(id)) { ... }
}
Existing overrides of addNotificationActions(Context, NotificationCompat.Builder)
and getCompactActions() keep working; see those methods for what carries over.
MediaSessionCompat.Callback.onMediaButtonEvent(Intent) is called for media keys the SDK does not handle itself
(anything other than play, pause, play/pause, headset hook, next, previous, skip forward and
back, fast-forward, rewind and stop), when a subclass overrides it. The rest of the
MediaSessionCompat.Callback base class is kept only for source compatibility; it is not
registered with a legacy session.
-
Field Summary
Fields -
Constructor Summary
ConstructorsModifierConstructorDescriptionServiceMediaApi(JWPlayer player) protectedServiceMediaApi(JWPlayer player, BGAFactory factory) -
Method Summary
Modifier and TypeMethodDescriptionvoidaddNotificationActions(android.content.Context context, androidx.core.app.NotificationCompat.Builder builder) Deprecated.android.app.PendingIntentgetActionIntent(android.content.Context context, int mediaKeyEvent) APendingIntentthat sendsmediaKeyEventto the background-audio service, as if a media button had been pressed.int[]Deprecated.Give buttons aNotificationButton.Builder.compactViewIndex(int)ingetNotificationButtons(Context)instead.getNotificationButtons(android.content.Context context) The buttons on the notification, in order, transport controls included.longvoidAsks forgetNotificationButtons(Context)to be read again, when the buttons depend on something other than the player state.voidvoidonNotificationButtonClick(String buttonId) Called on the main thread when a button fromgetNotificationButtons(Context)is tapped.voidonPause()voidonPlay()voidonRewind()voidonSeekTo(long pos) voidvoidvoidonSkipToQueueItem(long id) voidonStop()Called for Stop while playing or buffering.Methods inherited from class android.support.v4.media.session.MediaSessionCompat.Callback
onAddQueueItem, onAddQueueItem, onCommand, onCustomAction, onMediaButtonEvent, onPlayFromMediaId, onPlayFromSearch, onPlayFromUri, onPrepare, onPrepareFromMediaId, onPrepareFromSearch, onPrepareFromUri, onRemoveQueueItem, onRemoveQueueItemAt, onSetCaptioningEnabled, onSetPlaybackSpeed, onSetRating, onSetRating, onSetRepeatMode, onSetShuffleMode
-
Field Details
-
mPlayer
-
-
Constructor Details
-
ServiceMediaApi
-
ServiceMediaApi
-
-
Method Details
-
onPause
public void onPause()- Overrides:
onPausein classandroid.support.v4.media.session.MediaSessionCompat.Callback
-
onPlay
public void onPlay()- Overrides:
onPlayin classandroid.support.v4.media.session.MediaSessionCompat.Callback
-
onSeekTo
public void onSeekTo(long pos) - Overrides:
onSeekToin classandroid.support.v4.media.session.MediaSessionCompat.Callback
-
onSkipToNext
public void onSkipToNext()- Overrides:
onSkipToNextin classandroid.support.v4.media.session.MediaSessionCompat.Callback
-
onSkipToPrevious
public void onSkipToPrevious()- Overrides:
onSkipToPreviousin classandroid.support.v4.media.session.MediaSessionCompat.Callback
-
onStop
public void onStop()Called for Stop while playing or buffering. A Stop that arrives while paused (from dismissing the notification, a Bluetooth or car Stop button, or a media controller) does not call this: the content stays loaded, as it did before, and playback can be resumed.- Overrides:
onStopin classandroid.support.v4.media.session.MediaSessionCompat.Callback
-
onSkipToQueueItem
public void onSkipToQueueItem(long id) - Overrides:
onSkipToQueueItemin classandroid.support.v4.media.session.MediaSessionCompat.Callback
-
onFastForward
public void onFastForward()- Overrides:
onFastForwardin classandroid.support.v4.media.session.MediaSessionCompat.Callback
-
onRewind
public void onRewind()- Overrides:
onRewindin classandroid.support.v4.media.session.MediaSessionCompat.Callback
-
getPlayer
-
getNotificationCapabilities
public long getNotificationCapabilities() -
getNotificationButtons
@NonNull public List<NotificationButton> getNotificationButtons(@NonNull android.content.Context context) The buttons on the notification, in order, transport controls included.The default returns the actions added by
addNotificationActions(Context, NotificationCompat.Builder), with the compact view fromgetCompactActions(): previous, play or pause, and next, followinggetNotificationCapabilities(), or whatever a subclass that overrides those methods adds. To add buttons, callsuperand append to the list it returns. When the list is built withNotificationButtons (or is empty) and has no play/pause, play/pause is added first while the player offers it, so an empty list gives a notification with play/pause only. The plain result of anaddNotificationActionsoverride is rendered exactly as given, as before.Called on the main thread whenever the player state, playlist item or metadata changes, and after
invalidateNotificationButtons(), so the list can follow the state (a "like" button that disables itself, say). Give the same button the same id each time.At most 10 custom buttons are used; the rest are dropped with a warning. In practice 3 to 5 is the most the system shows: extra buttons may not appear at all, depending on the Android version and the device. Android 12 and below show at most 5 actions in the expanded notification, built-in controls and an automatically added play/pause (placed first) included; later ones are dropped, so put the important buttons first. On Android 13 and later, the system media controls lay out the buttons themselves, ignore the compact view, and do not show disabled buttons.
-
onNotificationButtonClick
Called on the main thread when a button fromgetNotificationButtons(Context)is tapped. Not called for a disabled button, nor for an action added byaddNotificationActions(android.content.Context, androidx.core.app.NotificationCompat.Builder), whose ownPendingIntentis sent instead. Does nothing by default. -
invalidateNotificationButtons
public void invalidateNotificationButtons()Asks forgetNotificationButtons(Context)to be read again, when the buttons depend on something other than the player state. Safe from any thread, including fromonNotificationButtonClick: the buttons are read again shortly after, on the main thread. A call made on the main thread from insidegetNotificationButtonsis ignored, since that read already sees the new state. Does nothing while this api is not backing background audio. -
getCompactActions
Deprecated.Give buttons aNotificationButton.Builder.compactViewIndex(int)ingetNotificationButtons(Context)instead. Still honoured for the actions fromaddNotificationActions(android.content.Context, androidx.core.app.NotificationCompat.Builder): the first three entries are used, and each index, into those actions in the order they were added, puts that action at that position in the compact view. An override is honoured exactly; with the default, play/pause is always in the compact view. -
addNotificationActions
@Deprecated public void addNotificationActions(android.content.Context context, androidx.core.app.NotificationCompat.Builder builder) Deprecated.OverridegetNotificationButtons(Context)instead. Still honoured: the SDK calls this on a scratch builder each time it reads the buttons, and turns each added action into a button with the same icon and title, in the same order. Tapping it sends the action's ownPendingIntent, as before; an action with a null intent is shown but does nothing. An action whose intent isgetActionIntent(android.content.Context, int)for a media key becomes the native control for that key. In the notification itself the action's intent is fired directly, as before; from the lock screen, Android 13+ system controls, Bluetooth or Auto the SDK sends it on the user's behalf.An override runs on the main thread on every relevant player event (state, item, metadata changes), so keep it cheap and free of side effects, and return the same
PendingIntents each time (same request code, noFLAG_CANCEL_CURRENT): the SDK identifies an action by its intent and title, so a new intent per call makes the button look new on every refresh. The actions are rendered exactly as added, play/pause only if you add it. Android 12 and below show at most 5 actions in the expanded notification; later ones are dropped, so put the important ones first.Limits: only the actions carry over; everything else set on the builder (text, style, colour, large icon, ...) is ignored, since the notification is built from the media session. The icon must be a drawable resource; an action with any other icon is skipped. Below Android 13 the notification's own buttons fire the intent directly, so an Activity intent opens as before. Android 13+ system media controls, the lock screen, Bluetooth and Auto press the button through the media session instead, and the SDK sends the intent for the user: Android blocks an Activity
PendingIntentstarted that way while the app is in the background (verified on Android 15). Use a broadcast intent, or theonNotificationButtonClick(String)callback, for actions that must work there; a service intent is subject to Android 8+ background start limits when the app is not in the foreground. -
getActionIntent
public android.app.PendingIntent getActionIntent(android.content.Context context, int mediaKeyEvent) APendingIntentthat sendsmediaKeyEventto the background-audio service, as if a media button had been pressed. InsideaddNotificationActions(android.content.Context, androidx.core.app.NotificationCompat.Builder), an action with this intent becomes the native control for that key. Works while background audio is active: it is a plain service start, which Android 8+ refuses for an app in the background with no foreground service. It is deliberately not a foreground-service start: a key that does not start playback (pause, next while paused) would leave the service unpromoted and the app would crash after the foreground-start timeout.
-
getNotificationButtons(Context)instead.