一、功能描述

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服务中。该接口用于远程控制路由类型。

11)、public void removeRemoteControlClient(Object remoteControlClient)

注销先前登记的RemoteControlClient对象。

二)、MediaRouteProvider与MediaRouteProvider. RouteController

这两个类都是抽象类。MediaRouteProvider及其控制类主要提供如下功能:

  1. MediaRouteProvider的功能是描述和发布接收设备的能力;

  2. 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 的媒体路由功能应用与框架解析相关推荐

  1. Android 的媒体路由功能应用与框架解析 MediaRouter

    一.功能描述 Android的媒体路由API被设计用来允许多种媒体(视频.音乐.图片)在与ANDROID设备连接(无线或有线)的辅助设备(如电视.立体声.家庭戏院系统.音乐播放机)上显示和播放,使用该 ...

  2. Android添加拍照功能,Android开发实现拍照功能的方法实例解析

    本文实例讲述了Android开发实现拍照功能的方法.分享给大家供大家参考,具体如下: 解析: 1)判断是否有摄像头checkCameraHardware(this) 2)获得相机camera = Ca ...

  3. android实现相机功能,Android开发实现拍照功能的方法实例解析

    本文实例讲述了Android开发实现拍照功能的方法.分享给大家供大家参考,具体如下: 解析: 1)判断是否有摄像头checkCameraHardware(this) 2)获得相机camera = Ca ...

  4. Android项目解耦--路由框架ARouter的使用

    Android项目解耦–路由框架ARouter源码解析 前言 随着业务量的增长,客户端必然随之越来越业务和功能模块耦合越来越生,开发人员代码维护成本越来越高. App一般都会走向组件化.插件化的道路, ...

  5. Android项目解耦--路由框架ARouter源码解析

    前言 上一篇文章Android项目解耦–路由框架ARouter的使用讲述了ARouter在项目中的使用,这边文章主要对ARouter的源码进行学习和分析. ARouter的结构 ARouter主要由三 ...

  6. Android平台页面路由框架ARouter原理

    本次分享将主要围绕以下几个方面: 一.为什么需要路由框架 二.ARouter的技术方案 三.使用ARouter的最佳实践 四.未来开发计划 一.为什么需要路由框架 原生的路由方案存在的问题 首先谈一谈 ...

  7. PHP简单实现MVC框架路由功能模式

    说到使用PHP进行网站开发,自然离不开各种PHP的开发框架,开发框架为我们提供了灵活的开发方式,MVC层分离,业务解耦等等,让我们的开发更为快捷方便.但是很多人只是会使用框架,却从来不去了解框架的内部 ...

  8. android 功能清单文件夹,全新Android L大小全部功能清单整理

    今天凌晨,谷歌在美国旧金山发布全新安卓系统 Android L,该系统预计今年秋季发布,在此之前先向开发者提供. 在凌晨的主题演讲中,谷歌表示全新安卓系统将为用户提供全新的使用体验,比如 Projec ...

  9. Android 9.0 蓝牙功能之一:蓝牙音乐

    Android 9.0 蓝牙功能之一:蓝牙音乐 本章节记录如何构建蓝牙音乐. 文章目录 Android 9.0 蓝牙功能之一:蓝牙音乐 主要流程 相关代码 其他要点: 蓝牙AG_EVENT广播 (手机 ...

最新文章

  1. Centos7更改root密码
  2. 电脑怎么python转行_零基础转行DA系列|一周Python for Data Science入门
  3. 洛谷P5110:块速递推(特征根方程、光速幂)
  4. Java 8默认方法可能会破坏您的(用户)代码
  5. docker 镜像 导入导出
  6. 2019全球编程语言高薪排行榜登场;余承东正式宣布华为IFA2019 或发布麒麟990;OPPO、vivo和小米成立互传联盟…...
  7. Centos6.4下安装mysql5.6.10
  8. 浙江大学 PTA习题3.6 一元多项式的乘法与加法运算 (20分)
  9. Office 2013中mathtype 6.x的安装方法简介
  10. 九、全面提高人民生话水平
  11. mysql_fetch_row()获取显示数据
  12. ftfind 桌面搜索引擎的设计文档 (2)
  13. 机房收费系统---可行性研究报告
  14. 教你用安卓神器-APK编辑器(手机端)改程序名+去程序广告!
  15. 蔡颖-《APS走向实践》书解读之一:APS优化供应链从绩效指标开始
  16. 元宇宙被这个圈子带火了一波,是我没想到的
  17. Qt官方示例-正则测试工具
  18. DAMA数据管理知识体系简介
  19. android装windows bios,普通安卓平板刷win10图文教程
  20. 英雄联盟账号服务器查询,lol战绩查询系统

热门文章

  1. Android App包瘦身优化
  2. 区块链能否助力版权“突围”?
  3. 三星S5终于降临 4月上市开卖的新机盘点
  4. python入门指南by许半仙百度云-《江火欲燃山》《这题超纲了》《Python入门指南》...
  5. php杂谈【基础篇】之_7.PHP涉及的所有英文单词
  6. Selenium学习 - 库代码解析
  7. 目标跟踪数据集GOT-10k的配置
  8. [前端框架]-VUE(下篇)
  9. 如何培养自己的赚钱能力
  10. 教你在MathType中输入空心字和花体字的重要方法