アプリで MediaRouter フレームワークを使用するには、インスタンスを取得する必要があります。
MediaRouter
オブジェクトの
ルーティング イベントをリッスンする MediaRouter.Callback
オブジェクト。
メディアルートを介して送信されたコンテンツは、ルートの
関連付けられた MediaRouteProvider
(ただし、
Bluetooth 出力デバイスなどです。図 1 は、
デバイス間でのコンテンツのルーティングに使用されるクラス。
注: アプリで Google Cast デバイス、 Cast SDK キャスト センダーとしてアプリをビルドします。 Cast のドキュメント 直接使用するのではなく
メディアルート ボタン
Android アプリでは、メディアルート ボタンを使用してメディアのルーティングを制御します。MediaRouter フレームワーク ユーザーがルーティングを認識して使用する際に役立つ、ボタンの標準インターフェースを提供する 提供しますメディアルート ボタンは通常、 アプリのアクションバーに追加できます(図 2 を参照)。
ユーザーがメディアルート ボタンを選択すると、利用可能なメディアルートのリストが表示されます(図 3 参照)。
メディアルート ボタンの作成手順は次のとおりです。
- AppCompatActivity を使用する
- メディアルート ボタンのメニュー項目を定義する
- MediaRouteSelector を作成する
- メディアルート ボタンをアクションバーに追加する
- アクティビティのライフサイクルで MediaRouter.Callback メソッドを作成し管理する
このセクションでは、最初の 4 つの手順について説明します。Callback メソッドについては、その次のセクションで説明します。
AppCompatActivity を使用する
アクティビティでメディア ルーター フレームワークを使用する場合は、
AppCompatActivity
からアクティビティを実行し、
パッケージ androidx.appcompat.app
。必ず
androidx.appcompat:appcompat
および androidx.mediarouter:mediarouter
サポート ライブラリをアプリ開発プロジェクトに追加できます。サポート ライブラリの追加や
Android Jetpack のスタートガイドをご覧ください。
注意: 必ず androidx
を使用してください。
メディア ルーター フレームワークの実装。古い 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="androidx.mediarouter.app.MediaRouteActionProvider" app:showAsAction="always" /> </menu>
MediaRouteSelector を作成する
メディアルート ボタンのメニューに表示されるルートは、MediaRouteSelector
によって決まります。
AppCompatActivity
からアクティビティを延長します
アクティビティの作成時に MediaRouteSelector.Builder
を呼び出してセレクタを作成します。
onCreate() メソッドから
示されています。セレクタはクラス変数に保存され、許容されるルートタイプが指定されることに注意してください。
MediaControlIntent
オブジェクトを追加します。
Kotlin
class MediaRouterPlaybackActivity : AppCompatActivity() { private var mSelector: MediaRouteSelector? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Create a route selector for the type of routes your app supports. mSelector = MediaRouteSelector.Builder() // These are the framework-supported intents .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) .build() } }
Java
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、
メーカーによっては、「セカンダリ出力」と呼ばれる特別なルーティング オプションをサポートしています。このルーティングでは
メディアアプリは、動画や音楽を、選択したリモート受信デバイスの画面やスピーカーに直接取得、レンダリング、ストリーミングします。
セカンダリ出力を使用すれば、ワイヤレス対応の音楽システムやビデオ ディスプレイにコンテンツを送信できます。検出と検出を有効にするには、
選択するには、該当するデバイス ID を
CATEGORY_LIVE_AUDIO
または
CATEGORY_LIVE_VIDEO
コントロール カテゴリを MediaRouteSelector に渡します。さらに、独自の Presentation
ダイアログを作成して処理する必要があります。
メディアルート ボタンをアクションバーに追加する
メディアルート メニューと MediaRouteSelector が定義されたので、アクティビティにメディアルート ボタンを追加できるようになりました。
アクティビティごとに onCreateOptionsMenu()
メソッドをオーバーライドして、オプションを追加します。
選択します。
Kotlin
override fun onCreateOptionsMenu(menu: Menu): Boolean { super.onCreateOptionsMenu(menu) // Inflate the menu and configure the media router action provider. menuInflater.inflate(R.menu.sample_media_router_menu, menu) // Attach the MediaRouteSelector to the menu item val mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item) val mediaRouteActionProvider = MenuItemCompat.getActionProvider(mediaRouteMenuItem) as MediaRouteActionProvider // Attach the MediaRouteSelector that you built in onCreate() selector?.also(mediaRouteActionProvider::setRouteSelector) // Return true to show the menu. return true }
Java
@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(selector); // Return true to show the menu. return true; }
アプリにアクションバーを実装する方法について詳しくは、 アクションバーを確認します。 ご覧ください。
任意のメディアルート ボタンを MediaRouteButton
として追加することもできます。
表示されます。setRouteSelector()
メソッドを使用して、MediaRouteSelector をボタンにアタッチする必要があります。詳しくは、
Google Cast の設計チェックリスト
をご覧ください。
MediaRouter コールバック
同じデバイスで実行されるすべてのアプリは、単一の MediaRouter
インスタンスとそのルートを共有します。
(アプリの MediaRouteSelector によってアプリごとにフィルタされます)。各アクティビティは MediaRouter と通信します。
MediaRouter.Callback
の独自の実装を使用する
あります。MediaRouter は、ユーザーがルートを選択、変更、接続解除するたびに、コールバック メソッドを呼び出します。
このコールバックには、以下に関する情報を受け取るためにオーバーライドできるメソッドがいくつかあります。
ルーティングイベントがあります少なくとも、MediaRouter.Callback
クラスの実装では、
onRouteSelected()
と
onRouteUnselected()
。
MediaRouter は共有リソースであるため、アプリで MediaRouter コールバックを管理する必要があります。 通常のアクティビティのライフサイクル コールバックに応答します。
- アクティビティが作成されたとき(
onCreate(Bundle)
)にMediaRouter
へのポインタを取得し、アプリの有効期間中はそのポインタを保持する。 - アクティビティが表示されるようになったときにコールバックを MediaRouter にアタッチし(
onStart()
)、非表示のときにデタッチする (onStop()
)。
次のコードサンプルは、
コールバック オブジェクトを作成して保存する、
MediaRouter
のインスタンスの取得とコールバックの管理方法を取得します。
onStart()
でコールバックをアタッチするときに CALLBACK_FLAG_REQUEST_DISCOVERY
フラグを使用している点に注意してください。
これにより、MediaRouteSelector はメディアルート ボタンの
利用可能なルートのリストです。
Kotlin
class MediaRouterPlaybackActivity : AppCompatActivity() { private var mediaRouter: MediaRouter? = null private var mSelector: MediaRouteSelector? = null // Variables to hold the currently selected route and its playback client private var mRoute: MediaRouter.RouteInfo? = null private var remotePlaybackClient: RemotePlaybackClient? = null // Define the Callback object and its methods, save the object in a class variable private val mediaRouterCallback = object : MediaRouter.Callback() { override fun onRouteSelected(router: MediaRouter, route: MediaRouter.RouteInfo) { 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 remotePlaybackClient = RemotePlaybackClient(this@MediaRouterPlaybackActivity, mRoute) // Start remote playback (if necessary) // ... } } override fun onRouteUnselected( router: MediaRouter, route: MediaRouter.RouteInfo, reason: Int ) { Log.d(TAG, "onRouteUnselected: route=$route") if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) { // Changed route: tear down previous client mRoute?.also { remotePlaybackClient?.release() remotePlaybackClient = null } // Save the new route mRoute = route when (reason) { MediaRouter.UNSELECT_REASON_ROUTE_CHANGED -> { // Resume local playback (if necessary) // ... } } } } } // Retain a pointer to the MediaRouter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Get the media router service. mediaRouter = MediaRouter.getInstance(this) ... } // Use this callback to run your MediaRouteSelector to generate the // list of available media routes override fun onStart() { mSelector?.also { selector -> mediaRouter?.addCallback(selector, mediaRouterCallback, 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 fun onStop() { mediaRouter?.removeCallback(mediaRouterCallback) super.onStop() } ... }
Java
public class MediaRouterPlaybackActivity extends AppCompatActivity { private MediaRouter mediaRouter; private MediaRouteSelector mSelector; // Variables to hold the currently selected route and its playback client private MediaRouter.RouteInfo mRoute; private RemotePlaybackClient remotePlaybackClient; // Define the Callback object and its methods, save the object in a class variable private final MediaRouter.Callback mediaRouterCallback = 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 remotePlaybackClient = 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 && remotePlaybackClient != null) { remotePlaybackClient.release(); remotePlaybackClient = 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. mediaRouter = MediaRouter.getInstance(this); ... } // Use this callback to run your MediaRouteSelector to generate the list of available media routes @Override public void onStart() { mediaRouter.addCallback(mSelector, mediaRouterCallback, 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() { mediaRouter.removeCallback(mediaRouterCallback); super.onStop(); } ... }
メディア ルーター フレームワークは、
MediaRouteDiscoveryFragment
クラスは、
アクティビティのコールバックを削除する
注: 音楽再生アプリの作成中に、そのアプリで再生したい音楽がある場合は、
バックグラウンドで音楽を再生するには、再生用の Service
を作成する必要があります。
Service のライフサイクル コールバックからメディア ルーター フレームワークを呼び出します。
リモート再生ルートの制御
リモート再生ルートを選択した場合は、アプリはリモコンとして機能します。経路の反対側にあるデバイス
は、コンテンツ データの取得、デコード、再生のすべての機能を処理します。アプリの UI のコントロールは、
RemotePlaybackClient
オブジェクト。
RemotePlaybackClient
クラスには、追加のメソッドが用意されています。
コンテンツ再生の管理に使用できます。以下に、RemotePlaybackClient
クラスの主要な再生メソッドをいくつか示します。
play()
- 特定の曲を再生するUri
で指定されたメディア ファイル。pause()
- 一時停止します。 再生中のメディア トラック。resume()
- 続行 一時停止コマンドの後、現在のトラックを再生するseek()
- 特定の場所に移動する 現在のトラックの位置を示します。release()
- 破棄します。 接続する必要があります。
以下のメソッドを使用して、 。これらのメソッドのほとんどは、コールバック オブジェクトを含めることができるので、 再生タスクまたはコントロール リクエストの進行状況。
RemotePlaybackClient
クラスは、
メディアキューの再生と管理のための複数のメディア アイテム。
サンプルコード
Android BasicMediaRouter および MediaRouter サンプルでは、MediaRouter API の使用方法をさらに詳しく説明しています。