FileDocCategorySizeDatePackage
MediaBrowserService.javaAPI DocAndroid 5.1 API18510Thu Mar 12 22:22:30 GMT 2015android.service.media

MediaBrowserService

public abstract class MediaBrowserService extends android.app.Service
Base class for media browse services.

Media browse services enable applications to browse media content provided by an application and ask the application to start playing it. They may also be used to control content that is already playing by way of a {@link MediaSession}.

To extend this class, you must declare the service in your manifest file with an intent filter with the {@link #SERVICE_INTERFACE} action. For example:

<service android:name=".MyMediaBrowserService"
android:label="@string/service_name" >
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService" />
</intent-filter>
</service>

Fields Summary
private static final String
TAG
private static final boolean
DBG
public static final String
SERVICE_INTERFACE
The {@link Intent} that must be declared as handled by the service.
private final android.util.ArrayMap
mConnections
private final android.os.Handler
mHandler
private ServiceBinder
mBinder
MediaSession.Token
mSession
Constructors Summary
Methods Summary
private voidaddSubscription(java.lang.String id, android.service.media.MediaBrowserService$ConnectionRecord connection)
Save the subscription and if it is a new subscription send the results.

        // Save the subscription
        final boolean added = connection.subscriptions.add(id);

        // If this is a new subscription, send the results
        if (added) {
            performLoadChildren(id, connection);
        }
    
public voiddump(java.io.FileDescriptor fd, java.io.PrintWriter writer, java.lang.String[] args)

    
public MediaSession.TokengetSessionToken()
Gets the session token, or null if it has not yet been created or if it has been destroyed.

        return mSession;
    
private booleanisValidPackage(java.lang.String pkg, int uid)
Return whether the given package is one of the ones that is owned by the uid.

        if (pkg == null) {
            return false;
        }
        final PackageManager pm = getPackageManager();
        final String[] packages = pm.getPackagesForUid(uid);
        final int N = packages.length;
        for (int i=0; i<N; i++) {
            if (packages[i].equals(pkg)) {
                return true;
            }
        }
        return false;
    
public voidnotifyChildrenChanged(java.lang.String parentId)
Notifies all connected media browsers that the children of the specified parent id have changed in some way. This will cause browsers to fetch subscribed content again.

param
parentId The id of the parent media item whose children changed.

        if (parentId == null) {
            throw new IllegalArgumentException("parentId cannot be null in notifyChildrenChanged");
        }
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                for (IBinder binder : mConnections.keySet()) {
                    ConnectionRecord connection = mConnections.get(binder);
                    if (connection.subscriptions.contains(parentId)) {
                        performLoadChildren(parentId, connection);
                    }
                }
            }
        });
    
public android.os.IBinderonBind(android.content.Intent intent)

        if (SERVICE_INTERFACE.equals(intent.getAction())) {
            return mBinder;
        }
        return null;
    
public voidonCreate()

        super.onCreate();
        mBinder = new ServiceBinder();
    
public abstract android.service.media.MediaBrowserService$BrowserRootonGetRoot(java.lang.String clientPackageName, int clientUid, android.os.Bundle rootHints)
Called to get the root information for browsing by a particular client.

The implementation should verify that the client package has permission to access browse media information before returning the root id; it should return null if the client is not allowed to access this information.

param
clientPackageName The package name of the application which is requesting access to browse media.
param
clientUid The uid of the application which is requesting access to browse media.
param
rootHints An optional bundle of service-specific arguments to send to the media browse service when connecting and retrieving the root id for browsing, or null if none. The contents of this bundle may affect the information returned when browsing.

public abstract voidonLoadChildren(java.lang.String parentId, android.service.media.MediaBrowserService$Result result)
Called to get information about the children of a media item.

Implementations must call result.{@link Result#sendResult result.sendResult} with the list of children. If loading the children will be an expensive operation that should be performed on another thread, result.{@link Result#detach result.detach} may be called before returning from this function, and then {@link Result#sendResult result.sendResult} called when the loading is complete.

param
parentId The id of the parent media item whose children are to be queried.
return
The list of children, or null if the id is invalid.

private voidperformLoadChildren(java.lang.String parentId, android.service.media.MediaBrowserService$ConnectionRecord connection)
Call onLoadChildren and then send the results back to the connection.

Callers must make sure that this connection is still connected.

        final Result<List<MediaBrowser.MediaItem>> result
                = new Result<List<MediaBrowser.MediaItem>>(parentId) {
            @Override
            void onResultSent(List<MediaBrowser.MediaItem> list) {
                if (list == null) {
                    throw new IllegalStateException("onLoadChildren sent null list for id "
                            + parentId);
                }
                if (mConnections.get(connection.callbacks.asBinder()) != connection) {
                    if (DBG) {
                        Log.d(TAG, "Not sending onLoadChildren result for connection that has"
                                + " been disconnected. pkg=" + connection.pkg + " id=" + parentId);
                    }
                    return;
                }

                final ParceledListSlice<MediaBrowser.MediaItem> pls = new ParceledListSlice(list);
                try {
                    connection.callbacks.onLoadChildren(parentId, pls);
                } catch (RemoteException ex) {
                    // The other side is in the process of crashing.
                    Log.w(TAG, "Calling onLoadChildren() failed for id=" + parentId
                            + " package=" + connection.pkg);
                }
            }
        };

        onLoadChildren(parentId, result);

        if (!result.isDone()) {
            throw new IllegalStateException("onLoadChildren must call detach() or sendResult()"
                    + " before returning for package=" + connection.pkg + " id=" + parentId);
        }
    
public voidsetSessionToken(MediaSession.Token token)
Call to set the media session.

This should be called as soon as possible during the service's startup. It may only be called once.

        if (token == null) {
            throw new IllegalArgumentException("Session token may not be null.");
        }
        if (mSession != null) {
            throw new IllegalStateException("The session token has already been set.");
        }
        mSession = token;
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                for (IBinder key : mConnections.keySet()) {
                    ConnectionRecord connection = mConnections.get(key);
                    try {
                        connection.callbacks.onConnect(connection.root.getRootId(), token,
                                connection.root.getExtras());
                    } catch (RemoteException e) {
                        Log.w(TAG, "Connection for " + connection.pkg + " is no longer valid.");
                        mConnections.remove(key);
                    }
                }
            }
        });