Queueing

The queue model in Cast is different from that in MediaSession. The Cast Connect library doesn't support reading a queue provided by MediaSession.

Handle Queue Loading and Setting the Queue Information

Queue loading is done in the same way as loading single items (via starting activity with an intent). You need to use our client library to parse the intent into a MediaLoadRequestData. The MediaQueueData field contains the queue information to be loaded.

private void handleCastLoad(MediaLoadRequestData requestData) {
  if (requestData.getQueueData()) {
    // If MediaQueueData is specified, this is a queue load request.
    myPlayer.load(
        requestData.getQueueData().getItems().get(0));

    // Set media status.
    castReceiverContext.getMediaManager()
        .setDataFromLoad(requestData) // This clears all status overrides.
                                      // The queue information is updated with
                                      // the MediaQueueData in the request.
        ...;

    mediaSession.setPlaybackState(...);
  }
}

Changing the Queue

When there are changes to the queue (such as from queueInsert()), you can use MediaQueueManager to update the queue. If you are creating new queue items, be sure to set the item ID by calling setItemId() on the builder using MediaQueueManager.autoGenerateItemId() to generate the item ID. Items in the queue loaded via setDataFromLoad() already have their item IDs set.

MediaManager mediaManager = castReceiverContext.getMediaManager();

MediaQueueManager mediaQueueManager = mediaManager.getMediaQueueManager();

mediaQueueManager.getQueueItems().add(/* position= */ index, mediaQueueItem);

mediaManager.broadcastMediaStatus();

Android TV apps should also handle onQueueUpdate() callback to support jumping to queue items and skip next/previous:

public class MyMediaCommandCallback extends MediaCommandCallback {
  @Override
  public Task<Void> onQueueUpdate(
      QueueUpdateRequestData queueUpdateRequestData) {
    ...
    int newItemId = MediaQueueItem.INVALID_ITEM_ID;
    if (queueUpdateRequestData.getJump() != null) {
      newItemId = myGetRelativeItemId(queueUpdateRequestData.getJump());
    } else if (queueUpdateRequestData.getCurrentItemId() != null) {
      newItemId = queueUpdateRequestData.getCurrentItemId();
    }

    if (newItemId != MediaQueueItem.INVALID_ITEM_ID) {
      castReceiverContext.getMediaManager().getMediaQueueManager()
          .setCurrentItemId(newItemId);
      castReceiverContext.getMediaManager().broadcastMediaStatus();
    }
}

MediaManager mediaManager =
    CastReceiverContext.getInstance().getMediaManager();
mediaManager.setMediaCommandCallback(new MyMediaCommandCallback());

You may also want to implement queue-related transport control callbacks, such as onSkipToNext(), onSkipToPrevious(), or onSkipToQueueItem().

public MyMediaSessionCallback extends MediaSessionCompat.Callback {

  public void onSkipToNext() {
    // Skip to next item in queue
    ...
  }

  public void onSkipToPrevious() {
    // Skip to previous item in queue
    ...
  }

  public void onSkipToQueueItem (long pos) {
    // Skip to specified queue item
    ...
  }
  ...
}

mediaSession.setCallback(new MyMediaSessionCallback());