Help us understand the problem. What is going on with this article?

Chromecastにキャストするサンプルアプリ作ってみた for Android

More than 5 years have passed since last update.

Chromecastがいよいよ日本で発売されました。

スマホやChromeブラウザから、画面出力するだけでしょ?と思っている人が結構多いと思うのですが、それは、Miracastの役割でして、Chromecastは、Chromecastがインターネットにアクセスして、コンテンツを表示するのが、本来の役割です。

Android端末から、Chromecastに命令を出して、Web上のコンテンツを表示するサンプルコードを作ってみました。(エラー処理とか基本無視ですwww)

ここでは、自由にカスタマイズできるCustom Receiverを使ったものです。

試す為には、Google Cast SDK Developer契約(5ドル)払わなくてはなりませんのであしからず。

Receiverのアプリケーションは、HTML5(HTML,CSS,Javascript)で作ります。ここでは、下記のような簡単なHTMLをWebサーバにアップロードしておきます。

mini.html
<!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を記述します。

140605-0001.png

ここで、Custom Receiverを選択して

140605-0002.png

Applecation IDが発行されるので、Android側のソースコードにこのApplication IDを記述することになります。

コンテンツの準備ができたということで、次は、Android側の準備をすることになります。

Android SDK Managerで、ライブラリを追加します。

必要なのは
Android Support Library
Google Play Services
の2つです。

140605-0003.png

インストールすると、Android SDKのフォルダのextrasにインストールされるので、Eclipseでインポートします!

importするライブラリは2つです。

android-support-v7-mediarouter
google-play-services_lib

140605-0004.png

140605-0005.png

140605-0006.png

android-support-v7-mediarouterをインポートした際にエラーが出る場合がありますので、その時は、プロジェクトのプロバティで、app_compact_v7のライブラリのパスを修正してください。

140605-0007.png

これで、新規にプロジェクトを作って開発を始められます。

新規プロジェクトを作ったら、そのプロジェクトにライブラリーを追加します。

140605-0008.png

これが終わったら、今度は、Manifestファイルの設定を変更します。

Applicationタグで、Google ServiceのAPIを使うので、metaタグを追加します。

140605-0009.png

次に、Parmissionです。
Wifiで通信しますので、INTERNETのパーミッションを追加します。

140605-0010.png

Google Playにアップするなら、もっと必要ですが、動作確認には、これで十分でしょう。

MainActivity.java
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のリストを取得することができます。

実行例Logcat出力
140605-0011.png

デバイスが見つかったら、接続を行います。

MainActivity.javaの抜粋
// 最初に見つけたデバイスに接続を行う。
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();
}

その他必要なコードは下記の通りです。

MainActivity.java抜粋
    // 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)をアップデートしてありますので、必要に応じてご利用ください。

以上、ハッピーキャスティング!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした