FileDocCategorySizeDatePackage
MediaSession.javaAPI DocAndroid 5.1 API43019Thu Mar 12 22:22:30 GMT 2015android.media.session

MediaSession

public final class MediaSession extends Object
Allows interaction with media controllers, volume keys, media buttons, and transport controls.

A MediaSession should be created when an app wants to publish media playback information or handle media keys. In general an app only needs one session for all playback, though multiple sessions can be created to provide finer grain controls of media.

Once a session is created the owner of the session may pass its {@link #getSessionToken() session token} to other processes to allow them to create a {@link MediaController} to interact with the session.

To receive commands, media keys, and other events a {@link Callback} must be set with {@link #setCallback(Callback)} and {@link #setActive(boolean) setActive(true)} must be called.

When an app is finished performing playback it must call {@link #release()} to clean up the session and notify any controllers.

MediaSession objects are thread safe.

Fields Summary
private static final String
TAG
public static final int
FLAG_HANDLES_MEDIA_BUTTONS
Set this flag on the session to indicate that it can handle media button events.
public static final int
FLAG_HANDLES_TRANSPORT_CONTROLS
Set this flag on the session to indicate that it handles transport control commands through its {@link Callback}.
public static final int
FLAG_EXCLUSIVE_GLOBAL_PRIORITY
System only flag for a session that needs to have priority over all other sessions. This flag ensures this session will receive media button events regardless of the current ordering in the system.
private final Object
mLock
private final int
mMaxBitmapSize
private final Token
mSessionToken
private final MediaController
mController
private final ISession
mBinder
private final CallbackStub
mCbStub
private CallbackMessageHandler
mCallback
private android.media.VolumeProvider
mVolumeProvider
private PlaybackState
mPlaybackState
private boolean
mActive
Constructors Summary
public MediaSession(android.content.Context context, String tag)
Creates a new session. The session will automatically be registered with the system but will not be published until {@link #setActive(boolean) setActive(true)} is called. You must call {@link #release()} when finished with the session.

param
context The context to use to create the session.
param
tag A short name for debugging purposes.


                                                             
           
        this(context, tag, UserHandle.myUserId());
    
public MediaSession(android.content.Context context, String tag, int userId)
Creates a new session as the specified user. To create a session as a user other than your own you must hold the {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission.

param
context The context to use to create the session.
param
tag A short name for debugging purposes.
param
userId The user id to create the session as.
hide

        if (context == null) {
            throw new IllegalArgumentException("context cannot be null.");
        }
        if (TextUtils.isEmpty(tag)) {
            throw new IllegalArgumentException("tag cannot be null or empty");
        }
        mMaxBitmapSize = context.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.config_mediaMetadataBitmapMaxSize);
        mCbStub = new CallbackStub(this);
        MediaSessionManager manager = (MediaSessionManager) context
                .getSystemService(Context.MEDIA_SESSION_SERVICE);
        try {
            mBinder = manager.createSession(mCbStub, tag, userId);
            mSessionToken = new Token(mBinder.getController());
            mController = new MediaController(context, mSessionToken);
        } catch (RemoteException e) {
            throw new RuntimeException("Remote error creating session.", e);
        }
    
Methods Summary
private voiddispatchAdjustVolume(int direction)

        postToCallback(CallbackMessageHandler.MSG_ADJUST_VOLUME, direction);
    
private voiddispatchCustomAction(java.lang.String action, android.os.Bundle args)

        postToCallback(CallbackMessageHandler.MSG_CUSTOM_ACTION, action, args);
    
private voiddispatchFastForward()

        postToCallback(CallbackMessageHandler.MSG_FAST_FORWARD);
    
private voiddispatchMediaButton(android.content.Intent mediaButtonIntent)

        postToCallback(CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent);
    
private voiddispatchNext()

        postToCallback(CallbackMessageHandler.MSG_NEXT);
    
private voiddispatchPause()

        postToCallback(CallbackMessageHandler.MSG_PAUSE);
    
private voiddispatchPlay()

        postToCallback(CallbackMessageHandler.MSG_PLAY);
    
private voiddispatchPlayFromMediaId(java.lang.String mediaId, android.os.Bundle extras)

        postToCallback(CallbackMessageHandler.MSG_PLAY_MEDIA_ID, mediaId, extras);
    
private voiddispatchPlayFromSearch(java.lang.String query, android.os.Bundle extras)

        postToCallback(CallbackMessageHandler.MSG_PLAY_SEARCH, query, extras);
    
private voiddispatchPrevious()

        postToCallback(CallbackMessageHandler.MSG_PREVIOUS);
    
private voiddispatchRate(android.media.Rating rating)

        postToCallback(CallbackMessageHandler.MSG_RATE, rating);
    
private voiddispatchRewind()

        postToCallback(CallbackMessageHandler.MSG_REWIND);
    
private voiddispatchSeekTo(long pos)

        postToCallback(CallbackMessageHandler.MSG_SEEK_TO, pos);
    
private voiddispatchSetVolumeTo(int volume)

        postToCallback(CallbackMessageHandler.MSG_SET_VOLUME, volume);
    
private voiddispatchSkipToItem(long id)

        postToCallback(CallbackMessageHandler.MSG_SKIP_TO_ITEM, id);
    
private voiddispatchStop()

        postToCallback(CallbackMessageHandler.MSG_STOP);
    
public MediaControllergetController()
Get a controller for this session. This is a convenience method to avoid having to cache your own controller in process.

return
A controller for this session.

        return mController;
    
public android.media.session.MediaSession$TokengetSessionToken()
Retrieve a token object that can be used by apps to create a {@link MediaController} for interacting with this session. The owner of the session is responsible for deciding how to distribute these tokens.

return
A token that can be used to create a MediaController for this session

        return mSessionToken;
    
public booleanisActive()
Get the current active state of this session.

return
True if the session is active, false otherwise.

        return mActive;
    
public static booleanisActiveState(int state)
Return true if this is considered an active playback state.

hide

        switch (state) {
            case PlaybackState.STATE_FAST_FORWARDING:
            case PlaybackState.STATE_REWINDING:
            case PlaybackState.STATE_SKIPPING_TO_PREVIOUS:
            case PlaybackState.STATE_SKIPPING_TO_NEXT:
            case PlaybackState.STATE_BUFFERING:
            case PlaybackState.STATE_CONNECTING:
            case PlaybackState.STATE_PLAYING:
                return true;
        }
        return false;
    
public voidnotifyRemoteVolumeChanged(android.media.VolumeProvider provider)
Notify the system that the remote volume changed.

param
provider The provider that is handling volume changes.
hide

        synchronized (mLock) {
            if (provider == null || provider != mVolumeProvider) {
                Log.w(TAG, "Received update from stale volume provider");
                return;
            }
        }
        try {
            mBinder.setCurrentVolume(provider.getCurrentVolume());
        } catch (RemoteException e) {
            Log.e(TAG, "Error in notifyVolumeChanged", e);
        }
    
private voidpostCommand(java.lang.String command, android.os.Bundle args, android.os.ResultReceiver resultCb)

        Command cmd = new Command(command, args, resultCb);
        postToCallback(CallbackMessageHandler.MSG_COMMAND, cmd);
    
private voidpostToCallback(int what)

        postToCallback(what, null);
    
private voidpostToCallback(int what, java.lang.Object obj)

        postToCallback(what, obj, null);
    
private voidpostToCallback(int what, java.lang.Object obj, android.os.Bundle extras)

        synchronized (mLock) {
            if (mCallback != null) {
                mCallback.post(what, obj, extras);
            }
        }
    
public voidrelease()
This must be called when an app has finished performing playback. If playback is expected to start again shortly the session can be left open, but it must be released if your activity or service is being destroyed.

        try {
            mBinder.destroy();
        } catch (RemoteException e) {
            Log.wtf(TAG, "Error releasing session: ", e);
        }
    
public voidsendSessionEvent(java.lang.String event, android.os.Bundle extras)
Send a proprietary event to all MediaControllers listening to this Session. It's up to the Controller/Session owner to determine the meaning of any events.

param
event The name of the event to send
param
extras Any extras included with the event

        if (TextUtils.isEmpty(event)) {
            throw new IllegalArgumentException("event cannot be null or empty");
        }
        try {
            mBinder.sendEvent(event, extras);
        } catch (RemoteException e) {
            Log.wtf(TAG, "Error sending event", e);
        }
    
public voidsetActive(boolean active)
Set if this session is currently active and ready to receive commands. If set to false your session's controller may not be discoverable. You must set the session to active before it can start receiving media button events or transport commands.

param
active Whether this session is active or not.

        if (mActive == active) {
            return;
        }
        try {
            mBinder.setActive(active);
            mActive = active;
        } catch (RemoteException e) {
            Log.wtf(TAG, "Failure in setActive.", e);
        }
    
public voidsetCallback(android.media.session.MediaSession$Callback callback)
Set the callback to receive updates for the MediaSession. This includes media button events and transport controls. The caller's thread will be used to post updates.

Set the callback to null to stop receiving updates.

param
callback The callback object

        setCallback(callback, null);
    
public voidsetCallback(android.media.session.MediaSession$Callback callback, android.os.Handler handler)
Set the callback to receive updates for the MediaSession. This includes media button events and transport controls.

Set the callback to null to stop receiving updates.

param
callback The callback to receive updates on.
param
handler The handler that events should be posted on.

        synchronized (mLock) {
            if (callback == null) {
                if (mCallback != null) {
                    mCallback.mCallback.mSession = null;
                }
                mCallback = null;
                return;
            }
            if (mCallback != null) {
                // We're updating the callback, clear the session from the old
                // one.
                mCallback.mCallback.mSession = null;
            }
            if (handler == null) {
                handler = new Handler();
            }
            callback.mSession = this;
            CallbackMessageHandler msgHandler = new CallbackMessageHandler(handler.getLooper(),
                    callback);
            mCallback = msgHandler;
        }
    
public voidsetExtras(android.os.Bundle extras)
Set some extras that can be associated with the {@link MediaSession}. No assumptions should be made as to how a {@link MediaController} will handle these extras. Keys should be fully qualified (e.g. com.example.MY_EXTRA) to avoid conflicts.

param
extras The extras associated with the {@link MediaSession}.

        try {
            mBinder.setExtras(extras);
        } catch (RemoteException e) {
            Log.wtf("Dead object in setExtras.", e);
        }
    
public voidsetFlags(int flags)
Set any flags for the session.

param
flags The flags to set for this session.

        try {
            mBinder.setFlags(flags);
        } catch (RemoteException e) {
            Log.wtf(TAG, "Failure in setFlags.", e);
        }
    
public voidsetMediaButtonReceiver(android.app.PendingIntent mbr)
Set a pending intent for your media button receiver to allow restarting playback after the session has been stopped. If your app is started in this way an {@link Intent#ACTION_MEDIA_BUTTON} intent will be sent via the pending intent.

param
mbr The {@link PendingIntent} to send the media button event to.

        try {
            mBinder.setMediaButtonReceiver(mbr);
        } catch (RemoteException e) {
            Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e);
        }
    
public voidsetMetadata(android.media.MediaMetadata metadata)
Update the current metadata. New metadata can be created using {@link android.media.MediaMetadata.Builder}.

param
metadata The new metadata

        if (metadata != null ) {
            metadata = (new MediaMetadata.Builder(metadata, mMaxBitmapSize)).build();
        }
        try {
            mBinder.setMetadata(metadata);
        } catch (RemoteException e) {
            Log.wtf(TAG, "Dead object in setPlaybackState.", e);
        }
    
public voidsetPlaybackState(PlaybackState state)
Update the current playback state.

param
state The current state of playback

        mPlaybackState = state;
        try {
            mBinder.setPlaybackState(state);
        } catch (RemoteException e) {
            Log.wtf(TAG, "Dead object in setPlaybackState.", e);
        }
    
public voidsetPlaybackToLocal(android.media.AudioAttributes attributes)
Set the attributes for this session's audio. This will affect the system's volume handling for this session. If {@link #setPlaybackToRemote} was previously called it will stop receiving volume commands and the system will begin sending volume changes to the appropriate stream.

By default sessions use attributes for media.

param
attributes The {@link AudioAttributes} for this session's audio.

        if (attributes == null) {
            throw new IllegalArgumentException("Attributes cannot be null for local playback.");
        }
        try {
            mBinder.setPlaybackToLocal(attributes);
        } catch (RemoteException e) {
            Log.wtf(TAG, "Failure in setPlaybackToLocal.", e);
        }
    
public voidsetPlaybackToRemote(android.media.VolumeProvider volumeProvider)
Configure this session to use remote volume handling. This must be called to receive volume button events, otherwise the system will adjust the appropriate stream volume for this session. If {@link #setPlaybackToLocal} was previously called the system will stop handling volume changes for this session and pass them to the volume provider instead.

param
volumeProvider The provider that will handle volume changes. May not be null.

        if (volumeProvider == null) {
            throw new IllegalArgumentException("volumeProvider may not be null!");
        }
        synchronized (mLock) {
            mVolumeProvider = volumeProvider;
        }
        volumeProvider.setCallback(new VolumeProvider.Callback() {
            @Override
            public void onVolumeChanged(VolumeProvider volumeProvider) {
                notifyRemoteVolumeChanged(volumeProvider);
            }
        });

        try {
            mBinder.setPlaybackToRemote(volumeProvider.getVolumeControl(),
                    volumeProvider.getMaxVolume());
            mBinder.setCurrentVolume(volumeProvider.getCurrentVolume());
        } catch (RemoteException e) {
            Log.wtf(TAG, "Failure in setPlaybackToRemote.", e);
        }
    
public voidsetQueue(java.util.List queue)
Update the list of items in the play queue. It is an ordered list and should contain the current item, and previous or upcoming items if they exist. Specify null if there is no current play queue.

The queue should be of reasonable size. If the play queue is unbounded within your app, it is better to send a reasonable amount in a sliding window instead.

param
queue A list of items in the play queue.

        try {
            mBinder.setQueue(queue == null ? null : new ParceledListSlice<QueueItem>(queue));
        } catch (RemoteException e) {
            Log.wtf("Dead object in setQueue.", e);
        }
    
public voidsetQueueTitle(java.lang.CharSequence title)
Set the title of the play queue. The UI should display this title along with the play queue itself. e.g. "Play Queue", "Now Playing", or an album name.

param
title The title of the play queue.

        try {
            mBinder.setQueueTitle(title);
        } catch (RemoteException e) {
            Log.wtf("Dead object in setQueueTitle.", e);
        }
    
public voidsetRatingType(int type)
Set the style of rating used by this session. Apps trying to set the rating should use this style. Must be one of the following:
  • {@link Rating#RATING_NONE}
  • {@link Rating#RATING_3_STARS}
  • {@link Rating#RATING_4_STARS}
  • {@link Rating#RATING_5_STARS}
  • {@link Rating#RATING_HEART}
  • {@link Rating#RATING_PERCENTAGE}
  • {@link Rating#RATING_THUMB_UP_DOWN}

        try {
            mBinder.setRatingType(type);
        } catch (RemoteException e) {
            Log.e(TAG, "Error in setRatingType.", e);
        }
    
public voidsetSessionActivity(android.app.PendingIntent pi)
Set an intent for launching UI for this Session. This can be used as a quick link to an ongoing media screen. The intent should be for an activity that may be started using {@link Activity#startActivity(Intent)}.

param
pi The intent to launch to show UI for this Session.

        try {
            mBinder.setLaunchPendingIntent(pi);
        } catch (RemoteException e) {
            Log.wtf(TAG, "Failure in setLaunchPendingIntent.", e);
        }