【Audio&Video】MediaRouter概述(17)

为了在您的应用程序中使用MediaRouter框架,您必须获取MediaRouter对象的实例并附加一个 MediaRouter.Callback对象来侦听路由事件。通过媒体路由发送的内容通过路由关联MediaRouteProvider(除少数特殊情况外,如蓝牙输出设备)。图1提供了用于在设备之间路由内容的类的高级视图。
【Audio&Video】MediaRouter概述(17)

图1.应用程序使用的关键媒体路由器类的概述。

注意:如果您希望您的应用支持 Google Cast设备,则应使用Cast SDK 并将您的应用构建为Cast发件人。按照Cast文档中的 说明操作, 而不是直接使用MediaRouter框架。

媒体路线按钮


Android应用程序应该使用媒体路线按钮来控制媒体路由。MediaRouter框架为按钮提供了一个标准接口,可帮助用户在路由可用时识别和使用路由。媒体路由按钮通常位于应用程序操作栏的右侧,如图2所示。
【Audio&Video】MediaRouter概述(17)

图2.操作栏中的媒体路由按钮。

当用户按下媒体路由按钮时,可用媒体路由将显示在列表中,如图3所示。
【Audio&Video】MediaRouter概述(17)

图3.按媒体路由按钮后显示的可用媒体路由列表。

按照以下步骤创建媒体路由按钮:

  1. 使用AppCompatActivity
  2. 定义媒体路由按钮菜单项
  3. 创建一个MediaRouteSelector
  4. 将媒体路由按钮添加到操作栏
  5. 在您的活动生命周期中创建和管理MediaRouter.Callback方法

本节介绍前四个步骤。下一节介绍回调方法。

使用AppCompatActivity

在活动中使用媒体路由器框架时,应扩展活动AppCompatActivity并导入软件包android.support.v7.media。您必须将 v7-appcompat 和 v7-mediarouter 支持库添加到您的应用开发项目中。有关将支持库添加到项目的更多信息,请参阅支持库设置。

警告:请务必使用android.support.v7.media 媒体路由器框架的实施。不要使用旧的android.media软件包。

定义媒体路由按钮菜单项

创建一个定义媒体路由按钮的菜单项的xml文件。该项目的行动应该是MediaRouteActionProvider班级。这是一个示例文件:

// myMediaRouteButtonMenuItem.xml
<?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>

创建一个MediaRouteSelector

出现在媒体路线按钮菜单中的路线由a决定MediaRouteSelector。 如下面的代码示例所示,AppCompatActivity 当MediaRouteSelector.Builder从onCreate()方法调用创建的活动时,从您的活动扩展并构建选择器。请注意,选择器保存在类变量中,并且允许的路由类型通过添加MediaControlIntent对象来指定:

public class MediaRouterPlaybackActivity extends AppCompatActivity {
    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_REMOTE_PLAYBACK)
                .build();
    }
}

对于大多数应用程序,唯一需要的路线类型是CATEGORY_REMOTE_PLAYBACK。此路线类型将运行您应用程序的设备视为遥控器。所连接的接收器设备处理所有内容数据检索,解码和回放。这就是支持Google Cast的应用程序(如 Chromecast)的工作方式。

少数制造商支持称为“辅助输出”的特殊路由选项。通过此路由,您的媒体应用程序可以检索,呈现视频或音乐并将其直接传输到所选远程接收设备上的屏幕和/或扬声器。使用辅助输出将内容发送到支持无线功能的音乐系统或视频显示器。要启用这些设备的发现和选择,您需要将CATEGORY_LIVE_AUDIO或 CATEGORY_LIVE_VIDEO 控制类别添加 到MediaRouteSelector。您还需要创建并处理您自己的Presentation对话框。

将媒体路由按钮添加到操作栏

通过定义媒体路线菜单和MediaRouteSelector,您现在可以将媒体路线按钮添加到活动。覆盖onCreateOptionsMenu()每个活动的方法以添加选项菜单。

@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);
    // Attach the MediaRouteSelector that you built in onCreate()
    mediaRouteActionProvider.setRouteSelector(mSelector);

    // Return true to show the menu.
    return true;
}

有关在您的应用中实施操作栏的更多信息,请参阅操作栏 开发人员指南。

您还可以MediaRouteButton在任何视图中添加媒体路由按钮。您必须使用该setRouteSelector()方法将MediaRouteSelector附加到按钮。请参阅 Google Cast设计清单 ,了解将媒体路线按钮合并到您的应用程序的准则。

MediaRouter回调


在同一设备上运行的所有应用程序共享一个MediaRouter实例及其路线(由应用程序的MediaRouteSelector对每个应用程序进行过滤)。每个活动都使用其自己的MediaRouter.Callback 方法实现与MediaRouter进行通信。只要用户选择,更改或断开路由,MediaRouter就会调用回调方法。

回调中有几种方法可以覆盖以接收有关路由事件的信息。至少,您的MediaRouter.Callback类的实现应该覆盖 onRouteSelected()和 onRouteUnselected()。

由于MediaRouter是一个共享资源,因此您的应用需要管理其MediaRouter回调以响应通常的活动生命周期回调:

创建活动时(onCreate(Bundle))MediaRouter在应用程序的整个生命周期内抓取一个指向并保持它的指针。
活动变为可见(onStart())时,将回调附加到MediaRouter ,并在隐藏时将其分离(onStop())。
以下代码示例演示了如何创建和保存回调对象,如何获取实例MediaRouter以及如何管理回调。注意CALLBACK_FLAG_REQUEST_DISCOVERY在附加回调时使用该标志onStart()。这允许您的MediaRouteSelector刷新媒体路由按钮的可用路由列表。

public class MediaRouterPlaybackActivity extends AppCompatActivity {
    private MediaRouter mMediaRouter;
    private MediaRouteSelector mSelector;

    // Variables to hold the currently selected route and its playback client
    private MediaRoute mRoute;
    private RemotePlaybackClient mRemotePlaybackClient;

    // Define the Callback object and its methods, save the object in a class variable
    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)){
                // Stop local playback (if necessary)
                // ...

                // Save the new route
                mRoute = route;

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

                // Start remote playback (if necessary)
                // ...
            }
        }

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

            if (route.supportsControlCategory(
                MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)){

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

                // Save the new route
                mRoute = route;

                if (reason != MediaRouter.UNSELECT_REASON_ROUTE_CHANGED) {
                    // Resume local playback  (if necessary)
                    // ...
                }
            }
        }
    }

    // Retain a pointer to the MediaRouter
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

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

    // Use this callback to run your MediaRouteSelector to generate the list of available media routes
    @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();
    }
    ...
}

媒体路由器框架还提供了一个 MediaRouteDiscoveryFragment类,该类负责添加和删除活动的回调。

注意:如果您正在编写音乐回放应用程序,并希望应用程序在后台播放音乐,则必须构建Service回放并从服务的生命周期回调中调用媒体路由器框架。

控制远程播放路线


当您选择远程播放路线时,您的应用将充当远程控制。路由另一端的设备处理所有内容数据检索,解码和回放功能。应用程序用户界面中的控件使用RemotePlaybackClient对象与接收器设备进行通信 。

该RemotePlaybackClient课程提供了用于管理内容回放的其他方法。以下是该RemotePlaybackClient课程的一些重要播放方法:

play()- 播放由特定的特定媒体文件Uri。
pause() - 暂停正在播放的媒体音轨。
resume() - 在暂停命令后继续播放当前曲目。
seek() - 移动到当前曲目中的特定位置。
release() - 从应用程序连接到远程播放设备。
您可以使用这些方法将操作附加到您在应用中提供的播放控件。大多数这些方法还允许您包含一个回调对象,以便您可以监视回放任务或控制请求的进度。

该RemotePlaybackClient班还支持多种媒体项目的媒体队列播放和管理排队。

示例代码


Android的BasicMediaRouterAndroid的MediaRouter 样品进一步证明使用MediaRouter API的。

联系我

QQ:94297366
微信打赏:https://pan.baidu.com/s/1dSBXk3eFZu3mAMkw3xu9KQ

公众号推荐:

【Audio&Video】MediaRouter概述(17)

猜你喜欢

转载自blog.51cto.com/4789781/2130805