Android 的媒体路由功能应用与框架解析
一、功能描述
Android
的媒体路由API被设计用来允许多种媒体(视频、音乐、图片)在与ANDROID设备连接(无线或有线)的辅助设备(如电视、立体声、家庭戏院系统、音乐播放机)上显示和播放,使用该框架和API,允许Android用户立即在辅助设备上显示图片、播放音乐、共享视频等。
媒体路由框架提供两种播放输出类型:远端播放和辅助输出。远端播放类型指的是辅助设备处理媒体内容的接收、解码和回放,而Android设备(如手机)只起远程控制作用,如ANDROID应用使用该类型用来支持Google
Cast。辅助输出类型则是应用本身处理媒体内容(视频或音乐),包括媒体内容的引出和处理,并把处理结果直接呈现和串流到辅助接收设备上,辅助接收设备只是呈现媒体处理后的最终内容,如Android系统中使用该方式用来支持Wireless
Display输出。
如下图是应用使用媒体路由框架播放内容的有关类的高层视图:
媒体路由框架用来提供和抽象已连接的媒体辅助输出的逻辑路径。
媒体应用通过一个MediaRouter对象(媒体路由框架提供的一个对象)来使用媒体路由框架,用来选择媒体路由,并经过媒体路由框架的路由连接到选择的最终接收设备。
Android系统从4.3版本开始提供了一个媒体路由服务,用来对ANDROID系统自带的本地显示和声音输出设备的路由支持,如speaker、有线耳机、USB耳机,蓝牙A2DP输出、HDMI输出、Wireless
Display输出等。这些媒体路由设备被称为框架提供的系统媒体路由。
对于没有被媒体路由框架支持的媒体播放硬件,可以通过实现一个应用,在此应用中通过使用ANDROID提供的媒体路由支持库v7-mediarouter(
v7-mediarouter支持库是版本为V18及以上的Android
Support支持库的一部分),继承v7-mediarouter支持库中提供的MediaRouteProviderService和MediaRouteProvider基类,实现一个继承这些基类的特定MediaRouteProviderService服务和一个针对特定硬件的特定的MediaRouteProvider对象,以此实现对特定媒体播放硬件的路由支持。这种用户实现的媒体路由称为用户媒体路由。
由于v7-mediarouter路由支持库兼容于ANDROID2.1以上的版本,因此可以使用该库在ANDROID2.1以上的系统上开发针对特定媒体播放辅助硬件的媒体路由应用。
每个辅助设备(除了蓝牙输出设备)为了支持媒体路由必须继承和实现一个特定MediaRouteProvider和创建和实现相关的RouteController对象。
如以上媒体路由框架视图所示,用户通过MediaRouter对象对媒体路由的选择最终由媒体路由框架传递和路由到选择路由对应的MediaRouteProvider对象,对选择的媒体设备的操作由媒体路由框架转发到MediaRouteProvider对象关联的MediaRouteProvider.RouteController对象,由MediaRouteProvider.RouteController对象完成对媒体设备的实际操作,包括转发应用发送来的媒体播放控制命令或其它请求以及处理实际的与媒体硬件的通讯。
媒体路由提供方在实现MediaRouteProvider时需要定义一个MediaRouteProviderDescriptor对象和几个MediaRouteProviderDescriptor对象及IntentFilter对象来描述媒体路由设备的路由能力。
对设备中的每一个可路由的媒体硬件,对于其支持的每一个媒体路由类别,需要定义一个IntentFilter对象,并添加到描述该媒体硬件某个路由能力的MediaRouteDescriptor对象中,并把MediaRouteDescriptor对象增加到MediaRouteProviderDescriptor对象中。
二、框架描述
如下是媒体路由框架内部主要相关类的一个类图。由这些类图中的类具体负责对系统提供的媒体设备和设备厂商提供的媒体设备的媒体播放路由支持。
这些类都位于v7-mediarouter支持库中。主要包含如下类:
一)、 MediaRouter类
该类是用户使用媒体框架的接口类,由该类为用户提供媒体路由操作的API接口。
MediaRouter主要包含如下API:
1)、
public static MediaRouter getInstance(Context context)
应用为了使用媒体路由框架,必须首先调用该接口获得一个MediaRouter对象实例。MediaRouter对象内部包含一个全局属性
sGlobal,sGlobal属性维护一个类型为MediaRouter类的一个内部类GlobalMediaRouter的单一实例,用来维护媒体路由的全局状态,MediaRouter对象的实例方法一般都是通过sGlobal来与媒体路由框架交互。该属性必须在MediaRouter对象初始化之前实例化,并只能有一个对象,因此采用了单例模式。
2)、 public
List<RouteInfo> getRoutes()
获得当前发现的所有媒体路由信息的一个列表,媒体路由框架对于每一个发现的媒体路由都用一个RouteInfo对象表示。一个媒体路由提供设备可能包含多个媒体路由。
3)、public
List<ProviderInfo> getProviders()
获得当前发现的媒体路由提供设备的MediaRouteProvider信息的列表,用ProviderInfo对象表示。
4)、 public
RouteInfo getDefaultRoute()
返回播放媒体内容的系统默认路由,媒体路由框架必须提供一个默认媒体路由。
5)、public
RouteInfo getSelectedRoute()
返回用户当前选择的媒体路由。该路由也必须存在。
6)、 public
void selectRoute(RouteInforoute)
用来选择特定的路由。
7)、 public
boolean isRouteAvailable(MediaRouteSelector selector, int flags)
判断是否存在一个与特定MediaRouteSelector相匹配的媒体路由,如存在则返回True。
MediaRouteSelector用来描述应用希望发现和使用的媒体路由的能力。
8)、 public
void addCallback(MediaRouteSelector selector, Callback callback)
登记一个具体的MediaRouter.Callback回调对象,并用来启动与特定MediaRouteSelector相匹配的媒体路由的发现,以及监听发现的媒体路由的相关事件,如用户已选择连接到某个媒体路由设备、某个媒体路由设备的特性发生改变或者断开某个媒体路由等事件。
应用为了使用相关的媒体路由,必须调用该函数来启动媒体路由的发现,并通过登记的回调函数接收相关的事件。
9)、 public
void removeCallback(Callback callback)
注销先前登记的回调。
10)、public
void addRemoteControlClient(ObjectremoteControlClient)
增加一个对选择的路由进行音量控制的控制客户端。该控制客户端必须已经使用AudioManager.registerRemoteControlClient方法登记于AudioManager服务中。该接口用于远程控制路由类型。
)、public
void removeRemoteControlClient(Object remoteControlClient)
注销先前登记的RemoteControlClient对象。
二)、MediaRouteProvider与MediaRouteProvider.
RouteController
这两个类都是抽象类。MediaRouteProvider及其控制类主要提供如下功能:
MediaRouteProvider的功能是描述和发布接收设备的能力;
MediaRouteProvider. RouteController类封装接收设备的编程接口和它的通讯传输机制,以便使设备与媒体框架兼容。
媒体路由框架中提供和实现了MediaRouteProvider类的两个派生类及其控制类:RegisteredMediaRouteProvider与RegisteredMediaRouteProvider.Controller,SystemMediaRouteProvider及有关的LegacyImpl.DefaultRouteController和JellybeanImpl.SystemRouteController控制类,分别对用户添加的媒体路由和系统自带的媒体路由提供支持。
每个非系统提供的辅助设备为了支持媒体路由,必须实现一个专用的MediaRouteProvider类的派生类及其控制类,并通过RegisteredMediaRouteProvider类登记到媒体框架中。
每个具体的MediaRouteProvider可能提供对多个媒体路由的支持,对MediaRouteProvider支持的每一个媒体路由需要创建一个独立RouteController对象来与该媒体路由交互。
每个RouteController对象在具体MediaRouteProvider类的onCreateRouteController函数中创建,在onCreateRouteController函数中需要根据媒体路由提供描述中的包含的媒体路由数创建相应的RouteController对象。
三)、媒体路由提供服务(MediaRouteProviderService)类
MediaRouteProviderService类作为一个抽象的service类,用来提供对用户提供的具体MediaRouteProvider类的封装。每一个非系统提供的媒体接收设备要支持媒体路由,在其应用包中必须实现一个MediaRouteProviderService服务的派生类和一个MediaRouteProvider类的特定实现。
在MediaRouteProviderService服务的派生类中需要实现MediaRouteProviderService服务的虚函数onCreateMediaRouteProvider,在该函数中实例化特定的MediaRouteProvider类。
在特定的MediaRouteProvider类的实例化函数中调用其publishRoutes函数来描述和发布要支持的媒体播放硬件的路由能力,以便系统中其它应用能够确定是否能够和如何与之交互。媒体设备路由能力用MediaRouteProviderDescriptor对象描述。
publishRoutes函数通过调用MediaRouteProvider的setDescriptor函数来发布该MediaRouteProvider支持的媒体设备路由能力。
四)、RegisteredMediaRouteProvider与RegisteredMediaRouteProvider.Controller
RegisteredMediaRouteProvider是MediaRouteProvider类的子类,RegisteredMediaRouteProvider是对媒体路由框架不支持的媒体播放硬件添加路由支持的主要的一个类。
RegisteredMediaRouteProvider对象和其包含的Controller对象是应用中实现的MediaRouteProvider对象和其对应的RouteController对象在媒体路由框架中的映射,两者存在一一对应关系,两者通过MediaRouteProviderService相联系。
RegisteredMediaRouteProvider对每一个发现的包含媒体路由提供服务的应用,在媒体路由框架中创建和添加一个RegisteredMediaRouteProvider对象,并通过该对象与应用中的媒体路由提供服务进行绑定。
RegisteredMediaRouteProvider中包含的Controller对象用来把用户对该硬件相应的媒体路由的请求通过与MediaRouteProviderService服务的连接转发到应用提供的媒体路由提供对象和相应的控制器对象。
五)、RegisteredMediaRouteProviderWatcher类
RegisteredMediaRouteProviderWatcher负责监视与扫描安装的应用包,用来发现应用包中包含的媒体路由提供服务。
对于发现的每一个媒体路由提供服务,RegisteredMediaRouteProviderWatcher除了创建和添加一个RegisteredMediaRouteProvider实例,并调用该实例的相关接口与新发现的媒体路由提供服务绑定,在与媒体路由提供服务绑定时调用媒体路由服务的onCreateMediaRouteProvider函数创建媒体路由提供服务封装的具体的MediaRouteProvider对象。
还调用GlobalMediaRouter对象的addProvider函数创建相应的RouteInfo和ProviderInfo对象并添加到媒体路由框架中,用来代表新发现的媒体路由和媒体路由提供者。
RegisteredMediaRouteProviderWatcher与PackageManager交互使用PackageManager的queryIntentServices接口来扫描安装的应用包。
六)、SystemMediaRouteProvider及其派生类LegacyImpl、JellybeanImp,LegacyImpl、JellybeanImp对应的控制类DefaultRouteController、SystemRouteController。另外还有JellybeanImpl的派生类JellybeanMr1Impl和JellybeanMr2Impl。以及相关的关联类MediaRouterJellybean、MediaRouterJellybeanMr1、MediaRouterJellybeanMr2。
SystemMediaRouteProvider是MediaRouteProvider抽象类的直接派生类。
这些类共同负责对应用提供系统内置的媒体路由功能。这些类通过android.media.MediaRouter接口来查询系统提供的系统媒体路由。
为了支持不同的ANDROID版本,SystemMediaRouteProvider类的这些派生类,用来提供对不同版本的支持。这些类的派生关系如下:
Jellybean以上版本(SDK
API版本号为16)对应的具体MediaRouteProvider类为JellybeanImpl,JellybeanMr1以上的版本(API版本号为17)对应的具体MediaRouteProvider类为JellybeanMr1Impl类,JellybeanMr1版本添加了对辅助显示路由的支持,因此JellybeanMr1Impl类添加了这方面的路由能力,JellybeanMr2以上的版本(API的版本号为18)对应的具体MediaRouteProvider类为JellybeanMr2Impl类,这些MediaRouteProvider类的控制器都是SystemRouteController。 Jellybean以下版本的的具体MediaRouteProvider类为LegacyImpl,其对应的控制器DefaultRouteController。
LegacyImpl的媒体路由只提供音乐类型的媒体播放路由能力,其通过AudioManager与声音服务交互实现声音路由功能。对应的DefaultRouteController控制器对象也是通过AudioManager的API用来设置和更新媒体播放的音量。
Jellybean及以后的版本系统提供了媒体路由服务,并提供了多种类型的媒体路由。为了与系统媒体路由服务的交互并支持不同的版本,v7-mediarouter支持库对不同版本提供了不同的接口类,对应JellybeanMr2版本的MediaRouterJellybeanMr2类,对应JellybeanMr1版本的MediaRouterJellybeanMr1类,以及对应Jellybean版本的MediaRouterJellybean类,这些接口类通过android.media.MediaRouter对象与系统提供的媒体路由服务交互。
由于JellybeanMr1开始提供辅助显示设备的路由支持,因此MediaRouterJellybeanMr1类还提供了与DisplayManager的接口。
七)RemoteControlClientCompat抽象类及其内部具体派生类RemoteControlClientCompat.LegacyImpl和
RemoteControlClientCompat.JellybeanImpl
对于远端播放类型的媒体路由,应用端需要提供一个RemoteControlClient对象用来提供对该种路由类型设备的操作。
RemoteControlClientCompat是RemoteControlClient对象通过v7-mediarouter支持库与系统实现交互的包装接口类。RemoteControlClient的派生类RemoteControlClientCompat.LegacyImp用来支持Jellybean以前的版本,目前什么也没有实现。RemoteControlClientCompat.JellybeanImpl则是对Jellybean以后的版本提供支持的具体RemoteControlClientCompat实现。
RemoteControlClientCompat.JellybeanImpl也是通过MediaRouterJellybean接口类与系统媒体路由交互。
三、主要流程
现在来看一下应用使用媒体路由功能的主要系统流程。
3.1 路由的发现
媒体路由的发现流程通过调用媒体路由支持库中的MediaRouter类的实例函数addCallback来启动。整个流程如下:
3.2媒体路由的选择
媒体路由的选择通过调用媒体路由支持库中MediaRouter类的实例函数selectRoute函数来启动。整个流程如下:
版权所有,转载时请尊重原创清楚注明链接和出处!
Android 的媒体路由功能应用与框架解析的更多相关文章
- Android 虚拟机Dalvik、Android各种java包功能、Android相关文件类型、应用程序结构分析、ADB
Android虚拟机Dalvik Dalvik冲击 随着Google 的AndroidSDK 的发布,关于它的API 以及在移动电话领域所带来的预期影响这些方面的讨论不胜枚举.不过,其中的一个话题在J ...
- Android media媒体库分析之:MediaProvider
在做Android媒体应用程序时(Audio.Image.Video)需要对Android的媒体提供者(MediaProvider)做详细的分析,下面记录一下我的收获: 一.获取MediaProvid ...
- zpf 路由功能
2015-4-11 20:51:06 又搞了一天, 解决了一堆bug, 重新规划了类文件夹, 改善自动加载功能 最新的特性就是支持子域名路由了 因为整个框架还在完善当中, 而且里边有好多接口有我自己申 ...
- Android平台免Root无侵入AOP框架Dexposed使用详解
Dexposed是基于久负盛名的开源Xposed框架实现的一个Android平台上功能强大的无侵入式运行时AOP框架. Dexposed的AOP实现是完全非侵入式的,没有使用任何注解处理器,编织器或者 ...
- 收藏的Android很好用的组件或者框架。
收藏的Android很好用的组件或者框架. android框架 先说两个站点: http://www.androidviews.net/ 非常好的国外开源码站,就是訪问速度有点慢啊 http://w ...
- 玩转nodeJS系列:使用原生API实现简单灵活高效的路由功能(支持nodeJs单机集群),nodeJS本就应该这样轻快
前言: 使用nodeJS原生API实现快速灵活路由,方便与其他库/框架进行整合: 1.原生API,简洁高效的轻度封装,加速路由解析,nodeJS本就应该这样轻快 2.不包含任何第三方库/框架,可以灵活 ...
- 【学习笔记】node.js重构路由功能
摘要:利用node.js模块化实现路由功能,将请求路径作为参数传递给一个route函数,这个函数会根据参数调用一个方法,最后输出浏览器响应内容 1.介绍 node.js是一个基于Chrome V8引擎 ...
- iScroll框架解析——Android 设备页面内 div(容器,非页面)overflow:scroll; 失效解决(转)
移动平台的活,兼容问题超多,今儿又遇到一个.客户要求在弹出层容器内显示内容,但内容条数过多,容器显示滚动条.按说是So easy,容器设死宽.高,CSS加属性 overflow:scroll; -we ...
- Android图片加载与缓存开源框架:Android Glide
<Android图片加载与缓存开源框架:Android Glide> Android Glide是一个开源的图片加载和缓存处理的第三方框架.和Android的Picasso库类似,个人感觉 ...
随机推荐
- springMVC源码分析--HandlerAdapter(一)
HandlerAdapter的功能实际就是执行我们的具体的Controller.Servlet或者HttpRequestHandler中的方法. 类结构如下:
- springMVC源码分析--ControllerBeanNameHandlerMapping(八)
在上一篇博客springMVC源码分析--AbstractControllerUrlHandlerMapping(六)中我们介绍到AbstractControllerUrlHandlerMapping ...
- 23 服务的启动Demo2
MainActivity.java package com.qf.day23_service_demo2; import android.app.Activity; import android.co ...
- FORM开发中Profiles的使用
用户配置文件相当于系统参数,可以在不同层级(Site层.应用模块层.责任层.用户层)设置不同的值:作用范围小的覆盖范围大的层,系统已经预设了很多user profile; 开发人员也可以定义 在EBS ...
- Android监听屏幕解锁和判断屏幕状态
开发后台服务的时候经常需要对屏幕状态进行判断,如果是想要监听屏幕解锁事件,可以在配置里面注册action为 android.intent.action.USER_PRESENT的广播,则可以监听解锁事 ...
- 剑指offer面试题5 从头到尾打印链表(java)
注:(1)这里体现了java数据结构与C语言的不同之处 (2)栈的操作直接利用stack进行 package com.xsf.SordForOffer; import java.util.Stack; ...
- LInux last命令详解
命令简介: 该命令用来列出目前与过去登录系统的用户相关信息.指令英文原义:show listing of last logged in users 执行权限 :有些需要特殊权限 指令所在路径: ...
- Android简易实战教程--第十六话《SharedPreferences保存用户名和密码》
之前在Android简易实战教程--第七话<在内存中存储用户名和密码> 那里是把用户名和密码保存到了内存中,这一篇把用户名和密码保存至SharedPreferences文件.为了引起误导, ...
- git提交代码到github
前言:转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52117504 git提交代码到github 命令汇总: git init git ...
- jquery实战第一讲---概述及其入门实例
就在5月28号周四下午五点的时候,接到xxx姐姐的电话,您是xxx吗?准备一下,周五上午八点半去远洋面试,一路风尘仆仆,颠颠簸簸,由于小编晕车,带着晕晕乎乎的脑子,小编就稀里糊涂的去面试了,温馨提醒, ...