Chromecastがいよいよ日本で発売されました。
スマホやChromeブラウザから、画面出力するだけでしょ?と思っている人が結構多いと思うのですが、それは、Miracastの役割でして、Chromecastは、Chromecastがインターネットにアクセスして、コンテンツを表示するのが、本来の役割です。
Android端末から、Chromecastに命令を出して、Web上のコンテンツを表示するサンプルコードを作ってみました。(エラー処理とか基本無視ですwww)
ここでは、自由にカスタマイズできるCustom Receiverを使ったものです。
試す為には、Google Cast SDK Developer契約(5ドル)払わなくてはなりませんのであしからず。
Receiverのアプリケーションは、HTML5(HTML,CSS,Javascript)で作ります。ここでは、下記のような簡単なHTMLをWebサーバにアップロードしておきます。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<style type="text/css">
body {
overflow:hidden;
}
div {
height:720PX;
width:1280PX;
text-align:center;
border:0px solid silver;
display: table-cell;
vertical-align:middle;
color:#FFFFFF;
background-color:#000000;
font-weight:bold;
font-family:Verdana, Geneva, sans-serif;
font-size:40px;
}
</style>
<title>Chromecastテストページ</title>
<script src="//www.gstatic.com/cast/sdk/libs/receiver/2.0.0/cast_receiver.js"></script>
<script type="text/javascript">
window.onload = function() {
cast.receiver.logger.setLevelValue(0);
window.castReceiverManager = cast.receiver.CastReceiverManager.getInstance();
console.log('Starting Receiver Manager');
// handler for the 'ready' event
castReceiverManager.onReady = function(event) {
console.log('Received Ready event: ' + JSON.stringify(event.data));
window.castReceiverManager.setApplicationState("Application status is ready...");
};
// handler for 'senderconnected' event
castReceiverManager.onSenderConnected = function(event) {
console.log('Received Sender Connected event: ' + event.data);
console.log(window.castReceiverManager.getSender(event.data).userAgent);
};
// handler for 'senderdisconnected' event
castReceiverManager.onSenderDisconnected = function(event) {
console.log('Received Sender Disconnected event: ' + event.data);
if (window.castReceiverManager.getSenders().length == 0) {
window.close();
}
};
// handler for 'systemvolumechanged' event
castReceiverManager.onSystemVolumeChanged = function(event) {
console.log('Received System Volume Changed event: ' + event.data['level'] + ' ' +
event.data['muted']);
};
// initialize the CastReceiverManager with an application status message
window.castReceiverManager.start({statusText: "Application is starting"});
console.log('Receiver Manager started');
};
</script>
</head>
<body>
<div>Chromecastテストぺーじだよ〜〜〜ん</div>
</body>
</html>
Google Cast SDK Developer Console上では、mini.htmlを置いたサイトのURLを記述します。
ここで、Custom Receiverを選択して
Applecation IDが発行されるので、Android側のソースコードにこのApplication IDを記述することになります。
コンテンツの準備ができたということで、次は、Android側の準備をすることになります。
Android SDK Managerで、ライブラリを追加します。
必要なのは
Android Support Library
Google Play Services
の2つです。
インストールすると、Android SDKのフォルダのextrasにインストールされるので、Eclipseでインポートします!
importするライブラリは2つです。
android-support-v7-mediarouter
google-play-services_lib
android-support-v7-mediarouterをインポートした際にエラーが出る場合がありますので、その時は、プロジェクトのプロバティで、app_compact_v7のライブラリのパスを修正してください。
これで、新規にプロジェクトを作って開発を始められます。
新規プロジェクトを作ったら、そのプロジェクトにライブラリーを追加します。
これが終わったら、今度は、Manifestファイルの設定を変更します。
Applicationタグで、Google ServiceのAPIを使うので、metaタグを追加します。
次に、Parmissionです。
Wifiで通信しますので、INTERNETのパーミッションを追加します。
Google Playにアップするなら、もっと必要ですが、動作確認には、これで十分でしょう。
package com.example.castcast;
import com.google.android.gms.cast.CastMediaControlIntent;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.media.MediaRouteSelector;
import android.support.v7.media.MediaRouter;
import android.support.v7.media.MediaRouter.RouteInfo;
import android.util.Log;
public class MainActivity extends Activity
{
private String TAG = "test";
// Google Cast SDK Developer Consoleから取得した Application IDを設定してください
private static String APPLICATION_ID = "hogehoge";
// Chromecastを探索するのに使う変数類
private MediaRouter mRouter;
private MediaRouteSelector mMediaRouteSelector;
private MediaRouter.Callback mCB;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Chromecastを探す準備
mRouter = MediaRouter.getInstance(this);
mMediaRouteSelector = new MediaRouteSelector.Builder().addControlCategory(CastMediaControlIntent.categoryForCast(APPLICATION_ID)).build();
mCB = new MediaRouter.Callback()
{
@Override
public void onRouteAdded(MediaRouter router, RouteInfo route)
{
Log.d(TAG,"onRouteAdded=" + route.getName());
}
@Override
public void onRouteRemoved(MediaRouter router, RouteInfo route)
{
Log.d(TAG,"onRouteRemoved" + route.getName());
}
};
}
@Override
protected void onResume()
{
super.onResume();
// Chromecastを探す
mRouter.addCallback(mMediaRouteSelector, mCB,MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
}
@Override
protected void onPause()
{
if (isFinishing())
{
mRouter.removeCallback(mCB);
}
super.onPause();
}
}
これだけのソースで、同一ネットワークに接続されているChromecastのリストを取得することができます。
デバイスが見つかったら、接続を行います。
// 最初に見つけたデバイスに接続を行う。
if(mSelectedDevice == null)
{
mSelectedDevice = CastDevice.getFromBundle(route.getExtras());
Cast.CastOptions.Builder apiOptionsBuilder = Cast.CastOptions.builder(mSelectedDevice, mCastClientListener);
apiOptionsBuilder.setVerboseLoggingEnabled(true);
mApiClient = new GoogleApiClient.Builder(getBaseContext())
.addApi(Cast.API, apiOptionsBuilder.build())
.addConnectionCallbacks(mConnectionCallbacks)
.addOnConnectionFailedListener(mConnectionFailedListener)
.build();
mApiClient.connect();
}
その他必要なコードは下記の通りです。
// Chromecastに接続確認用コールバック
private GoogleApiClient.ConnectionCallbacks mConnectionCallbacks = new GoogleApiClient.ConnectionCallbacks()
{
@Override
public void onConnected(Bundle connectionHint)
{
Log.d(TAG,"onConnected");
try
{
Cast.CastApi.launchApplication(mApiClient, APPLICATION_ID, false)
.setResultCallback(new ResultCallback<Cast.ApplicationConnectionResult>()
{
@Override
public void onResult(ApplicationConnectionResult result)
{
Status status = result.getStatus();
if (status.isSuccess())
{
mSessionId = result.getSessionId();
Log.d(TAG,"mSessionID=" + mSessionId);
}
}
});
}
catch(Exception ex)
{
Log.d(TAG,ex.toString());
}
}
@Override
public void onConnectionSuspended(int cause)
{
}
};
// Chromecastに接続失敗した場合に呼ばれる
private GoogleApiClient.OnConnectionFailedListener mConnectionFailedListener = new GoogleApiClient.OnConnectionFailedListener()
{
@Override
public void onConnectionFailed(ConnectionResult result)
{
}
};
// Chromecastとの接続を解除する
private void peardown()
{
if (mApiClient != null)
{
if (mApiClient.isConnected())
{
try
{
Cast.CastApi.stopApplication(mApiClient, mSessionId);
}
catch (Exception e)
{
Log.e(TAG, "Exception while removing channel", e);
}
mApiClient.disconnect();
}
mApiClient = null;
mSelectedDevice = null;
mSessionId = null;
}
}
GitHubに動くプロジェクトファイル一式(SampleCast)をアップデートしてありますので、必要に応じてご利用ください。
以上、ハッピーキャスティング!