Android API Guides---Media Router

Media Router

当用户连接他们的电视,家庭影院系统和音乐播放器与无线技术,他们希望能够在这些大型,更响亮的设备从Android应用播放内容。启用这种播放可以把你的一个设备,一个用户的应用程序到一个共享的经验,喜悦和激励多个用户。


Android的媒体路由器的API旨在使这些辅助设备的媒体显示和回放。还有您可以使用使用这些API来播放内容两种主要的方法:


远程回放 - 这种方法使用的接收设备来处理内容的数据检索,解码和回放,同时在用户手中的Andr​​oid设备被用作遥控器。这种方法是由谷歌支持的Andr​​oid演员使用的应用程序。
辅助输出 - 通过这种方法,您的应用程序检索,呈现和直接流视频或音乐到接收设备。这种方法被用来支持Android上的无线显示输出。
本指南说明了您的应用程序可以如何提供媒体使用这些方法的执行二次播放设备。


概观


媒体路由器的API支持范围广泛的媒体输出,通过有线和无线方式播放连接到Android设备的设备。为了使这些连接,媒体路由器架构抽象的音频和视频输出Android设备的逻辑路径。这种架构使您的应用程序快速通道媒体内容连接播放设备,如家庭影院和音响系统,提供Android的媒体途径支持。


为了你的应用程序中使用这个框架,你必须得到MediaRouter框架对象的实例,并附加MediaRouter.Callback对象聆听到可用的媒体路线事件。通过媒体路线引导内容经过路线的关联MediaRouteProvider(除少数特殊情况下,诸如蓝牙输出设备)。下图提供了您的应用程序可以用来播放与媒体路由器框架内容类的高级视图。

Android API Guides---Media Router_第1张图片

图1.概述应用使用的主要媒体路由器类。
不是由媒体路由器框架支持的媒体播放硬件的制造商可以添加用于通过实现媒体RouteProvider和分发其作为一个应用程序的设备的支持。有关实现媒体提供者路线的详细信息,请参阅媒体RouteProvider参考文档和V7-mediarouter支持库样本

<sdk>/extras/android/compatibility/v7/mediarouter.

媒体路由器包


媒体路由器API提供作为Android的支持库版本18和更高的一部分,在V7-mediarouter支持库。具体来说,应该在android.support.v7.media包媒体路由器功能使用类。这些API与运行Android 2.1(API 7级)和较高的设备兼容。


注意:有另一套在已经被取代了V7-mediarouter支持库的android.media提供的媒体路由器的API。你不应该使用android.media类媒体路由器功能。


为了使用android.support.v7.media媒体路由器类,则必须将V7-mediarouter支持库包添加到您的应用程序开发项目。有关添加支持库到你的应用程序开发项目的更多信息,请参阅支持库设置。


铸造用户界面


实现媒体路由器API Android应用应包括投放按钮作为用户界面的一部分,允许用户选择一个媒体路线起到辅助输出设备上的媒体。媒体路由器框架为按钮,你应该用它来帮助用户识别和使用功能,在您的应用程序的标准接口。图2显示了演员按钮应该出现的应用程序。

Android API Guides---Media Router_第2张图片

图2.操作栏的右侧所示的钮扣。


注意:当实现,提供了一个媒体路由器接口必须从Android支持库扩展要么ActionBarActivity或FragmentActivity,即使活动的Android:是的minSdkVersion11 API或更高。


铸按钮


落实演员按钮用户界面的推荐方法是从ActionBarActivity扩展您的活动,并使用onCreateOptionsMenu()方法来添加一个选项菜单。该按钮必须使用MediaRouteActionProvider类作为其行动:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      >

    <item android:id="@+id/media_route_menu_item"
        android:title="@string/media_route_menu_title"
        app:actionProviderClass="android.support.v7.app.MediaRouteActionProvider"
        app:showAsAction="always"
    />
</menu>
有关在您的应用程序执行操作栏的更多信息,请参阅操作栏开发人员指南。
一旦你添加投放按钮,您的用户界面,您必须将媒体路径选择对象。构建一个选择器在下一节的讨论。
如果你不想在你的动作条菜单,你也可以使用MediaRouteButton添加一个演员按钮,您的应用程序。如果选择这种方法,您应根据谷歌演员设计清单将此按钮添加到您的应用程序的行动吧。你还必须在媒体路径选择连接使用setRoute选择()方法的按钮。
有关将演员按钮到您的应用指南,查看谷歌演员设计清单。
媒体路径选择
当用户按下投放按钮时,媒体路由器框架查找可用的媒体路线和呈现的选择列表给用户,如图3。

Android API Guides---Media Router_第3张图片

图3.可用的媒体路线,按演员按钮后显示的列表。


媒体的航线上出现的列表,远程回放,辅助输出或其他人,由您app.You定义的类型通过创建一个MediaRouteSelector,它接受由您创建的框架和其他媒体的路线供应商提供的MediaControlIntent对象定义这些类型或其他开发人员。该框架提供的路线类别如下:


CATEGORY_LIVE_AUDIO - 音频的输出到辅助输出设备,诸如启用无线的音乐系统。
CATEGORY_LIVE_VIDEO - 视频输出到第二输出设备,如无线显示设备。
CATEGORY_REMOTE_PLAYBACK - 播放处理媒体检索,解码和回放,如Chromecast装置一个单独的设备上的视频或音频。
当创建一个MediaRouteSelector对象,请使用MediaRouteSelector.Builder类来创建对象并设置上的媒体播放类别(控制类),如下面的代码示例:

public class MediaRouterPlaybackActivity extends ActionBarActivity {
    private MediaRouteSelector mSelector;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Create a route selector for the type of routes your app supports.
        mSelector = new MediaRouteSelector.Builder()                 // These are the framework-supported intents                 .addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)                 .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)                 .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
                .build();
    }
}
媒体路由器框架使用这个选择对象来选择你的应用支持,如图3。一旦你定义了这个选择,你将其连接到与演员菜单项关联的MediaRouteActionProvider对象的媒体路线提供了接口,如图所示下面的代码示例:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);

    // Inflate the menu and configure the media router action provider.
    getMenuInflater().inflate(R.menu.sample_media_router_menu, menu);

    // Attach the MediaRouteSelector to the menu item
    MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item);
    MediaRouteActionProvider mediaRouteActionProvider =
            (MediaRouteActionProvider)MenuItemCompat.getActionProvider(
            mediaRouteMenuItem);
    mediaRouteActionProvider.setRouteSelector(mSelector);

    // Return true to show the menu.
    return true;
}
一旦你取得了这些更改您的应用程序,你可能期望的演员按钮出现在您的活动。可惜的是,它没有(除非你的设备已经与无线显示配对)。在大多数情况下,还必须与媒体路由框架,这是在下一节讨论连接。


连接到媒体路由


为了连接到由用户选择的媒体路线,您的应用程序必须获得MediaRouter框架对象,然后附上MediaRouter.Callback对象。回调对象当选择一个路线,改变,或由用户断开从媒体路由器框架接收消息。


以获得MediaRouter框架对象的一个​​实例,调用MediaRouter.getInstance()从一个活动的onCreate()方法支持媒体路由器API。


注意:MediaRouter对象是由框架保持一个单。然而,一旦你的应用程序获得对象的实例,您必须到您的应用程序终止,以防止它被垃圾收集保留该实例。


创建MediaRouter回调


媒体路由器框架,通过您连接到MediaRouter框架对象的回调对象的应用程序进行通信。使用该媒体路由器框架必须为了延长MediaRouter.Callback对象时,媒体路由被连接来接收信息的应用程序。


有在你可以覆盖接收有关媒体路由器事件信息的回调几种方法。至少,你的MediaRouter.Callback类的实现应该重写以下方法:


onRouteSelected() - 当用户连接到一个媒体路由器输出装置调用。
onRouteUnselected() - 当调用从一个媒体路由器输出设备的用户断开连接。
onRoutePresentationDisplayChanged() - 当演示文稿显示更改其显示的指标,比如从720像素至1080像素分辨率改变调用。
您MediaRouter.Callback实现的方法,以确定是否已连接的路由是远程播放设备,例如Chromecast,或次级输出设备,诸如无线显示设备的第一次机会。如果您的应用程序支持的设备类型,那么您的实现应该在此分支所示,此示例代码:

private final MediaRouter.Callback mMediaRouterCallback =
        new MediaRouter.Callback() {

    @Override
    public void onRouteSelected(MediaRouter router, RouteInfo route) {
        Log.d(TAG, "onRouteSelected: route=" + route);

        if (route.supportsControlCategory(
            MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)){
            // remote playback device
            updateRemotePlayer(route);
        } else {
            // secondary output device
            updatePresentation(route);
        }
    }

    @Override
    public void onRouteUnselected(MediaRouter router, RouteInfo route) {
        Log.d(TAG, "onRouteUnselected: route=" + route);

        if (route.supportsControlCategory(
            MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)){
            // remote playback device
            updateRemotePlayer(route);
        } else {
            // secondary output device
            updatePresentation(route);
        }
    }

    @Override
    public void onRoutePresentationDisplayChanged(
            MediaRouter router, RouteInfo route) {
        Log.d(TAG, "onRoutePresentationDisplayChanged: route=" + route);

        if (route.supportsControlCategory(
            MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)){
            // remote playback device
            updateRemotePlayer(route);
        } else {
            // secondary output device
            updatePresentation(route);
        }
    }
}
定义媒体路由器回调对象后,仍然需要将其附加到主媒体路由器框架对象。下一节讨论适当的方式来连接你的回调媒体路线。
附加回调MediaRouter
感觉媒体路由是一种共享接口,您的应用程序必须重视和您的应用程序启动和关闭分离您MediaRouter.Callback对象。要做到这一点,就必须添加和删除从媒体路由器架构您的应用程序的回调对象作为你的应用程序的活动周期的一部分。这种方法允许其他应用程序要利用媒体的途径输出,而您的应用程序在后台或没有运行。
注意:如果你正在编写一个音乐播放应用,并希望允许的音乐播放,同时您的应用程序在后台运行,必须建立播放服务和连接服务,它的生命周期媒体路由器框架。
下面的代码示例演示如何使用生命周期方法适当地添加和删除应用的媒体路由器回调对象:

public class MediaRouterPlaybackActivity extends ActionBarActivity {
    private MediaRouter mMediaRouter;
    private MediaRouteSelector mSelector;
    private Callback mMediaRouterCallback;

    // your app works with so the framework can discover them.
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Get the media router service.
        mMediaRouter = MediaRouter.getInstance(this);
        ...
    }

    // Add the callback on start to tell the media router what kinds of routes
    // your app works with so the framework can discover them.
    @Override
    public void onStart() {
        mMediaRouter.addCallback(mSelector, mMediaRouterCallback,
                MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
        super.onStart();
    }

    // Remove the selector on stop to tell the media router that it no longer
    // needs to discover routes for your app.
    @Override
    public void onStop() {
        mMediaRouter.removeCallback(mMediaRouterCallback);
        super.onStop();
    }
    ...
}
你应该添加,只有在在onStart()和的onStop()生命周期方法去除媒体路由器回调。不包括在onResume()或的onPause()方法,这些调用。
注:媒体航线框架还提供了MediaRouter发现片段类,它需要添加和删除一个活动回调的照顾。
现在,当你运行你的应用程序,你应该会看到一个演员按钮出现在您的活动。当你触摸按钮,路线选择对话框出现如图3所示,让您的用户选择一个可用的媒体路线。确保测试此接口时,你有一个支持的设备在本地网络上。
注意:为了让无线显示路线在媒体路径选择对话框中显示,用户必须启用设置应用程序这个选项。该选项下的显示类别,被称为在Android 4.4(KitKat)的更高版本的设备,并在Android 4.2.x版(Jelly Bean)的设备无线显示屏幕演员。有关启用此功能的详细信息,请参阅本无线显示技术支持页面。
远程回放
远程回放方式发送控制命令给辅助设备来启动播放和控制播放正在进行中(暂停,快退,快进,音量上下)。使用这种方法,接收装置(例如有Chromecast)负责检索和呈现内容。
当你的应用程序支持这种类型的媒体路线,你必须创建使用远程回放通过您的应用程序的MediaRouter.Callback对象收到MediaRouter.RouteInfo对象RemotePlaybackClient对象。下面的示例代码演示了创建一个新的远程回放客户端,并将其发送的视频播放控制器的方法:

private void updateRemotePlayer(RouteInfo route) {
    // Changed route: tear down previous client
    if (mRoute != null && mRemotePlaybackClient != null) {
        mRemotePlaybackClient.release();
        mRemotePlaybackClient = null;
    }

    // Save new route
    mRoute = route;

    // Attach new playback client
    mRemotePlaybackClient = new RemotePlaybackClient(this, mRoute);

    // Send file for playback
    mRemotePlaybackClient.play(Uri.parse(
            "http://archive.org/download/Sintel/sintel-2048-stereo_512kb.mp4"),
            "video/mp4", null, 0, null, new ItemActionCallback() {

            @Override
            public void onResult(Bundle data, String sessionId,
                    MediaSessionStatus sessionStatus,
                    String itemId, MediaItemStatus itemStatus) {
                logStatus("play: succeeded for item " + itemId);
            }

            @Override
            public void onError(String error, int code, Bundle data) {
                logStatus("play: failed - error:"+ code +" - "+ error);
            }
        });
    }
}
该RemotePlaybackClient类提供了管理内容播放的其他方法。这里有几个来自RemotePlaybackClient类的主要方法回放:


玩() - 播放特定的媒体文件,由URI指定。
暂停() - 暂停当前播放的媒体轨道。
简历() - 继续播放当前曲目暂停命令后。
求() - 移动到当前轨道的特定位置。
发布() - 推倒,从您的应用程序的远程回放设备的连接。
您可以使用这些方法来连接行动来播放你在你的应用程序提供的控件。这些方法大多还允许包含回调对象,因此您可以监视任务播放或控制请求的进度。


该RemotePlaybackClient类还支持多种媒体项目的媒体队列播放和管理排队。有关这些功能全面的示例实现,请参阅SampleMediaRouterActivity及其相关类mediarouter支持库示例<SDK> /演员/安卓/兼容性/ V7 / mediarouter的V7。


有关使用Chromecast设备上的谷歌演员API的更多信息,请参阅谷歌演员的开发者文档。


辅助输出


次级输出方式发送准备媒体内容播放所连接的辅助设备。辅助设备可以包括电视机或无线的音响系统,可以通过无线协议或电线,例如HDMI电缆连接。用这种方法,应用程式负责处理用于播放(下载,解码音频和视频轨道的同步)的媒体内容,而辅助设备仅输出在其最终形式的内容。


注意:使用与媒体路由器框架次级输出显示航线上要求只在Android 4.2(API级别17)和更高可用的类,具体演示类。如果您正在构建,同时支持远程回放和次级输出设备的应用程序,你必须包括以下禁用所支持的Andr​​oid版本级别的代码检查。


创建演示文稿对象


使用时与媒体路由器框架次级输出的显示,您可以创建包含要显示屏幕上的内容的演示文稿对象。这次报告会是由Dialog类的扩展,所以可以增加布局和视图来演示。


你应该知道该演示文稿对象都有自己的内容和资源,从创建该对象的应用程序的活动分开。具有二级环境是必需的,因为演讲的内容是一个显示是从您的应用程序的本地Android设备上显示不同的上绘制。具体来说,辅助显示器需要一个单独的环境,因为它可能需要根据其特定的屏幕规格加载资源。


下面的代码示例显示了一个最小的实现演示文稿对象,包括GLSurfaceView对象。

public class SamplePresentation extends Presentation {
    public SamplePresentation(Context outerContext, Display display) {
        super(outerContext, display);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Notice that we get resources from the context of the Presentation
        Resources resources = getContext().getResources();

        // Inflate a layout.
        setContentView(R.layout.presentation_with_media_router_content);

        // Add presentation content here:
        // Set up a surface view for visual interest
        mSurfaceView = (GLSurfaceView)findViewById(R.id.surface_view);
        mSurfaceView.setRenderer(new CubeRenderer(false));
    }
}
创建演示文稿控制器
为了显示一个演示文稿对象,你应该写处理由MediaRouter.Callback对象收到的消息的响应和管理展现对象的创建和删除控制器层。控制器层也应处理附着演示所选择的显示对象,它表示由用户选择的不同的物理显示装置。控制器层可以简单地在活动的方法,该方法支持次要显示。
下面的代码示例显示了作为一个单一的方法来实现演示控制器层。此方法处理时被选择或断开一个多媒体驳回无效展示,和显示装置连接时创建演示对象。

private void updatePresentation(RouteInfo route) {
    // Get its Display if a valid route has been selected
    Display selectedDisplay = null;
    if (route != null) {
        selectedDisplay = route.getPresentationDisplay();
    }

    // Dismiss the current presentation if the display has changed or no new
    // route has been selected
    if (mPresentation != null && mPresentation.getDisplay() != selectedDisplay) {
        mPresentation.dismiss();
            mPresentation = null;
    }

    // Show a new presentation if the previous one has been dismissed and a
    // route has been selected.
    if (mPresentation == null && selectedDisplay != null) {
        // Initialize a new Presentation for the Display
        mPresentation = new SamplePresentation(this, selectedDisplay);
        mPresentation.setOnDismissListener(
                new DialogInterface.OnDismissListener() {
                    // Listen for presentation dismissal and then remove it
                    @Override
                    public void onDismiss(DialogInterface dialog) {
                        if (dialog == mPresentation) {
                            mPresentation = null;
                        }
                    }
                });

        // Try to show the presentation, this might fail if the display has
        // gone away in the meantime
        try {
            mPresentation.show();
        } catch (WindowManager.InvalidDisplayException ex) {
            // Couldn't show presentation - display was already removed
            mPresentation = null;
        }
    }
}
意:当用户连接到一个无线显示,媒体路由器框架自动提供,它是一个连接的设备上显示屏幕内容的通知。

你可能感兴趣的:(java,android,media,api,sdk,router)