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

メディア セッションは、オーディオ プレーヤーまたは動画プレーヤーを普遍的な方法で操作します。アプリでメディアが再生されていることを Android に通知することで、再生コントロールをアプリに委任できます。メディア セッションと統合することで、アプリは外部でメディア再生をアドバタイズし、外部ソースから再生コマンドを受信できるようになります。これらのソースは、物理的なボタン(ヘッドセットの再生ボタン、テレビのリモコンなど)または間接的なコマンド(Google アシスタントに「一時停止」を指示するなど)です。メディア セッションはこれらのコマンドを、コマンドの送信元のメディア プレーヤー(透過的)に適用するアプリに委任します。

メディア セッションは、それが管理するプレーヤーとともに存在します。メディア セッションの作成と初期化は、メディア セッションとそれに関連付けられたプレーヤーを所有するアクティビティまたはサービスの 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) に指定します。エラーによって再生がブロックされていれば、PlaybackState は引き続き STATE_ERROR とエラーを報告します。

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

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

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

アルバム アートワーク

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

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

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

Android 5.0(API レベル 21)以降では、ロック画面上のトランスポート コントロールは提供されません。トランスポート コントロールを表示するには、代わりに MediaStyle 通知を使用する必要があります。

カスタム アクションを追加する

メディアアプリでは、高評価、高評価、30 秒巻き戻しなどのカスタム アクションを定義できます。カスタム操作は、まったく新しい動作を実装する必要があります。カスタム アクションを使用して、PlaybackStateCompat で定義された標準のトランスポート コントロール アクションのいずれかを置き換えることは避けてください。

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 を使用するようにできます。

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

メディア セッション コールバック メソッドの実装は、アプリの構造によって異なります。オーディオ アプリ動画アプリにおけるコールバックの使用方法を説明している個別のページを参照し、アプリの種類ごとにコールバックの実装方法を確認してください。