Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 的媒體路由功能應用與框架解析

Android 的媒體路由功能應用與框架解析

編輯:關於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 getRoutes()

獲得當前發現的所有媒體路由信息的一個列表,媒體路由框架對於每一個發現的媒體路由都用一個RouteInfo對象表示。一個媒體路由提供設備可能包含多個媒體路由。

3)、public List 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函數來啟動。整個流程如下:

    \


    版權所有,轉載時請尊重原創清楚注明鏈接和出處!

     
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved