public class

MediaBrowser

extends MediaController

 java.lang.Object

androidx.media2.session.MediaController

↳androidx.media2.session.MediaBrowser

Gradle dependencies

compile group: 'androidx.media2', name: 'media2-session', version: '1.2.1'

  • groupId: androidx.media2
  • artifactId: media2-session
  • version: 1.2.1

Artifact androidx.media2:media2-session:1.2.1 it located at Google repository (https://maven.google.com/)

Overview

Browses media content offered by a MediaLibraryService.

Summary

Methods
public <any>getChildren(java.lang.String parentId, int page, int pageSize, MediaLibraryService.LibraryParams params)

Gets the list of children under the parent.

public <any>getItem(java.lang.String mediaId)

Gets the media item with the given media id.

public <any>getLibraryRoot(MediaLibraryService.LibraryParams params)

Gets the library root.

public <any>getSearchResult(java.lang.String query, int page, int pageSize, MediaLibraryService.LibraryParams params)

Gets the search result from the library service.

public <any>search(java.lang.String query, MediaLibraryService.LibraryParams params)

Sends a search request to the library service.

public <any>subscribe(java.lang.String parentId, MediaLibraryService.LibraryParams params)

Subscribes to a parent id for the change in its children.

public <any>unsubscribe(java.lang.String parentId)

Unsubscribes for changes to the children of the parent, which was previously subscribed with MediaBrowser.

from MediaControlleraddPlaylistItem, adjustVolume, close, deselectTrack, fastForward, getAllowedCommands, getBufferedPosition, getBufferingState, getConnectedToken, getCurrentMediaItem, getCurrentMediaItemIndex, getCurrentPosition, getDuration, getExtraControllerCallbacks, getNextMediaItemIndex, getPlaybackInfo, getPlaybackSpeed, getPlayerState, getPlaylist, getPlaylistMetadata, getPreviousMediaItemIndex, getRepeatMode, getSelectedTrack, getSessionActivity, getShuffleMode, getTracks, getVideoSize, isConnected, movePlaylistItem, notifyAllControllerCallbacks, pause, play, prepare, registerExtraCallback, removePlaylistItem, replacePlaylistItem, rewind, seekTo, selectTrack, sendCustomCommand, setMediaItem, setMediaUri, setPlaybackSpeed, setPlaylist, setRating, setRepeatMode, setShuffleMode, setSurface, setTimeDiff, setVolumeTo, skipBackward, skipForward, skipToNextPlaylistItem, skipToPlaylistItem, skipToPreviousPlaylistItem, unregisterExtraCallback, updatePlaylistMetadata
from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Methods

public <any> getLibraryRoot(MediaLibraryService.LibraryParams params)

Gets the library root.

If it's successfully completed, LibraryResult.getMediaItem() will return the library root.

Parameters:

params: library params getting root

See also: LibraryResult.getMediaItem()

public <any> subscribe(java.lang.String parentId, MediaLibraryService.LibraryParams params)

Subscribes to a parent id for the change in its children. When there's a change, MediaBrowser.BrowserCallback will be called with the library params. You should call MediaBrowser to get the items under the parent.

Parameters:

parentId: non-empty parent id
params: library params

public <any> unsubscribe(java.lang.String parentId)

Unsubscribes for changes to the children of the parent, which was previously subscribed with MediaBrowser.

This unsubscribes all previous subscriptions with the parent id, regardless of the library param that was previously sent to the library service.

Parameters:

parentId: non-empty parent id

public <any> getChildren(java.lang.String parentId, int page, int pageSize, MediaLibraryService.LibraryParams params)

Gets the list of children under the parent.

If it's successfully completed, LibraryResult.getMediaItems() will return the list of children.

Parameters:

parentId: non-empty parent id for getting the children
page: page number to get the result. Starts from 0
pageSize: page size. Should be greater than or equal to 1
params: library params

See also: LibraryResult.getMediaItems()

public <any> getItem(java.lang.String mediaId)

Gets the media item with the given media id.

If it's successfully completed, LibraryResult.getMediaItem() will return the media item.

Parameters:

mediaId: non-empty media id for specifying the item

See also: LibraryResult.getMediaItem()

public <any> search(java.lang.String query, MediaLibraryService.LibraryParams params)

Sends a search request to the library service.

Returned LibraryResult will only tell whether the attempt to search was successful. For getting the search result, wait for MediaBrowser.BrowserCallback being called and call MediaBrowser} for getting the result.

Parameters:

query: non-empty search query
params: library params

See also: MediaBrowser.BrowserCallback, MediaBrowser

public <any> getSearchResult(java.lang.String query, int page, int pageSize, MediaLibraryService.LibraryParams params)

Gets the search result from the library service.

If it's successfully completed, LibraryResult.getMediaItems() will return the search result.

Parameters:

query: non-empty search query that you've specified with MediaBrowser.
page: page number to get search result. Starts from 0
pageSize: page size. Should be greater or equal to 1
params: library params

See also: LibraryResult.getMediaItems()

Source

/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.media2.session;

import android.content.Context;
import android.os.Bundle;
import android.support.v4.media.session.MediaSessionCompat;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.media2.session.MediaLibraryService.LibraryParams;

import com.google.common.util.concurrent.ListenableFuture;

import java.util.concurrent.Executor;

/**
 * Browses media content offered by a {@link MediaLibraryService}.
 */
public class MediaBrowser extends MediaController {
    static final String TAG = "MediaBrowser";
    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    /**
     * Callback to listen events from {@link MediaLibraryService}.
     */
    public static class BrowserCallback extends MediaController.ControllerCallback {
        /**
         * Called when there's change in the parent's children after you've subscribed to the parent
         * with {@link #subscribe}.
         * <p>
         * This API is called when the library service called
         * {@link MediaLibraryService.MediaLibrarySession#notifyChildrenChanged} for the parent.
         *
         * @param browser the browser for this event
         * @param parentId non-empty parent id that you've specified with
         *                 {@link #subscribe(String, LibraryParams)}
         * @param itemCount number of children
         * @param params library params from the library service. Can be differ from params
         *               that you've specified with {@link #subscribe(String, LibraryParams)}.
         */
        public void onChildrenChanged(@NonNull MediaBrowser browser, @NonNull String parentId,
                @IntRange(from = 0) int itemCount, @Nullable LibraryParams params) { }

        /**
         * Called when there's change in the search result requested by the previous
         * {@link MediaBrowser#search(String, LibraryParams)}.
         *
         * @param browser the browser for this event
         * @param query non-empty search query that you've specified with
         *              {@link #search(String, LibraryParams)}
         * @param itemCount The item count for the search result
         * @param params library params from the library service. Can be differ from params
         *               that you've specified with {@link #search(String, LibraryParams)}.
         */
        public void onSearchResultChanged(@NonNull MediaBrowser browser, @NonNull String query,
                @IntRange(from = 0) int itemCount, @Nullable LibraryParams params) { }
    }

    /**
     * Creates a {@link MediaBrowser} from the {@link SessionToken}.
     *
     * @param context context
     * @param token token to connect to
     * @param executor executor to run callbacks on
     * @param callback controller callback to receive changes in
     */
    MediaBrowser(@NonNull Context context, @NonNull SessionToken token,
            @Nullable Bundle connectionHints, @Nullable Executor executor,
            @Nullable BrowserCallback callback) {
        super(context, token, connectionHints, executor, callback);
    }

    MediaBrowser(@NonNull Context context, @NonNull MediaSessionCompat.Token token,
            @Nullable Bundle connectionHints, @Nullable Executor executor,
            @Nullable BrowserCallback callback) {
        super(context, token, connectionHints, executor, callback);
    }

    @Override
    MediaBrowserImpl createImpl(@NonNull Context context, @NonNull SessionToken token,
            @Nullable Bundle connectionHints) {
        if (token.isLegacySession()) {
            return new MediaBrowserImplLegacy(context, this, token);
        } else {
            return new MediaBrowserImplBase(context, this, token, connectionHints);
        }
    }

    @Override
    MediaBrowserImpl getImpl() {
        return (MediaBrowserImpl) super.getImpl();
    }

    /**
     * Gets the library root.
     * <p>
     * If it's successfully completed, {@link LibraryResult#getMediaItem()} will return the library
     * root.
     *
     * @param params library params getting root
     * @see LibraryResult#getMediaItem()
     */
    @NonNull
    public ListenableFuture<LibraryResult> getLibraryRoot(@Nullable final LibraryParams params) {
        if (isConnected()) {
            return getImpl().getLibraryRoot(params);
        }
        return createDisconnectedFuture();
    }

    /**
     * Subscribes to a parent id for the change in its children. When there's a change,
     * {@link BrowserCallback#onChildrenChanged(MediaBrowser, String, int, LibraryParams)} will be
     * called with the library params. You should call
     * {@link #getChildren(String, int, int, LibraryParams)}
     * to get the items under the parent.
     *
     * @param parentId non-empty parent id
     * @param params library params
     */
    @NonNull
    public ListenableFuture<LibraryResult> subscribe(@NonNull String parentId,
            @Nullable LibraryParams params) {
        if (TextUtils.isEmpty(parentId)) {
            throw new IllegalArgumentException("parentId shouldn't be empty");
        }
        if (isConnected()) {
            return getImpl().subscribe(parentId, params);
        }
        return createDisconnectedFuture();
    }

    /**
     * Unsubscribes for changes to the children of the parent, which was previously subscribed with
     * {@link #subscribe(String, LibraryParams)}.
     * <p>
     * This unsubscribes all previous subscriptions with the parent id, regardless of the library
     * param that was previously sent to the library service.
     *
     * @param parentId non-empty parent id
     */
    @NonNull
    public ListenableFuture<LibraryResult> unsubscribe(@NonNull String parentId) {
        if (TextUtils.isEmpty(parentId)) {
            throw new IllegalArgumentException("parentId shouldn't be empty");
        }
        if (isConnected()) {
            return getImpl().unsubscribe(parentId);
        }
        return createDisconnectedFuture();
    }

    /**
     * Gets the list of children under the parent.
     * <p>
     * If it's successfully completed, {@link LibraryResult#getMediaItems()} will return the list
     * of children.
     *
     * @param parentId non-empty parent id for getting the children
     * @param page page number to get the result. Starts from {@code 0}
     * @param pageSize page size. Should be greater than or equal to {@code 1}
     * @param params library params
     * @see LibraryResult#getMediaItems()
     */
    @NonNull
    public ListenableFuture<LibraryResult> getChildren(@NonNull String parentId,
            @IntRange(from = 0) int page, @IntRange(from = 1) int pageSize,
            @Nullable LibraryParams params) {
        if (TextUtils.isEmpty(parentId)) {
            throw new IllegalArgumentException("parentId shouldn't be empty");
        }
        if (page < 0) {
            throw new IllegalArgumentException("page shouldn't be negative");
        }
        if (pageSize < 1) {
            throw new IllegalArgumentException("pageSize shouldn't be less than 1");
        }
        if (isConnected()) {
            return getImpl().getChildren(parentId, page, pageSize, params);
        }
        return createDisconnectedFuture();
    }

    /**
     * Gets the media item with the given media id.
     * <p>
     * If it's successfully completed, {@link LibraryResult#getMediaItem()} will return the media
     * item.
     *
     * @param mediaId non-empty media id for specifying the item
     * @see LibraryResult#getMediaItem()
     */
    @NonNull
    public ListenableFuture<LibraryResult> getItem(@NonNull final String mediaId) {
        if (TextUtils.isEmpty(mediaId)) {
            throw new IllegalArgumentException("mediaId shouldn't be empty");
        }
        if (isConnected()) {
            return getImpl().getItem(mediaId);
        }
        return createDisconnectedFuture();
    }

    /**
     * Sends a search request to the library service.
     * <p>
     * Returned {@link LibraryResult} will only tell whether the attempt to search was successful.
     * For getting the search result, wait for
     * {@link BrowserCallback#onSearchResultChanged(MediaBrowser, String, int, LibraryParams)}
     * being called and call {@link #getSearchResult(String, int, int, LibraryParams)}}
     * for getting the result.
     *
     * @param query non-empty search query
     * @param params library params
     * @see BrowserCallback#onSearchResultChanged(MediaBrowser, String, int, LibraryParams)
     * @see #getSearchResult(String, int, int, LibraryParams)
     */
    @NonNull
    public ListenableFuture<LibraryResult> search(@NonNull String query,
            @Nullable LibraryParams params) {
        if (TextUtils.isEmpty(query)) {
            throw new IllegalArgumentException("query shouldn't be empty");
        }
        if (isConnected()) {
            return getImpl().search(query, params);
        }
        return createDisconnectedFuture();
    }

    /**
     * Gets the search result from the library service.
     * <p>
     * If it's successfully completed, {@link LibraryResult#getMediaItems()} will return the search
     * result.
     *
     * @param query non-empty search query that you've specified with
     *              {@link #search(String, LibraryParams)}.
     * @param page page number to get search result. Starts from {@code 0}
     * @param pageSize page size. Should be greater or equal to {@code 1}
     * @param params library params
     * @see LibraryResult#getMediaItems()
     */
    @NonNull
    public ListenableFuture<LibraryResult> getSearchResult(@NonNull final String query,
            @IntRange(from = 0) int page, @IntRange(from = 1) int pageSize,
            @Nullable final LibraryParams params) {
        if (TextUtils.isEmpty(query)) {
            throw new IllegalArgumentException("query shouldn't be empty");
        }
        if (page < 0) {
            throw new IllegalArgumentException("page shouldn't be negative");
        }
        if (pageSize < 1) {
            throw new IllegalArgumentException("pageSize shouldn't be less than 1");
        }
        if (isConnected()) {
            return getImpl().getSearchResult(query, page, pageSize, params);
        }
        return createDisconnectedFuture();
    }

    void notifyBrowserCallback(final BrowserCallbackRunnable callbackRunnable) {
        if (mPrimaryCallback != null && mPrimaryCallbackExecutor != null) {
            mPrimaryCallbackExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    callbackRunnable.run((BrowserCallback) mPrimaryCallback);
                }
            });
        }
    }

    interface BrowserCallbackRunnable {
        void run(@NonNull BrowserCallback callback);
    }

    /**
     * Builder for {@link MediaBrowser}.
     * <p>
     * To set the token of the session for the controller to connect to, one of the
     * {@link #setSessionToken(SessionToken)} or
     * {@link #setSessionCompatToken(MediaSessionCompat.Token)} should be called.
     * Otherwise, the {@link #build()} will throw an {@link IllegalArgumentException}.
     * <p>
     * Any incoming event from the {@link MediaSession} will be handled on the callback
     * executor.
     */
    public static final class Builder extends
            BuilderBase<MediaBrowser, MediaBrowser.Builder, BrowserCallback> {
        public Builder(@NonNull Context context) {
            super(context);
        }

        @Override
        @NonNull
        public Builder setSessionToken(@NonNull SessionToken token) {
            return super.setSessionToken(token);
        }

        @Override
        @NonNull
        public Builder setSessionCompatToken(@NonNull MediaSessionCompat.Token compatToken) {
            return super.setSessionCompatToken(compatToken);
        }

        @Override
        @NonNull
        public Builder setControllerCallback(@NonNull Executor executor,
                @NonNull BrowserCallback callback) {
            return super.setControllerCallback(executor, callback);
        }

        @Override
        @NonNull
        public Builder setConnectionHints(@NonNull Bundle connectionHints) {
            return super.setConnectionHints(connectionHints);
        }

        /**
         * Builds a {@link MediaBrowser}.
         *
         * @throws IllegalArgumentException if both {@link SessionToken} and
         * {@link MediaSessionCompat.Token} are not set.
         *
         * @return a new browser
         */
        @Override
        @NonNull
        public MediaBrowser build() {
            if (mToken == null && mCompatToken == null) {
                throw new IllegalArgumentException("token and compat token shouldn't be both null");
            }
            if (mToken != null) {
                return new MediaBrowser(mContext, mToken, mConnectionHints,
                        mCallbackExecutor, (BrowserCallback) mCallback);
            } else {
                return new MediaBrowser(mContext, mCompatToken, mConnectionHints,
                        mCallbackExecutor, (BrowserCallback) mCallback);
            }
        }
    }

    private static ListenableFuture<LibraryResult> createDisconnectedFuture() {
        return LibraryResult.createFutureWithResult(
                LibraryResult.RESULT_ERROR_SESSION_DISCONNECTED);
    }

    interface MediaBrowserImpl extends MediaControllerImpl {
        ListenableFuture<LibraryResult> getLibraryRoot(
                @Nullable LibraryParams rootHints);
        ListenableFuture<LibraryResult> subscribe(@NonNull String parentId,
                @Nullable LibraryParams params);
        ListenableFuture<LibraryResult> unsubscribe(@NonNull String parentId);
        ListenableFuture<LibraryResult> getChildren(@NonNull String parentId, int page,
                int pageSize, @Nullable LibraryParams params);
        ListenableFuture<LibraryResult> getItem(@NonNull String mediaId);
        ListenableFuture<LibraryResult> search(@NonNull String query,
                @Nullable LibraryParams params);
        ListenableFuture<LibraryResult> getSearchResult(@NonNull String query, int page,
                int pageSize, @Nullable LibraryParams params);
    }
}