Google Cast SDKを使ったAndroid/iOSアプリの作り方と注意点:Chromecastアプリ開発入門(終)(2/6 ページ)
メディアストリーミングデバイス「Chromecast」用アプリの開発方法を一から解説する連載。今回は、テレビ側のReceiverアプリにつなげるスマホのSenderアプリの概要と作り方、注意点、Cast Companion Libraryの使い方などを解説します。
Androidアプリ開発方法
次に、AndroidでのSenderアプリの開発方法について解説します。
依存ライブラリ
まず、Google Cast SDKが外部依存するライブラリを取り込む必要があります。
依存ライブラリの種類と、それぞれの役割は次の通りです。
- Android Support Libraries(rev 19.0.1以上)
- android-support-v7-appcompat
- Android 2系でActionBarを表示するためのライブラリ
- CastアイコンをActionBarに表示するために使う
- android-support-v7-mediarouter
- Androidスマートフォンが外部スピーカーなどの外部出力デバイスの検出・接続を管理するライブラリ
- Chromecastとの接続やCastアイコンなどのUI表示に使う
- android-support-v7-appcompat
- Google Play services SDK(rev 4.2 以上)
- google-play-services_lib
- Google Play Servicesの機能を使うためのライブラリ
- Google Cast Android APIを提供する
- Receiverアプリの起動やReceiverアプリとの通信など、Chromecastの主機能を使うために必要
- google-play-services_lib
Receiverアプリとの通信はWebSocketで行いますが、アプリ開発者は上記ライブラリのAPIを使うことでWebSocketを意識することなくプログラミングできます。
Google Cast SDK自体はGoogle Play Services SDKに同梱されているため、個別にインストールする必要はありません。ただし、Google Play Servicesに依存するため、ユーザーが「Google Play 開発者サービス」をアンインストールしたり無効にしている場合はChromecastの機能が使えない可能性があります。
コラム「Google Play Servicesとは」
Google MapsやGoogle+、Google Castなど、グーグルが提供するサービスを使ったアプリを開発できる仕組みです。Androidスマートフォンには、アプリ開発者が作ったアプリとは別にGoogle Play Servicesのアプリがインストールされており、バックグラウンドで常駐しています。
Androidの設定画面からアプリ一覧を見ると「Google Play開発者サービス」と表示されているのが、Google Play Servicesのアプリです。アプリ開発者が作ったアプリは、「Google Play開発者サービス」を介することで、これらのサービスを使えるようになります。「Google Play開発者サービス」は自動で更新されるため、アプリ開発者は自身のアプリをアップデートすることなく常に最新バージョンのサービスを使えます。
これらのライブラリの具体的な取り込み手順については、開発環境(Eclipse/Android Studio)によっても異なるため、ここでは説明を省きます。グーグルが公開しているSupport Library SetupやAndroid Sender App Developmentを参照してください。
次に、具体的な実装を見ていきます。
Chromecastデバイスでの接続概要
まずはChromecastデバイスの検索・接続・Receiverアプリの起動までを説明します。ユーザーがChromecastと接続するときはCastアイコンを使いますが、Castアイコンの実装方法には次の3通りがあります。
- MediaRouteActionProviderを使い、標準的なCastアイコンが組み込まれたActionBarを設置する
- MediaRouteButtonを使い、ActionBar以外の任意の場所に標準的なCastアイコンを設置する
- MediaRouterのAPIを使い、Castアイコンの機能を持った独自UIを開発する
1と2では、Castアイコンをタップした後、標準的なCastメニューが表示される部分も組み込まれています。3は、UIとは独立したベーシックなAPIだけを使って開発する方法で、Castアイコン・Castメニューを含めUI部分を全て自前で作成する必要があります。
公開されているサンプルプログラムMediaRouter-Cast-Button-androidにそれぞれの実装例が記述されています。
本記事では、接続に関する最低限の実装方法を理解してからUI部分について知ってもらうため、始めに3の方法を解説した後、1のMediaRouteActionProviderを使った方法を示します。
MediaRouterによるChromecastデバイスの検出と接続先選択
中心となるクラスはandroid-support-v7-mediarouterライブラリのMediaRouterクラスで、このクラスがChromecastを含めたマルチメディアの外部出力先の検出をつかさどります。その他、外部出力先を検索する条件を表したMediaRouteSelectorクラスや、検索結果が得られたときなどのコールバックを記述するMediaRouter.Callbackクラスを使います。
まず、それぞれのクラスのインスタンスを取得/生成します(コード1)。
mMediaRouter = MediaRouter.getInstance(getApplicationContext()); //【1】 mMediaRouteSelector = new MediaRouteSelector.Builder().addControlCategory( CastMediaControlIntent.categoryForCast(APPLICATION_ID)).build();//【2】 mMediaRouterCallback = new MyMediaRouterCallback();//【3】
【1】でMediaRouterクラスのインスタンスを取得し、【2】【3】でMediaRouteSelector、MediaRouter.Callbackクラスのインスタンスを生成しています。【3】のMyMediaRouterCallbackクラスはMediaRouter.Callbackインターフェースを実装したクラスで、詳細は後に記します。
【2】では、Builder()メソッドを使ってMediaRouteSelectorクラスをインスタンス化する際、「media control category」という外部出力先の種類を示す文字列を指定しています。ここではChromecastデバイスを検出したいので、CastMediaControlIntentクラスのcategoryForCast()メソッドを使ってChromecast用の文字列を生成しています。
具体的には「com.google.android.gms.cast.CATEGORY_CAST/{Application ID}」のようなReceiverアプリのApplication IDを付与した文字列となっています。
注意点として、MediaRouterをimportするパッケージは「android.support.v7.media.MediaRouter」としてください。誤って「android.media.MediaRouter」をimportしてはいけません。
次にMediaRouteSelector、MediaRouter、MediaRouter.Callbackのインスタンスを関連付け、デバイス検出時などにコールバックが呼ばれるようにします。通常はActivityのonResume()メソッドで実装します(コード2)。
mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
一方、ActivityのonPause()メソッドでは、次のようにデバイス検出のコールバックを解除する処理を行います(コード3)。
mMediaRouter.removeCallback(mMediaRouterCallback);
MediaRouter.Callbackの実装クラスMyMediaRouterCallbackでは、以下のコールバックメソッドをオーバーライドします(コード4)。
private class MyMediaRouterCallback extends MediaRouter.Callback { @Override public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) { // 新たなCastデバイスが見つかったときに呼ばれる Log.d(TAG, "onRouteAdded: info=" + info); // 見つかったデバイスの情報を保持 mMediaRoutes.add(info); } @Override public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo info) { // 見つかっていたCastデバイスを見失ったときに呼ばれる Log.d(TAG, "onRouteRemoved: info=" + info); // 見つかったデバイスの情報を削除 mMediaRoutes.remove(info); } @Override public void onRouteSelected(MediaRouter router, RouteInfo info) { // 接続先Castデバイスを選択したときに呼ばれる Log.d(TAG, "onRouteSelected: info=" + info); // 選択したデバイスを保持 mSelectedDevice = CastDevice.getFromBundle(info.getExtras()); } @Override public void onRouteUnselected(MediaRouter router, RouteInfo info) { // 接続先Castデバイスの選択を解除したときに呼ばれる Log.d(TAG, "onRouteUnselected: info=" + info); mSelectedDevice = null; } }
Castアイコンの表示は、onRouteAdded()メソッドが呼ばれて検出済みのデバイスが一つでも得られたときに行うといいでしょう。
Castメニューで検出したChromecastデバイスの一覧を表示できるよう、onRouteAdded()メソッドの引数に渡されたMediaRouter.RouteInfoインスタンスを保持しておきます。ユーザーがデバイスの一覧をタップして接続先デバイスを選んだときは、次のようにMediaRouterインスタンスに対して選んだ接続先デバイスを教えます(コード5)。
MediaRouter.RouteInfo info = mMediaRoutes.get(selected); //ユーザーが選択したデバイスに関するRouteInfoを得る mMediaRouter.selectRoute(info); //MediaRouterに選択したデバイスを教える
selectRoute()を実行すると、onRouteSelected()メソッドが呼ばれる仕組みです。
以上でMediaRouterに対して接続先デバイスを指定することができました。
Chromecastデバイスとの接続とReceiverアプリの起動
次にChromecastデバイスと接続し、Receiverアプリを起動します。
中心となるクラスはgoogle-play-services_libライブラリのGoogleApiClientクラスです。このクラスはChromecastを含むGoogle Play servicesを使うための窓口となるクラスです。
まず、必要なクラスのインスタンスを生成します(コード6)。
mCastClientListener = new CastListener(); mConnectionCallbacks = new ConnectionCallbacks(); mConnectionFailedListener = new ConnectionFailedListener(); Cast.CastOptions.Builder apiOptionsBuilder = Cast.CastOptions.builder( mSelectedDevice, mCastClientListener); mApiClient = new GoogleApiClient.Builder(this) .addApi(Cast.API, apiOptionsBuilder.build()) .addConnectionCallbacks(mConnectionCallbacks) .addOnConnectionFailedListener(mConnectionFailedListener) .build();
CastListener、ConnectionCallbacks、ConnectionFailedListenerは、それぞれCast.Listener、GoogleApiClient.ConnectionCallbacks、GoogleApiClient.OnConnectionFailedListener、で定義されているIFを実装した自作クラスで、Chromecastデバイスとの通信結果や、Receiverアプリの状態変化などのコールバックを実装しています。
各コールバックの実装例は次の通りです(コード7)。
private class CastListener implements Cast.Listener { @Override public void onApplicationStatusChanged() { // Receiverアプリの状態が変わったときに呼ばれる Log.d(TAG, "onApplicationStatusChanged"); } @Override public void onVolumeChanged() { // Receiverアプリの音量が変わったときに呼ばれる Log.d(TAG, "onVolumeChanged"); } @Override public void onApplicationDisconnected(int errorCode) { // Receiverアプリとの接続が切断したときに呼ばれる Log.d(TAG, "onApplicationDisconnected"); } } private class ConnectionCallbacks implements GoogleApiClient.ConnectionCallbacks { @Override public void onConnected(Bundle connectionHint) { // Chromecastデバイスとの接続が成功したときに呼ばれる Log.d(TAG, "onConnected"); } @Override public void onConnectionSuspended(int cause) { // Chromecastデバイスとの接続が途切れたときに呼ばれる Log.d(TAG, "onConnectionSuspended"); } } private class ConnectionFailedListener implements GoogleApiClient.OnConnectionFailedListener { @Override public void onConnectionFailed(ConnectionResult result) { // Chromecastデバイスとの接続に失敗したときに呼ばれる Log.d(TAG, "onConnectionFailed"); } }
GoogleApiClientをインスタンス化したら、次のようにしてChromecastデバイスと接続します(コード8)。
mApiClient.connect();
接続の結果によって、コード7のコールバックメソッドのいずれかが呼び出されます。
接続が成功したら、次のようにしてReceiverアプリを起動します(コード9)。
try { Cast.CastApi .launchApplication(mApiClient, APPLICATION_ID, false) .setResultCallback( new ResultCallback<Cast.ApplicationConnectionResult>() { @Override public void onResult(Cast.ApplicationConnectionResult result) { Status status = result.getStatus(); if (status.isSuccess()) { // Receiverアプリ起動成功 } else { // Receiverアプリ起動失敗 } } }); } catch (Exception e) { Log.e(TAG, "Failed to launch application", e); }
Cast.CastApiのlaunchApplication()メソッドにReceiverアプリのApplication IDを指定して起動します。setResultCallback()メソッドにはReceiverアプリ起動の結果を受け取るコールバックを設定します。
これらのアプリ起動の処理は、コード7のonConnected()メソッドが呼ばれたタイミングで実行すればいいでしょう。
以上がChromecastデバイスの検索からReceiverアプリの起動までの最小限の実装です。上記を応用すればChromecastデバイスとの接続機能を持ったUIを自由に開発できます。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- Windows OS/Androidの画面をChromecast経由でテレビに表示する
会議室のテレビにWindows OSの画面を映してプレゼンテーションしたい。でもケーブルをつなぐのはスマートではない。こんなとき、テレビにChromecastを接続し、Windows OSにGoogle Chromeをインストールすれば、画面をWi-Fi経由でテレビに表示できるようになる。 - 米グーグルがChromecastのSDKを公開
モバイル端末とTVの垣根を超えるChromecast用のSDKをGoogleが公開。Chromeの拡張機能とiOS向けのGoogle Cast SDKは即日提供を開始、Android版も数日中にリリース予定だという。 - グーグルのプレスイベントで見るグーグル新時代の幕開け
新型Nexus 7タブレットやAndroid 4.3、さらには新デバイスChromecastの発表から、グーグルの新世代戦略を読み解きます。 - YouTube動画を家中のディスプレイで再生できたら
YouTubeビデオを、ブラウザからリビングのテレビやタブレットに飛ばせたら。HTML5のPlayコマンドをテレビに送信して再生する方法を紹介します - Android L、Android Wear、Android TV、Android Autoの開発者向け現状まとめ
米グーグルが「Google I/O 2014」で発表した次期Android「Android L」「Android TV」「Android Auto」の開発者プレビュー、そして「Android Wear」の正式版。これらに対応したアプリを開発するには、どこを見ればいいのか。概要とともに簡単にまとめてみた。 - 第17回 iPhoneの画面をApple TVでテレビに表示する
iPhoneの画面をテレビに映してプレゼンしたい。こんなとき、会議室にApple TVを用意しておくと便利。たった3ステップでiPhoneの画面をテレビに映せるようになる。 - Windows OSの画面をApple TV経由でテレビに表示する
会議室のテレビにWindows OSの画面を映してプレゼンテーションしたい。でもケーブルをつなげるのは少々スマートではない。こんなとき、テレビにApple TVを接続し、Windows OSに「AirParrot」をインストールすれば、画面をWi-Fi経由でテレビに表示できるようになる。 - WebSocketでスマートテレビをリアル接続するぷらら
ひかりTV独自のスマートテレビリモコンの接続方法はWebSocketを用いた常時接続だ。その仕組みと開発意図を聞いた。 - さまざまなデバイスがWebと結び付いていく
テレビやカーナビ、家電とWebが連携していく「Web of Things」。NHKなど、最前線の取り組みが語られたカンファレンスをレポートする - テレビのスマート化とYouTubeのテレビ化
YouTubeなどネットの攻勢に対し、何もしないと「テレビは死ぬ」。それは明らかだ。テレビ局がよいサービスを開発できるかどうかが要となる。 - スマートテレビはチャンスだぞ
テレビもスマート、なんだと。アメリカからGoogle TVやApple TVがやってくる。米テレビ局の映像配信Huluも上陸している。もちろん、日本だって手を打っている - 今度こそテレビとWebの統合なるか:「Google TV」は従来のWebテレビと何が違うのか?
- 頭脳放談第120回:Google TVがVIA Technologiesも救う?
- WebとUIをつなぐトリックスター(2):テレビでYahoo!デバイスが変わればUIデザインも変わる
制作の要となるエンジニアとデザイナのチームワークのツボを探る連載。今回はヤフーのテレビ向けサービスのデザイン担当に話を聞いた