メディア セッションの使用

メディア セッションは、それが管理するプレーヤーとともに存在します。メディア セッションの作成と初期化は、そのメディア セッションと関連プレーヤーを所有するアクティビティまたはサービスの onCreate() メソッドで行います。

メディア セッションの初期化

作成したばかりのメディア セッションには何の機能もありません。次の手順を行って、セッションを初期化する必要があります。

  • メディア セッションがメディア コントローラやメディアボタンからのコールバックを受信できるようにフラグを設定します。
  • PlaybackStateCompat のインスタンスを作成して初期化し、セッションに割り当てます。再生状態はセッション全体を通して変化するため、PlaybackStateCompat.Builder を再利用できるようキャッシュに保存しておくことをおすすめします。
  • MediaSessionCompat.Callback のインスタンスを作成し、セッションに割り当てます(詳細は下記コールバックの説明を参照)。

メディア セッションの作成と初期化は、そのセッションを所有するアクティビティまたはサービスonCreate() メソッドで行います。

アプリが新たに初期化(または停止)されたときにメディアボタンを機能させるには、その PlaybackState に、メディアボタンが送信するインテントと一致する再生アクションが含まれている必要があります。これが、初期化中に ACTION_PLAY をセッション状態に割り当てる理由です。詳細については、メディアボタンへの応答をご覧ください。

再生状態とメタデータの維持

メディア セッションの状態を表すクラスは 2 種類あります。

PlaybackStateCompat クラスは、プレーヤーの現在の動作状態を表します。これには、以下が含まれます。

  • トランスポートの状態(プレーヤーが再生中、一時停止中、バッファリング中など。getState() を参照)
  • エラーコード、および必要に応じてエラー メッセージ(getErrorCode()、および下記の状態とエラーを参照)
  • プレーヤーの位置
  • 現在の状態で処理できる有効なコントローラ アクション

MediaMetadataCompat クラスは、再生中の素材を表します。これには、以下が含まれます。

  • アーティスト名、アルバム名、トラック名
  • トラックの長さ
  • ロック画面に表示されるアルバム アートワーク(画像は最大サイズ 320 x 320 dp のビットマップ。それを超える場合は縮小される)
  • アートワークの拡大版の場所を示す ContentUris のインスタンス

プレーヤーの状態とメタデータは、メディア セッションの存在期間にわたって変化する可能性があります。状態やメタデータが変化するたびに、各クラスに対応するビルダー(PlaybackStateCompat.Builder() または MediaMetadataCompat.Builder())を使用し、その後、setPlaybackState() または setMetaData() を呼び出して新しいインスタンスをメディア セッションに渡す必要があります。このような操作を頻繁に行うことによるメモリ消費を抑えるため、一度作成したビルダーを、セッション全体を通じて再利用することをおすすめします。

状態とエラー

PlaybackState は、「セッションの再生状態」の個別の値(getState())と、必要に応じて関連する「エラーコード」getErrorCode())を含むオブジェクトです。エラーには、以下に示すとおり、致命的なものと非致命的なものがあります。

再生が中断されたときは必ず、致命的エラーを生成するようにします。それには、トランスポート状態を STATE_ERROR に設定し、関連するエラーに setErrorMessage(int, CharSequence) を指定します。エラーによって再生がブロックされている間は、PlaybackStateSTATE_ERROR とそのエラーを報告し続けるようにします。

アプリでリクエストの処理はできないものの再生を続けられる場合は、非致命的エラーを生成します。この場合、トランスポートは「通常」の状態(STATE_PLAYING など)のままにしますが、PlaybackState にはエラーコードを入れます。たとえば、最後の曲の再生中にユーザーが次の曲へのスキップをリクエストした場合は、再生を続行できますが、新しい PlaybackState をエラーコード ERROR_CODE_END_OF_QUEUE で作成して setPlaybackState() を呼び出すようにします。これにより、セッションに接続されたメディア コントローラによって onPlaybackStateChanged() コールバックが受け取られ、ユーザーに対して何が起こったかが伝えられます。非致命的エラーは、発生時に一度だけ報告するようにします。そのセッションで次に PlaybackState を更新するときは、同じ非致命的エラーを再度設定しないでください(新しいリクエストによってエラーが発生した場合を除く)。

メディア セッションのロック画面

Android 4.0(API レベル 14)以降では、システムからメディア セッションの再生状態とメタデータへのアクセスが可能です。これにより、ロック画面にメディア コントロールとアートワークが表示されます。この動作は、Android のバージョンによって異なります。

アルバム アートワーク

Android 4.0(API レベル 14)以降では、ロック画面の背景にアルバム アートワークが表示されます(メディア セッション メタデータに背景ビットマップが含まれている場合のみ)。

トランスポート コントロール

Android 4.0(API レベル 14)~Android 4.4(API レベル 19)では、メディア セッションがアクティブで、メディア セッション メタデータに背景ビットマップが含まれている場合、ロック画面にトランスポート コントロールが自動的に表示されます。

Android 5.0(API レベル 21)以降では、ロック画面にトランスポート コントロールは表示されません。トランスポート コントロールを表示するには、MediaStyle 通知を使用します。

カスタム アクションの追加

カスタム アクションの追加は、addCustomAction() を使用して行えます。たとえば、高評価アクションを実装したコントロールを追加するには、次のようにします。

Kotlin

    stateBuilder.addCustomAction(
            PlaybackStateCompat.CustomAction.Builder(
                    CUSTOM_ACTION_THUMBS_UP,
                    resources.getString(R.string.thumbs_up),
                    thumbsUpIcon
            ).run {
                setExtras(customActionExtras)
                build()
            }
    )
    

Java

    stateBuilder.addCustomAction(new PlaybackStateCompat.CustomAction.Builder(
        CUSTOM_ACTION_THUMBS_UP, resources.getString(R.string.thumbs_up), thumbsUpIcon)
        .setExtras(customActionExtras)
        .build());
    

完全な例については、Universal Music Playerをご覧ください。

カスタム アクションには onCustomAction() で応答します。

Kotlin

    override fun onCustomAction(action: String, extras: Bundle?) {
        when(action) {
            CUSTOM_ACTION_THUMBS_UP -> {
                ...
            }
        }
    }
    

Java

    @Override
    public void onCustomAction(@NonNull String action, Bundle extras) {
        if (CUSTOM_ACTION_THUMBS_UP.equals(action)) {
            ...
        }
    }
    

Universal Music Player もご覧ください。

メディア セッション コールバック

主要なメディア セッション コールバック メソッドは、onPlay()onPause()onStop() です。 この中に、プレーヤーを制御するコードを追加します。

セッションのコールバックのインスタンス化と設定をランタイムに(onCreate() で)行うため、アプリではさまざまなプレーヤーを使用するコールバックの選択肢を定義し、デバイスやシステムレベルに応じて適切なコールバックとプレーヤーの組み合わせを選択できます。このようにして、アプリの他の部分を変更せずにプレーヤーを変更できます。たとえば、Android 4.1(API レベル 16)以降で実行する場合は ExoPlayer を、それより前のシステムでは MediaPlayer を使用するようにできます。

コールバックでは、プレーヤーの制御やメディア セッションの状態遷移の管理に加え、アプリの機能の有効化や無効化、他のアプリやデバイス ハードウェアとのやりとりの制御も行えます(オーディオ出力の制御を参照)。

メディア セッション コールバック メソッドの実装は、アプリの構造によって異なります。オーディオ アプリ動画アプリでのコールバックの使用方法を説明しているページで、それぞれのアプリでどのようにコールバックを実装すべきかをご確認ください。