Android センダーアプリを Cast SDK v2 から Cast Application Framework(CAF)に移行する

次の手順では、Android 送信アプリを Cast SDK v2 から、CastContext シングルトンに基づく CAF Sender に変換します。

Cast CAF Sender SDK は、CastContext を使用して GoogleAPIClient を管理します。CastContext はライフサイクル、エラー、コールバックを管理するため、Cast アプリの開発が大幅に簡素化されます。

はじめに

  • CAF Sender は、Android SDK マネージャーを使用して Google Play 開発者サービスの一部として引き続き配布されます。
  • Google Cast デザイン チェックリスト(com.google.android.gms.cast.framework.*)に準拠する責任を負う新しいパッケージが追加されました
  • CAF Sender は、Cast UX 要件に準拠したウィジェットを提供します。v2 では UI コンポーネントが提供されず、これらのウィジェットを実装する必要がありました。
  • Cast API の使用に GoogleApiClient を使用する必要がなくなりました。
  • CAF Sender の字幕は v2 に似ています。

依存関係

V2 と CAF は、サポート ライブラリ機能ガイドで説明されているように、サポート ライブラリと Google Play 開発者サービス(9.2.0 以降)に同じ依存関係があります。

CAF がサポートする Android SDK の最小バージョンは 9(Gingerbread)です。

初期化

CAF では、Cast フレームワークに明示的な初期化ステップが必要です。これには、CastContext シングルトンを初期化し、適切な OptionsProvider を使用してウェブレシーバー アプリケーション ID とその他のグローバル オプションを指定します。

public class CastOptionsProvider implements OptionsProvider {

    @Override
    public CastOptions getCastOptions(Context context) {
        return new CastOptions.Builder()
                .setReceiverApplicationId(context.getString(R.string.app_id))
                .build();
    }

    @Override
    public List<SessionProvider> getAdditionalSessionProviders(Context context) {
        return null;
    }
}

アプリの AndroidManifest.xml ファイルの「application」タグ内で OptionsProvider を宣言します。

<application>
...
    <meta-data
        android:name=
            "com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
        android:value="com.google.sample.cast.refplayer.CastOptionsProvider" />
</application>

各アクティビティの onCreate メソッドで CastContext を必要に応じて初期化します。

private CastContext mCastContext;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.video_browser);
    setupActionBar();

    mCastContext = CastContext.getSharedInstance(this);
}

これらの手順は v2 では必要ありませんでした。

デバイス検出

CAF では、アプリがフォアグラウンドに移行すると検出プロセスがフレームワークによって自動的に開始され、バックグラウンドに移行すると停止されます。MediaRouteSelectorMediaRouter.Callback は使用しないでください。

キャスト ボタンとキャスト ダイアログ

v2 と同様に、これらのコンポーネントは MediaRouter サポート ライブラリによって提供されます。

キャスト ボタンは引き続き MediaRouteButton によって実装され、メニューのメニュー項目として(ActionBar または Toolbar を使用して)アクティビティに追加できます。

<item
    android:id="@+id/media_route_menu_item"
    android:title="@string/media_route_menu_title"
    app:actionProviderClass="android.support.v7.app.MediaRouteActionProvider"
    app:showAsAction="always"/>

CastButtonFactory を使用して MediaRouteButton をキャスト フレームワークに接続するように、各アクティビティの onCreateOptionMenu() メソッドをオーバーライドします。

private MenuItem mediaRouteMenuItem;

public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    getMenuInflater().inflate(R.menu.browse, menu);
    mediaRouteMenuItem =
        CastButtonFactory.setUpMediaRouteButton(getApplicationContext(),
                                                menu,
                                                R.id.media_route_menu_item);
    return true;
}

ユーザーがボタンをタップすると、キャスト ダイアログが自動的に表示されます。

デバイス コントロール

CAF では、デバイスの制御は大部分がフレームワークによって処理されます。送信側のアプリは、デバイスへの接続と GoogleApiClient を使用したウェブ レシーバー アプリの起動を処理する必要はありません(処理しようとしないでください)。送信者とウェブ受信者の間のインタラクションが「セッション」として表されるようになりました。SessionManager クラスはセッションのライフサイクルを処理し、ユーザーの操作に応じてセッションを自動的に開始および停止します。セッションは、ユーザーがキャスト ダイアログでキャスト デバイスを選択すると開始され、ユーザーがキャスト ダイアログで [キャストを停止] ボタンをタップするか、送信元アプリ自体が終了すると終了します。送信側のアプリは、SessionManagerSessionManagerListener を登録することで、セッション ライフサイクル イベントの通知を受け取ることができます。SessionManagerListener コールバックは、すべてのセッション ライフサイクル イベントのコールバック メソッドを定義します。

CastSession クラスは、Cast デバイスとのセッションを表します。このクラスには、デバイスの音量とミュート状態を制御するメソッドがあります。これは、以前の v2 では Cast.CastApi のメソッドを使用して行われていました。

v2 では、Cast.Listener コールバックにより、デバイスの状態(音量、ミュート状態、スタンバイ ステータスなど)の変更に関する通知が提供されていました。

CAF では、音量/ミュート状態の変化通知は引き続き Cast.Listener のコールバック メソッドを介して配信されます。これらのリスナーは CastSession に登録されます。残りのデバイス状態通知はすべて CastStateListener コールバックを介して配信されます。これらのリスナーは CastSession に登録されます。関連するフラグメント、アクティビティ、アプリがバックグラウンドに移動したときに、リスナーの登録を解除してください。

再接続ロジック

v2 と同様に、CAF は、一時的な Wi-Fi 信号の喪失やその他のネットワーク エラーにより切断されたネットワーク接続を再確立しようとします。これはセッションレベルで行われるようになりました。セッションは、接続が失われたときに「一時停止」状態になり、接続が復元されると「接続済み」状態に戻ります。このプロセスの一環として、フレームワークがウェブレシーバー アプリケーションへの再接続と、キャスト チャネルの再接続を行います。

また、CAF には、デフォルトで有効になっている自動セッション再開機能も追加されています(CastOptions で無効にできます)。Cast セッションの進行中に送信元アプリがバックグラウンドに送信された場合、または(スワイプして)終了した場合、またはクラッシュした場合、送信元アプリがフォアグラウンドに戻ったとき、または再起動されたときに、フレームワークはそのセッションを再開しようとします。これは SessionManager によって自動的に処理され、登録された SessionManagerListener インスタンスに対して適切なコールバックが発行されます。

カスタム チャネルの登録

v2 では、カスタム チャネル(Cast.MessageReceivedCallback を使用して実装)は Cast.CastApi に登録されます。CAF では、カスタム チャンネルは CastSession インスタンスに登録されます。登録は SessionManagerListener.onSessionStarted コールバック メソッドで行うことができます。メディア アプリケーションでは、Cast.CastApi.setMessageReceivedCallbacks を介してメディア コントロール チャネルを明示的に登録する必要がなくなりました。詳細については、次のセクションをご覧ください。

メディア コントロール

v2 クラス RemoteMediaPlayer は非推奨であるため、使用しないでください。CAF では、より便利な API で同等の機能を提供する新しい RemoteMediaClient クラスに置き換えられています。このオブジェクトを明示的に初期化または登録する必要はありません。接続先のウェブ レシーバー アプリケーションがメディア ネームスペースをサポートしている場合、フレームワークはオブジェクトを自動的にインスタンス化し、セッション開始時に基盤となるメディア チャネルを登録します。

RemoteMediaClient には、CastSession オブジェクトの getRemoteMediaClient メソッドとしてアクセスできます。

v2 では、RemoteMediaPlayer で発行されたすべてのメディア リクエストは、PendingResult コールバックを介して RemoteMediaPlayer.MediaChannelResult を返します。

CAF では、RemoteMediaClient で発行されたすべてのメディア リクエストは、PendingResult コールバックを介して RemoteMediaClient.MediaChannelResult を返します。このコールバックは、リクエストの進行状況と最終的な結果を追跡するために使用できます。

v2 RemoteMediaPlayer は、RemoteMediaPlayer.OnStatusUpdatedListener を介してウェブリシーバーのメディア プレーヤーの状態の変化に関する通知を送信します。

CAF では、RemoteMediaClientRemoteMediaClient.Listener インターフェースを介して同等のコールバックを提供します。RemoteMediaClient には任意の数のリスナーを登録できます。これにより、複数の送信側コンポーネントが、セッションに関連付けられた RemoteMediaClient の単一インスタンスを共有できます。

v2 では、センダー アプリケーションがユーザー インターフェースを Web レシーバーのメディア プレーヤーの状態と同期させるという負担を負っていました。

CAF では、クラス UIMediaController がこの責任のほとんどを担います。

案内用のオーバーレイ

V2 には、導入用オーバーレイ UI はありません。

CAF には、ユーザーに初めてキャスト アイコンを表示する際にハイライト表示するためのカスタムビュー IntroductoryOverlay が用意されています。

ミニ コントローラ

v2 では、送信側アプリにミニ コントローラをゼロから実装する必要があります。

CAF では、SDK に MiniControllerFragment というカスタムビューが用意されており、これをミニ コントローラを表示するアクティビティのアプリ レイアウト ファイルに追加できます。

通知とロック画面

v2 では、通知とロック画面のコントローラは SDK から提供されません。この SDK では、Android フレームワーク API を使用して、これらの機能を送信元アプリに組み込む必要があります。

CAF では、SDK に NotificationsOptions.Builder が用意されており、送信側アプリに通知とロック画面用のメディア コントロールを構築できます。通知とロック画面のコントロールは、CastContext を初期化するときに CastOptions で有効にできます。

public CastOptions getCastOptions(Context context) {
    NotificationOptions notificationOptions = new NotificationOptions.Builder()
            .setTargetActivityClassName(VideoBrowserActivity.class.getName())
            .build();
    CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
            .setNotificationOptions(notificationOptions)
            .build();

    return new CastOptions.Builder()
            .setReceiverApplicationId(context.getString(R.string.app_id))
            .setCastMediaOptions(mediaOptions)
            .build();
}

拡張コントローラ

v2 では、拡張コントローラを送信側アプリにゼロから実装する必要があります。

CAF には、独自の拡張コントローラを簡単に構築できる UIMediaController ヘルパークラスが用意されています。

CAF には、アプリに簡単に追加できる、ビルド済みの拡張コントローラ ウィジェット ExpandedControllerActivity が追加されています。UIMediaController を使用してカスタム拡張コントローラを実装する必要がなくなりました。

音声フォーカス

v2 では、MediaSessionCompat を使用して音声フォーカスを管理する必要があります。

CAF では、音声フォーカスは自動的に管理されます。

デバッグログ

CAF にはロギング オプションはありません。

サンプルアプリ

CAF を使用するCodelab チュートリアルサンプルアプリがあります。