Media Route Provider
用户希望从他们的Android设备播放媒体内容更大,更亮,更响亮的连接播放设备如电视机,音响和家庭影院设备。由于这些设备制造商,让Android用户能够即时显示图片,播放一首歌曲,或共享使用你的产品可以使它更引人注目的,引人入胜的朋友和家人视频。
Android的媒体路由器架构让制造商可以通过一个叫做媒体RouteProvider标准化接口,使他们的设备上播放。 AA路线提供商定义播放接收设备上的媒体,从而有可能对你的设备从支持媒体路线的任何Android应用程序发挥媒体的通用接口。
本指南讨论如何创建的接收装置的媒体路线提供商,使其可用于在Android上运行其他媒体播放应用程序。
概观
Android的媒体路由器框架使媒体应用开发商和媒体播放设备制造商通过一个通用的API和普通用户界面进行连接。然后实现一个MediaRouter接口应用开发者可以连接到框架和播放内容到参与媒体路由器框架的装置。媒体播放设备制造商可以通过发布MediaRouteProvider,其它应用程序连接到与接收器上的设备播放媒体参与的框架。图1示出了如何应用程式连接到通过媒体路由器框架的接收装置。
图1.概述媒体路线提供商类如何提供从媒体应用接收设备的通信。
当你建立你的接收设备中的媒体路线供应商,供应商有以下用途:
描述和发布接收设备的功能,以便其他应用程序可以发现它和使用它的播放功能。
包裹接收器设备和它的通信的传输机制的编程接口,使设备与媒体路由器框架兼容。
路线供应商的分布
一个媒体路由提供商分配作为一个Android应用程序的一部分。您的路线提供商可以通过扩展MediaRouteProviderService或与您自己的服务包您MediaRouteProvider实施,并宣布为媒体路线提供者的意图过滤器提供给其他应用程序。这些步骤允许其他应用程序来发现和利用媒体的路线。
注意:包含媒体路径提供程序的应用还可以包括一个MediaRouter接口路由提供商,但是这不是必需的。
播放的类型
存在由媒体路由器框架支持播放两种主要类型。一个媒体路线提供商可以支持一种或两种类型的播放,这取决于你想支持您的播放设备和功能的能力:
远程回放 - 这种方法使用接收设备来处理内容的数据检索,解码和回放,同时在用户手中的Android设备被用作遥控器。这种方法是由谷歌支持的Android演员使用的应用程序。
辅助输出 - 使用这种方法,Android的媒体应用程序检索,呈现和直接流视频或音乐的接收装置。这种方法被用来支持Android上的无线显示输出。
媒体路由器包
媒体路由器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支持库包添加到您的应用程序开发项目。有关添加支持库到你的应用程序开发项目的更多信息,请参阅支持库设置。
创建提供商服务
媒体路由器架构必须能够发现并连接到您的媒体路线提供商允许其他应用程序使用您的路线。为了做到这一点,媒体路由器框架将查找声明媒体路线提供商的意图行动应用程序。当另一个应用想要连接到您的供应商,该框架必须能够调用并连接到它,所以你的提供者必须在服务被封装。
下面的示例代码显示了媒体航线提供服务,并在一个清单,这使得它被发现和媒体路由器框架使用的意图过滤器的声明:
<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>此清单例子声明了包装的实际媒体路线提供类的服务。 Android的媒体路由器框架提供用作媒体航线提供服务包装器MediaRouter提供服务类。下面的代码示例演示如何使用该包装类:
public class SampleMediaRouteProviderService extends MediaRouteProviderService { @Override public MediaRouteProvider onCreateMediaRouteProvider() { return new SampleMediaRouteProvider(this); } }指定路由功能
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); } }如果指定类别远程回放互联网,你还必须定义什么样的介质类型和播放控制是通过媒体途径提供商支持。下一节介绍如何指定设备的这些设置。
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); } } }播放控制
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); } ... }有关可用播放控制意图的更多信息,请参阅MediaControl Intent类。
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); }有关可用描述符设置的详细信息,请参阅MediaRouter描述符和媒体RouteProvider描述符的参考文档。
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; } ... }要明白,媒体RouteProvider.Route Controller类旨在充当API来的媒体回放设备的包装是重要的。在这一类方法的实现完全取决于你的接收设备提供的编程接口。