From 55b38fadd0d815450a3461f143c525429ab6b0f5 Mon Sep 17 00:00:00 2001 From: Joe Fernandez Date: Wed, 26 Mar 2014 23:11:31 -0700 Subject: docs: MediaRouteProvider Developer Guide Change-Id: I04e63a8972e29d67af6035462fd2808a562ac241 --- docs/html/guide/guide_toc.cs | 5 +- docs/html/guide/topics/media/mediarouteprovider.jd | 453 +++++++++++++++++++++ docs/html/guide/topics/media/mediarouter.jd | 38 +- .../mediarouter/media-route-provider-framework.png | Bin 0 -> 23424 bytes .../._data.plist | Bin 0 -> 4096 bytes .../._image1.png | Bin 0 -> 4096 bytes .../data.plist | Bin 0 -> 3986 bytes .../image1.png | Bin 0 -> 12532 bytes .../media-router-framework.graffle/data.plist | Bin 0 -> 4218 bytes .../media-router-framework.graffle/image1.png | Bin 0 -> 12532 bytes 10 files changed, 479 insertions(+), 17 deletions(-) create mode 100644 docs/html/guide/topics/media/mediarouteprovider.jd create mode 100644 docs/html/images/mediarouter/media-route-provider-framework.png create mode 100644 docs/image_sources/mediarouter/media-route-provider-framework.graffle/._data.plist create mode 100644 docs/image_sources/mediarouter/media-route-provider-framework.graffle/._image1.png create mode 100644 docs/image_sources/mediarouter/media-route-provider-framework.graffle/data.plist create mode 100644 docs/image_sources/mediarouter/media-route-provider-framework.graffle/image1.png create mode 100644 docs/image_sources/mediarouter/media-router-framework.graffle/data.plist create mode 100644 docs/image_sources/mediarouter/media-router-framework.graffle/image1.png diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index 73d5b7437fc9..0a234aa17279 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -368,7 +368,10 @@ Media Playback
  • - MediaRouter + Media Router +
  • +
  • + Media Route Provider
  • Supported Media Formats diff --git a/docs/html/guide/topics/media/mediarouteprovider.jd b/docs/html/guide/topics/media/mediarouteprovider.jd new file mode 100644 index 000000000000..389fbfb7794f --- /dev/null +++ b/docs/html/guide/topics/media/mediarouteprovider.jd @@ -0,0 +1,453 @@ +page.title=Media Route Provider +page.tags="mediarouteprovider","mediacontrolintent" +@jd:body + +
    +
    +

    In this document

    +
      +
    1. Overview +
        +
      1. Distribution of route providers
      2. +
      3. Types of playback
      4. +
      5. Media router packages
      6. +
      +
    2. +
    3. Creating a Provider Service
    4. +
    5. Specifying Route Capabilities +
        +
      1. Route categories
      2. +
      3. Media types and protocols
      4. +
      5. Playback controls
      6. +
      7. MediaRouteProviderDescriptor
      8. +
      +
    6. +
    7. Controlling Routes
    8. +
    +

    Key Classes

    +
      +
    1. {@link android.support.v7.media.MediaRouteProvider}
    2. +
    3. {@link android.support.v7.media.MediaRouteProviderDescriptor}
    4. +
    5. {@link android.support.v7.media.MediaRouteProvider.RouteController RouteController}
    6. +
    +

    Related Samples

    +
      +
    1. MediaRouter
    2. +
    +
    +
    + +

    Users want to play media content from their Android devices bigger, brighter, and louder on + connected playback devices such as televisions, stereos, + and home theater equipment. As a manufacturer of these devices, allowing Android users to + instantly show a picture, play a song, or share a video for friends and family using your product + can make it much more compelling and engaging.

    + +

    The Android media router framework allows manufacturers to enable playback on their devices + through a standardized interface called a {@link android.support.v7.media.MediaRouteProvider}. + A route provider defines a common interface for playing media on a receiver device, making it + possible to play media on your equipment from any Android application that supports media + routes.

    + +

    This guide discusses how to create a media route provider for a receiver device and make it + available to other media playback applications that run on Android.

    + +

    Overview

    + +

    The Android media router framework enables media app developers and media playback device + manufacturers to connect through a common API and common user interface. App developers that + implement a {@link android.support.v7.media.MediaRouter} interface can then connect to the + framework and play content to devices that participate in the media router framework. Media + playback device manufacturers can participate in the framework by publishing a {@link + android.support.v7.media.MediaRouteProvider} that allows other applications to connect to and + play media on the receiver devices. Figure 1 illustrates how an app connects to a receiving + device through the media router framework.

    + + +

    + Figure 1. Overview of how media route provider classes provide communication + from a media app to a receiver device. +

    + +

    When you build a media route provider for your receiver device, the provider serves the +following purposes:

    + + + + +

    Distribution of route providers

    + +

    A media route provider is distributed as part of an Android app. Your route provider can be + made available to other apps by extending + {@link android.support.v7.media.MediaRouteProviderService} or wrapping your implementation of + {@link android.support.v7.media.MediaRouteProvider} with your own service and declaring an intent + filter for the media route provider. These steps allow other apps to discover and make use of + your media route.

    + +

    + Note: The app containing the media route provider can also include a + MediaRouter interface to the + route provider, but this is not required. +

    + + +

    Types of playback

    + +

    There are two main types of playback supported by the media router framework. A media route + provider can support one or both types of playback, depending on the capabilities of your playback + equipment and the functionality you want to support:

    + + + + +

    Media router packages

    + +

    + The media router APIs are provided as part of the Android Support Library version 18 and higher, + in the v7-mediarouter + support library. You should use the classes in the + {@link android.support.v7.media} package for media route provider functions. + These APIs are compatible with devices running Android 2.1 (API level 7) and higher. +

    + +

    + Caution: There is another set of media router APIs provided in the + {@link android.media} class package that have been superseded by the + v7-mediarouter + support library. You should not use the {@link android.media} classes for + implementing media route provider functions. +

    + +

    In order to use the {@link android.support.v7.media} media router classes, you + must add the v7-mediarouter support library package to your app development project. For more + information on adding support libraries to your app development project, see + Support Library Setup. +

    + + +

    Creating a Provider Service

    + +

    The media router framework must be able to discover and connect to your media route provider + to allow other applications to use your route. In order to do this, the media router framework + looks for apps that declare a media route provider intent action. When another app wants to + connect to your provider, the framework must be able to invoke and connect to it, so your provider + must be encapsulated in a {@link android.app.Service}.

    + +

    The following example code shows the declaration of a media route provider service and the + intent filter in a manifest, which allows it to be discovered and used by the media router + framework:

    + +
    +<service android:name=".provider.SampleMediaRouteProviderService"
    +    android:label="@string/sample_media_route_provider_service"
    +    android:process=":mrp">
    +    <intent-filter>
    +        <action android:name="android.media.MediaRouteProviderService" />
    +    </intent-filter>
    +</service>
    +
    + +

    This manifest example declares a service that wraps the actual media route provider classes. + The Android media router framework provides the + {@link android.support.v7.media.MediaRouteProviderService} class for use as a service wrapper for + media route providers. The following example code demonstrates how to use this wrapper + class:

    + +
    +public class SampleMediaRouteProviderService extends MediaRouteProviderService {
    +
    +    @Override
    +    public MediaRouteProvider onCreateMediaRouteProvider() {
    +        return new SampleMediaRouteProvider(this);
    +    }
    +}
    +
    + + +

    Specifying Route Capabilities

    + +

    Apps connecting to the media router framework can discover your media route through your + app's manifest declarations, but they also need to know the capabilities of the media routes you + are providing. Media routes can be of different types and have different features, and other apps + need to be able to discover these details to determine if they are compatible with your route.

    + +

    The media router framework allows you to define and publish the capabilities of your media + route through {@link android.content.IntentFilter} objects, {@link + android.support.v7.media.MediaRouteDescriptor} objects and a {@link + android.support.v7.media.MediaRouteProviderDescriptor}. This section explains how to use these + classes to publish the details of your media route for other apps.

    + + +

    Route categories

    + +

    As part of the programmatic description of your media route provider, you must specify + whether your provider supports remote playback, secondary output, or both. These are the route + categories provided by the media router framework:

    + + + +

    In order to include these settings in a description of your media route, you insert them into + an {@link android.content.IntentFilter} object, which you later add to a + {@link android.support.v7.media.MediaRouteDescriptor} object:

    + +
    +public final class SampleMediaRouteProvider extends MediaRouteProvider {
    +    private static final ArrayList<IntentFilter> CONTROL_FILTERS_BASIC;
    +    static {
    +        IntentFilter videoPlayback = new IntentFilter();
    +        videoPlayback.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
    +        CONTROL_FILTERS_BASIC = new ArrayList<IntentFilter>();
    +        CONTROL_FILTERS_BASIC.add(videoPlayback);
    +    }
    +}
    +
    +
    + +

    If you specify the {@link android.support.v7.media.MediaControlIntent#CATEGORY_REMOTE_PLAYBACK + CATEGORY_REMOTE_PLAYBACK} intent, you must also define what media types and + playback controls are supported by your media route provider. The next section describes how to + specify these settings for your device.

    + + +

    Media types and protocols

    + +

    A media route provider for a remote playback device must specify the media types and transfer + protocols it supports. You specify these settings using the {@link android.content.IntentFilter} + class and the {@link android.content.IntentFilter#addDataScheme addDataScheme()} and + {@link android.content.IntentFilter#addDataType addDataType()} methods of that object. The + following code snippet demonstrates how to define an intent filter for supporting remote video + playback using http, https, and Real Time Streaming Protocol (RTSP):

    + +
    +public final class SampleMediaRouteProvider extends MediaRouteProvider {
    +
    +    private static final ArrayList<IntentFilter> CONTROL_FILTERS_BASIC;
    +
    +    static {
    +        IntentFilter videoPlayback = new IntentFilter();
    +        videoPlayback.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
    +        videoPlayback.addAction(MediaControlIntent.ACTION_PLAY);
    +        videoPlayback.addDataScheme("http");
    +        videoPlayback.addDataScheme("https");
    +        videoPlayback.addDataScheme("rtsp");
    +        addDataTypeUnchecked(videoPlayback, "video/*");
    +        CONTROL_FILTERS_BASIC = new ArrayList<IntentFilter>();
    +        CONTROL_FILTERS_BASIC.add(videoPlayback);
    +    }
    +    ...
    +
    +    private static void addDataTypeUnchecked(IntentFilter filter, String type) {
    +        try {
    +            filter.addDataType(type);
    +        } catch (MalformedMimeTypeException ex) {
    +            throw new RuntimeException(ex);
    +        }
    +    }
    +}
    +
    +
    + + +

    Playback controls

    + +

    A media route provider that offers remote playback must specify the types of media controls + it supports. These are the general types of control that media routes can provide:

    + + + +

    The following code example demonstrates how to construct an intent filter for supporting + basic media route playback controls:

    + +
    +public final class SampleMediaRouteProvider extends MediaRouteProvider {
    +    private static final ArrayList<IntentFilter> CONTROL_FILTERS_BASIC;
    +    static {
    +        ...
    +        IntentFilter playControls = new IntentFilter();
    +        playControls.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
    +        playControls.addAction(MediaControlIntent.ACTION_SEEK);
    +        playControls.addAction(MediaControlIntent.ACTION_GET_STATUS);
    +        playControls.addAction(MediaControlIntent.ACTION_PAUSE);
    +        playControls.addAction(MediaControlIntent.ACTION_RESUME);
    +        playControls.addAction(MediaControlIntent.ACTION_STOP);
    +        CONTROL_FILTERS_BASIC = new ArrayList<IntentFilter>();
    +        CONTROL_FILTERS_BASIC.add(videoPlayback);
    +        CONTROL_FILTERS_BASIC.add(playControls);
    +    }
    +    ...
    +}
    +
    + +

    For more information about the available playback control intents, see the + {@link android.support.v7.media.MediaControlIntent} class.

    + + +

    MediaRouteProviderDescriptor

    + +

    After defining the capabilities of your media route using {@link + android.content.IntentFilter} objects, you can then create a descriptor object for publishing to + the Android media router framework. This descriptor object contains the specifics of your media + route's capabilities so that other applications can determine how to interact with your media + route.

    + +

    The following example code demonstrates how to add the previously created intent filters to a + {@link android.support.v7.media.MediaRouteProviderDescriptor} and set the descriptor for use by + the media router framework:

    + +
    +public SampleMediaRouteProvider(Context context) {
    +    super(context);
    +    publishRoutes();
    +}
    +
    +private void publishRoutes() {
    +    Resources r = getContext().getResources();
    +    // Create a route descriptor using previously created IntentFilters
    +    MediaRouteDescriptor routeDescriptor = new MediaRouteDescriptor.Builder(
    +            VARIABLE_VOLUME_BASIC_ROUTE_ID,
    +            r.getString(R.string.variable_volume_basic_route_name))
    +            .setDescription(r.getString(R.string.sample_route_description))
    +            .addControlFilters(CONTROL_FILTERS_BASIC)
    +            .setPlaybackStream(AudioManager.STREAM_MUSIC)
    +            .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
    +            .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE)
    +            .setVolumeMax(VOLUME_MAX)
    +            .setVolume(mVolume)
    +            .build();
    +    // Add the route descriptor to the provider descriptor
    +    MediaRouteProviderDescriptor providerDescriptor =
    +            new MediaRouteProviderDescriptor.Builder()
    +            .addRoute(routeDescriptor)
    +            .build();
    +
    +    // Publish the descriptor to the framework
    +    setDescriptor(providerDescriptor);
    +}
    +
    + +

    For more information on the available descriptor settings, see the reference documentation + for {@link android.support.v7.media.MediaRouteDescriptor} and {@link + android.support.v7.media.MediaRouteProviderDescriptor}.

    + + +

    Controlling Routes

    + +

    When an application connects to your media route provider, the provider receives playback + commands through the media router framework sent to your route by other apps. To handle these + requests, you must provide an implementation of a {@link + android.support.v7.media.MediaRouteProvider.RouteController} class, which processes the commands + and handles the actual communication to your receiver device.

    + +

    The media router framework calls the {@link + android.support.v7.media.MediaRouteProvider#onCreateRouteController onCreateRouteController()} + method of your route provider to obtain an instance of this class and then routes requests to it. + These are the key methods of the {@link + android.support.v7.media.MediaRouteProvider.RouteController} class, which you must implement for + your media route provider:

    + + + +

    All playback control requests, except for volume changes, are directed to the {@link + android.support.v7.media.MediaRouteProvider.RouteController#onControlRequest onControlRequest()} + method. Your implementation of this method must parse the control requests and respond to them + appropriately. Here is an example implementation of this method which processes commands for a + remote playback media route:

    + +
    +private final class SampleRouteController extends
    +        MediaRouteProvider.RouteController {
    +    ...
    +
    +    @Override
    +    public boolean onControlRequest(Intent intent, ControlRequestCallback callback) {
    +
    +        String action = intent.getAction();
    +
    +        if (intent.hasCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) {
    +            boolean success = false;
    +            if (action.equals(MediaControlIntent.ACTION_PLAY)) {
    +                success = handlePlay(intent, callback);
    +            } else if (action.equals(MediaControlIntent.ACTION_ENQUEUE)) {
    +                success = handleEnqueue(intent, callback);
    +            } else if (action.equals(MediaControlIntent.ACTION_REMOVE)) {
    +                success = handleRemove(intent, callback);
    +            } else if (action.equals(MediaControlIntent.ACTION_SEEK)) {
    +                success = handleSeek(intent, callback);
    +            } else if (action.equals(MediaControlIntent.ACTION_GET_STATUS)) {
    +                success = handleGetStatus(intent, callback);
    +            } else if (action.equals(MediaControlIntent.ACTION_PAUSE)) {
    +                success = handlePause(intent, callback);
    +            } else if (action.equals(MediaControlIntent.ACTION_RESUME)) {
    +                success = handleResume(intent, callback);
    +            } else if (action.equals(MediaControlIntent.ACTION_STOP)) {
    +                success = handleStop(intent, callback);
    +            } else if (action.equals(MediaControlIntent.ACTION_START_SESSION)) {
    +                success = handleStartSession(intent, callback);
    +            } else if (action.equals(MediaControlIntent.ACTION_GET_SESSION_STATUS)) {
    +                success = handleGetSessionStatus(intent, callback);
    +            } else if (action.equals(MediaControlIntent.ACTION_END_SESSION)) {
    +                success = handleEndSession(intent, callback);
    +            }
    +
    +            Log.d(TAG, mSessionManager.toString());
    +            return success;
    +        }
    +        return false;
    +    }
    +    ...
    +}
    +
    + +

    It is important to understand that the {@link + android.support.v7.media.MediaRouteProvider.RouteController} class is intended to act as a wrapper + for the API to your media playback equipment. The implementation of the methods in this class is + entirely dependent on the programmatic interface provided by your receiving device.

    diff --git a/docs/html/guide/topics/media/mediarouter.jd b/docs/html/guide/topics/media/mediarouter.jd index 1b102652b423..e0bf88914899 100644 --- a/docs/html/guide/topics/media/mediarouter.jd +++ b/docs/html/guide/topics/media/mediarouter.jd @@ -1,5 +1,5 @@ -page.title=MediaRouter -page.tags="cast","chromecast","wireless display","miracast" +page.title=Media Router +page.tags="mediarouter","cast","chromecast","wireless display","miracast" @jd:body
    @@ -36,6 +36,10 @@ page.tags="cast","chromecast","wireless display","miracast"
  • {@link android.support.v7.media.MediaRouter.Callback}
  • {@link android.support.v7.media.MediaRouteProvider}
  • +

    Related Samples

    +
      +
    1. MediaRouter
    2. +
    @@ -105,15 +109,17 @@ page.tags="cast","chromecast","wireless display","miracast" (API level 7) and higher.

    -

    - Note: There is another set of media router APIs provided in the +

    + Caution: There is another set of media router APIs provided in the {@link android.media} that have been superseded by the v7-mediarouter support library. You should not use the {@link android.media} classes for media router functions.

    In order to use the {@link android.support.v7.media} media router classes, you must add the v7-mediarouter - support library package to your app development project. + support library package to your app development project. For more + information on adding support libraries to your app development project, see + Support Library Setup.

    @@ -211,9 +217,9 @@ page.tags="cast","chromecast","wireless display","miracast" CATEGORY_LIVE_VIDEO} — Output of video to a secondary output device, such as Wireless Display devices.
  • {@link android.support.v7.media.MediaControlIntent#CATEGORY_REMOTE_PLAYBACK - CATEGORY_REMOTE_PLAYBACK} — Play video or audio on a separate device that supports the - Google Cast remote control protocol, such - as Chromecast. + CATEGORY_REMOTE_PLAYBACK} — Play video or audio on a separate device that handles media + retrieval, decoding, and playback, such as + Chromecast devices.
  • @@ -279,7 +285,7 @@ public boolean onCreateOptionsMenu(Menu menu) {

    In order to connect to a media route selected by the user, your app must obtain the {@link android.support.v7.media.MediaRouter} framework object and then attach a {@link android.support.v7.media.MediaRouter.Callback} object. The callback object receives messages - from the media router framework when a route selected, changed or disconnected by the user.

    + from the media router framework when a route is selected, changed, or disconnected by the user.

    To obtain an instance of the {@link android.support.v7.media.MediaRouter} framework object, call {@link android.support.v7.media.MediaRouter#getInstance MediaRouter.getInstance()} @@ -299,11 +305,11 @@ public boolean onCreateOptionsMenu(Menu menu) {

    The media router framework communicates with an app through a callback object that you attach to the {@link android.support.v7.media.MediaRouter} framework object. An app that uses the media router framework must extend the {@link - android.support.v7.media.MediaRouter.Callback} object to receive messages when a media route is - connected and provide content to the connected device through that route.

    + android.support.v7.media.MediaRouter.Callback} object in order to receive messages when a + media route is connected.

    -

    There are several methods in the callback that can be overwritten to receive messages about - media router events. At the minimum, your implementation of the {@link +

    There are several methods in the callback that you can override to receive information about + media router events. At minimum, your implementation of the {@link android.support.v7.media.MediaRouter.Callback} class should override the following methods:

    @@ -440,12 +446,12 @@ public class MediaRouterPlaybackActivity extends ActionBarActivity {

    Note: The media route framework also provides a - {@link android.support.v7.app.MediaRouteDiscoveryFragment} class which takes care of adding and - removing the call back for an activity. + {@link android.support.v7.app.MediaRouteDiscoveryFragment} class, which takes care of adding and + removing the callback for an activity.

    Now when you run your application, you should see a Cast button appear in your activity. - When you press the button the media router framework, a route selection dialog appears as shown + When you touch the button, a route selection dialog appears as shown in figure 3, allowing your user to select an available media route. Make sure you have a supported device available on your local network when testing this interface.

    diff --git a/docs/html/images/mediarouter/media-route-provider-framework.png b/docs/html/images/mediarouter/media-route-provider-framework.png new file mode 100644 index 000000000000..60cc29a35325 Binary files /dev/null and b/docs/html/images/mediarouter/media-route-provider-framework.png differ diff --git a/docs/image_sources/mediarouter/media-route-provider-framework.graffle/._data.plist b/docs/image_sources/mediarouter/media-route-provider-framework.graffle/._data.plist new file mode 100644 index 000000000000..d82ea050f0c0 Binary files /dev/null and b/docs/image_sources/mediarouter/media-route-provider-framework.graffle/._data.plist differ diff --git a/docs/image_sources/mediarouter/media-route-provider-framework.graffle/._image1.png b/docs/image_sources/mediarouter/media-route-provider-framework.graffle/._image1.png new file mode 100644 index 000000000000..3435e35bbff4 Binary files /dev/null and b/docs/image_sources/mediarouter/media-route-provider-framework.graffle/._image1.png differ diff --git a/docs/image_sources/mediarouter/media-route-provider-framework.graffle/data.plist b/docs/image_sources/mediarouter/media-route-provider-framework.graffle/data.plist new file mode 100644 index 000000000000..07791df4a0ed Binary files /dev/null and b/docs/image_sources/mediarouter/media-route-provider-framework.graffle/data.plist differ diff --git a/docs/image_sources/mediarouter/media-route-provider-framework.graffle/image1.png b/docs/image_sources/mediarouter/media-route-provider-framework.graffle/image1.png new file mode 100644 index 000000000000..d6e3e9591212 Binary files /dev/null and b/docs/image_sources/mediarouter/media-route-provider-framework.graffle/image1.png differ diff --git a/docs/image_sources/mediarouter/media-router-framework.graffle/data.plist b/docs/image_sources/mediarouter/media-router-framework.graffle/data.plist new file mode 100644 index 000000000000..ffd82121845b Binary files /dev/null and b/docs/image_sources/mediarouter/media-router-framework.graffle/data.plist differ diff --git a/docs/image_sources/mediarouter/media-router-framework.graffle/image1.png b/docs/image_sources/mediarouter/media-router-framework.graffle/image1.png new file mode 100644 index 000000000000..d6e3e9591212 Binary files /dev/null and b/docs/image_sources/mediarouter/media-router-framework.graffle/image1.png differ -- cgit v1.2.3-59-g8ed1b