The Cast framework provides queueing classes that support the creation of lists
of [`MediaQueueItem`](https://developers.google.com/cast/docs/reference/android/com/google/android/gms/cast/MediaQueueItem)
instances, which can be built from `MediaInfo` instances such as video or audio
streams, to play sequentially on the receiver. This queue of content items
can be edited, reordered, updated, and so forth.

> [!NOTE]
> **Note:** Review the [Google Cast Autoplay](https://developers.google.com/cast/docs/design_checklist/cast-autoplay.md.txt) for best practices when designing an autoplay/queueing experience for Cast.

The Receiver SDK maintains the queue and responds to operations on the
queue as long as the queue has at least one item currently active (playing or
paused). Senders can join the session and add items to the queue. The receiver
maintains a session for queue items until the last item completes playback or
the sender stops the playback and terminates the session, or until a sender
loads a new queue on the receiver. The receiver does not maintain any
information about terminated queues by default. Once the last item in the queue
finishes, the media session ends and the queue vanishes.

> [!NOTE]
> **Note:** The [`Styled Media Receiver`](https://developers.google.com/cast/docs/styled_receiver.md.txt) and [`Default Media Receiver`](https://developers.google.com/cast/docs/receiver_apps#default) do not support a queue of images; only a queue of audio or video streams is supported in the styled and default receivers.

## Create and load media queue items

A media queue item is represented in the Cast framework as a
[`MediaQueueItem`](https://developers.google.com/android/reference/com/google/android/gms/cast/MediaQueueItem.md.txt)
instance.
When you create a media queue item, if you are using the [Media Player
Library](https://developers.google.com/cast/docs/reference/player) with adaptive content, you can set the
preload time so that the player can begin buffering the media queue item before
the item ahead of it in the queue finishes playing. Setting the item's autoplay
attribute to true allows the receiver to play it automatically. For example,
you can use a builder pattern to create your media queue item as follows:
Kotlin

```kotlin
val queueItem: MediaQueueItem = MediaQueueItem.Builder(mediaInfo)
    .setAutoplay(true)
    .setPreloadTime(20.0)
    .build()
```
Java

```java
MediaQueueItem queueItem = new MediaQueueItem.Builder(mediaInfo)
  .setAutoplay(true)
  .setPreloadTime(20)
  .build();
```

Load an array of media queue items in the queue by using the appropriate
[`queueLoad`](https://developers.google.com/cast/docs/reference/android/com/google/android/gms/cast/framework/media/RemoteMediaClient#queueLoad(com.google.android.gms.cast.MediaQueueItem%5B%5D,%20int,%20int,%20long,%20org.json.JSONObject))
method of `RemoteMediaClient`.

## Receive media queue status updates

When the receiver loads a media queue item, it assigns a unique ID to the item
which persists for the duration of the session (and the life of the queue). Your
app can learn the status of the queue in terms of which item is currently loaded
(it might not be playing), loading, or preloaded. The
[`MediaStatus`](https://developers.google.com/android/reference/com/google/android/gms/cast/MediaStatus.md.txt#constant-summary)
class provides this status information:

- [`getPreloadedItemId()`](https://developers.google.com/android/reference/com/google/android/gms/cast/MediaStatus.md.txt#getPreloadedItemId()) method - If the next item has been preloaded, returns the preloaded item ID.
- [`getLoadingItemId()`](https://developers.google.com/android/reference/com/google/android/gms/cast/MediaStatus.md.txt#getLoadingItemId()) method - Returns the item ID of the item that is currently loading (but isn't active in the queue) on the receiver.
- [`getCurrentItemId()`](https://developers.google.com/android/reference/com/google/android/gms/cast/MediaStatus.md.txt#getCurrentItemId()) method - Returns the item ID of the item that that was active in the queue (it might not be playing) at the time the media status change happened.
- [`getQueueItems()`](https://developers.google.com/android/reference/com/google/android/gms/cast/MediaStatus.md.txt#getQueueItems()) (**Deprecated, use `MediaQueue` instead** ) method - Returns the list of `MediaQueueItem` instances as an unmodifiable list.

Your app can also get the list of items using the
[`MediaQueue`](https://developers.google.com/android/reference/com/google/android/gms/cast/framework/media/MediaQueue.md.txt)
class. The class is a sparse data model of the media queue. It keeps the list of
item IDs in the queue, which is automatically synchronized with the receiver.
`MediaQueue` doesn't keep all the
[`MediaQueueItem`](https://developers.google.com/android/reference/com/google/android/gms/cast/MediaQueueItem.md.txt)
because it will take too much memory when the queue is very long. Instead, it
fetches the items on demand and keeps an [`LruCache`](https://developer.android.com/reference/android/util/LruCache.html) of
recently accessed items. You can use these methods to access the media queue:

- [`getItemIds()`](https://developers.google.com/android/reference/com/google/android/gms/cast/framework/media/MediaQueue.md.txt#getItemIds()) method - Returns the list of all item IDs in order.
- [`getItemAtIndex()`](https://developers.google.com/android/reference/com/google/android/gms/cast/framework/media/MediaQueue.md.txt#getItemAtIndex(int)) method - Returns the cached item at a given index. If the item is not cached, `MediaQueue` will return `null` and schedule to fetch the item. When the item is fetched, [`MediaQueue.Callback#itemsUpdatedAtIndexes()`](https://developers.google.com/android/reference/com/google/android/gms/cast/framework/media/MediaQueue.Callback.md.txt#itemsUpdatedAtIndexes(int%5B%5D)) will be called, and calling `getItemAtIndex()` with the same ID again will return the item.
- [`fetchMoteItemsRelativeToIndex()`](https://developers.google.com/android/reference/com/google/android/gms/cast/framework/media/MediaQueue.md.txt#getItemIds(int,%0Aint,%20int)) is used when the user scrolls the queue UI to the top or bottom, and your app wants to fetch more items from the cloud.

Use these methods together with the other media status methods to inform your
app about the status of the queue and the items in the queue. In addition to
media status updates from the receiver, your app can listen for changes to the
queue by implementing
[`RemoteMediaClient.Callback`](https://developers.google.com/cast/docs/reference/android/com/google/android/gms/cast/framework/media/RemoteMediaClient.Callback)
and
[`MediaQueue.Callback`](https://developers.google.com/android/reference/com/google/android/gms/cast/framework/media/MediaQueue.Callback.md.txt).

> [!NOTE]
> **Note:** To provide the best user experience, the sender app must show the next autoplay item in the queue in the sender UI.

Also, the Cast SDK provides two utility classes to create UI for queueing.

- [`MediaQueueRecyclerViewAdapter`](https://developers.google.com/cast/docs/reference/android/com/google/android/gms/cast/framework/media/MediaQueueRecyclerViewAdapter), for backing the data of [`RecyclerView`](https://developer.android.com/jetpack/androidx/releases/recyclerview)
- [`MediaQueueListAdapter`](https://developers.google.com/cast/docs/reference/android/com/google/android/gms/cast/framework/media/MediaQueueListAdapter), for backing the data of [`ListAdapter`](https://developer.android.com/reference/android/widget/ListAdapter.html).

For example, to create a `RecyclerView` using `MediaQueueRecyclerViewAdapter`:
Kotlin

```kotlin
class MyRecyclerViewAdapter(mediaQueue: MediaQueue?) :
    MediaQueueRecyclerViewAdapter<MyViewHolder?>(mediaQueue) {
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val item = getItem(position)

        // Update the view using `item`.
        ...
    }
}

class MyViewHolder : RecyclerView.ViewHolder {
    // Implement your own ViewHolder.
    ...
}

fun someMethod() {
    val adapter = MyRecyclerViewAdapter(
        mCastSession.remoteMediaClient.getMediaQueue())
    val recyclerView =
        activity.findViewById(R.id.my_recycler_view_id) as RecyclerView
    recyclerView.adapter = adapter
}
```
Java

```java
public class MyRecyclerViewAdapter extends MediaQueueRecyclerViewAdapter<MyViewHolder> {
    public MyRecyclerViewAdapter(MediaQueue mediaQueue) {
        super(mediaQueue);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
      MediaQueueItem item = getItem(position);

      // Update the view using `item`.
      ...
    }
}

public class MyViewHolder implements RecyclerView.ViewHolder {
  // Implement your own ViewHolder.
  ...
}

public void someMethod() {
    RecyclerView.Adapter adapter = new MyRecyclerViewAdapter(
        mCastSession.getRemoteMediaClient().getMediaQueue());
    RecyclerView recyclerView =
        (RecyclerView) getActivity().findViewById(R.id.my_recycler_view_id);
    recyclerView.setAdapter(adapter);
}
```

## Edit the queue

To operate on the items in the queue, use the queue methods of the
[`RemoteMediaClient`](https://developers.google.com/cast/docs/reference/android/com/google/android/gms/cast/framework/media/RemoteMediaClient#pubmethods)
class. These let you load an array of items into a new queue, insert items into
an existing queue, update the properties of items in the queue, make an item
jump forward or backward in the queue, set the properties of the queue itself
(for example, change the `repeatMode` algorithm that selects the next item),
remove items from the queue, and reorder the items in the queue.