MediaSession — 主要概念、統合、およびAndroidでの動作メカニズム

著者: IT Sectr 公開日: 2026-05-23 読了時間: 8 分

MediaSessionは、メディアコンテンツの再生を管理し、外部デバイスと統合するためのAndroidフレームワークコンポーネントです。Bluetoothヘッドセット、ヘッドフォン、Android Auto、システムメディアセンターとのインタラクションのための統一インターフェースを提供します。Android Developers Guide, 2026によると、MediaSessionは非推奨のRemoteControlClientを置き換え、システムと同期するプレーヤーに必須です。

重要なポイント

  • MediaSessionは、Androidでメディアストリームを管理するための中心的なコンポーネントで、外部ソースからコマンドを受け取ります。
  • Bluetooth AVRCP、ヘッドセット、Android Auto、ウェアラブルデバイス、Androidメディアセンターをサポートします。
  • セッションはプレーヤーの状態(再生/一時停止/次へ/前へ)とメタデータ(タイトル、アーティスト、カバーアート)をシステムと同期します。
  • AndroidXのMediaSessionCompatが必要で、API 14までの下位互換性を提供します。
  • MediaSession.Callbackシステムが受信コマンドを処理し、MediaSessionの状態を変更します。

MediaSessionとは?

MediaSessionは、アプリがメディアアクティビティを宣言し、外部ソースから制御コマンドを受け取ることを可能にするAndroidのシステムコンポーネントです。ユーザーがBluetoothヘッドセットの再生ボタンを押すと、システムはこのイベントをアクティブなMediaSessionに渡し、アプリはCallbackを介して応答します。

Android 5.0以前は、この目的のためにRemoteControlClientが使用されていましたが、十分な柔軟性がなく、Android Auto、スマートウォッチ、スマートスピーカーなどの最新のシナリオをサポートしていませんでした。MediaSessionはAPI 21で導入され、オーディオおよびビデオ再生を行うすべてのAndroidアプリの事実上の標準となりました。

Androidデベロッパードキュメント(2026年)によると、アプリは独立した再生ソースごとに1つのMediaSessionを作成する必要があります。任意の時点でアクティブにできるセッションは1つだけで、新しいセッションは自動的に前のセッションを非アクティブにします。

MediaSessionとMediaBrowserService

MediaSessionとMediaBrowserServiceの組み合わせにより、完全なメディア管理サイクルが実現します。サービスはコンテンツツリー(プレイリスト、カタログ)を提供し、セッションはナビゲーションと再生コマンドを受け入れます。これはGoogleが音楽プレーヤー、ポッドキャスト、オーディオブックに推奨するアーキテクチャです。

MediaBrowserServiceは通知付きのフォアグラウンドサービスとして実行され、Activityが破棄されてもアプリが動作し続けることを保証します。これは、アプリが最小化されている間も再生を続ける必要があるオーディオプレーヤーにとって重要です。

MediaSessionの仕組み

セッションは2種類のインタラクションをサポートします。MediaController(クライアント側)からコマンドを受信し、PlaybackStateを介して状態をブロードキャストします。MediaControllerは同じプロセス内または別のアプリ内に存在でき、システムはSessionTokenを介してリクエストをルーティングします。

ユーザーがAndroid音声アシスタントを呼び出して“次のトラックを再生”と言うと、システムはMediaBrowserServiceへの接続を介してアクティブなMediaSessionを見つけ、ACTION_SKIP_TO_NEXTコマンドを送信します。アプリのCallbackはonSkipToNext()呼び出しを受信し、PlaybackStateを更新します。

setPlaybackState()によるPlaybackStateの更新は、接続されているすべてのMediaControllerインスタンスに即座に通知されます。システムメディアセンター、Bluetoothデバイス、Android Autoが同時に更新を受信し、通常の条件下での遅延は50ミリ秒を超えません。

PlaybackStateとそのメタデータ

PlaybackStateには主要な状態フラグ(isPlaying、位置、速度、利用可能なアクション(再生、一時停止、シーク、停止))が含まれます。PlaybackStateが適切に設定されていないと、システムはアプリがどのコマンドをサポートしているかを認識できず、対応するイベントを送信しません。

メタデータ(MediaMetadata)は、現在のトラックに関する情報(タイトル、アーティスト、アルバムアートURI)で状態を補完します。Android AutoとウェアラブルデバイスはMediaMetadataを使用して画面に情報を表示します。Google I/O 2024によると、MediaMetadataを適切に設定すると、サードパーティのランチャーでのアプリの可視性が40%向上します。

MediaSessionの主要コンポーネント

MediaSessionアーキテクチャは4つの相互接続されたコンポーネントで構成され、それぞれが独自の役割を果たします。完全なシステム統合には、開発者は4つすべてを実装する必要があります。

  • MediaSessionCompat — セッションのメインクラス。アプリタグで作成され、メディアボタン用のPendingIntentを受け入れます。
  • MediaSession.Callback — コマンドハンドラー。onPlay、onPause、onSkipToNext、onSeekToなどのメソッドを実装します。
  • PlaybackStateCompat — 現在のプレーヤーの状態。フラグ、位置、速度、利用可能なアクションのリストを含みます。
  • MediaMetadataCompat — 現在のメディアのメタデータ:タイトル、アーティスト、アルバム、カバーアート、再生時間。

MediaSessionのライフサイクル

セッションは、サービスまたはActivityのonCreateメソッドでMediaSessionCompat(context, tag)を呼び出して作成されます。作成後、setFlags(FLAG_HANDLES_MEDIA_BUTTONS | FLAG_HANDLES_TRANSPORT_CONTROLS)を呼び出す必要があります。onDestroyでは、システムリソースを解放するためにrelease()が呼び出されます。

ライフサイクル管理の誤りはよくある間違いの1つです。release()を呼び出さないと、セッションがシステムに残り、次のアプリが古い状態を受け取る可能性があります。Android 13+はセッションリークに対してLogcat警告を表示します。

アプリケーションへのMediaSession統合

基本的な統合は、セッションを作成しCallbackを実装することから始まります。AndroidXメディアライブラリのMediaSessionCompatを使用することをお勧めします。これは、API 14から35までのすべてのAndroidバージョンに統一APIを提供します。

MediaSessionとCallbackの作成

kotlin
class MusicService : Service() {

    private lateinit var mediaSession: MediaSessionCompat
    private lateinit var stateBuilder: PlaybackStateCompat.Builder

    override fun onCreate() {
        super.onCreate()

        mediaSession = MediaSessionCompat(this, "MusicService")
        mediaSession.setFlags(
            MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS
                or MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS
        )
        mediaSession.setCallback(MediaSessionCallback())
        updatePlaybackState(false)
    }

    private inner class MediaSessionCallback : MediaSessionCompat.Callback() {
        override fun onPlay() {
            updatePlaybackState(true)
        }

        override fun onPause() {
            updatePlaybackState(false)
        }
    }

    private fun updatePlaybackState(isPlaying: Boolean) {
        stateBuilder = PlaybackStateCompat.Builder()
            .setState(
                if (isPlaying) PlaybackStateCompat.STATE_PLAYING
                else PlaybackStateCompat.STATE_PAUSED,
                AudioTrackCompat.CURRENT_POSITION_NOT_SET,
                1.0f
            )
            .setActions(
                PlaybackStateCompat.ACTION_PLAY
                    or PlaybackStateCompat.ACTION_PAUSE
                    or PlaybackStateCompat.ACTION_SKIP_TO_NEXT
                    or PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
            )
        mediaSession.setPlaybackState(stateBuilder.build())
    }

    override fun onDestroy() {
        mediaSession.release()
        super.onDestroy()
    }
}

この例では、MusicServiceタグとメディアボタン操作用のフラグを持つMediaSessionが作成されています。CallbackはonPlayとonPauseを実装し、PlaybackStateを更新します。setActionsメソッドは、システムがロック画面とメディアセンターに表示する利用可能なアクションを宣言します。

MediaMetadataの設定

kotlin
private fun setMetadata(title: String, artist: String) {
    val metadata = MediaMetadataCompat.Builder()
        .putString(MediaMetadataCompat.METADATA_KEY_TITLE, title)
        .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist)
        .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, 300000L)
        .putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, albumArtUrl)
        .build()
    mediaSession.setMetadata(metadata)
}

メタデータはトラックが変更されるたびに更新する必要があります。システムはMETADATA_KEY_TITLEMETADATA_KEY_ARTISTを使用して、車載Bluetoothディスプレイやウェアラブルデバイスに情報を表示します。カバーアートURIが設定されていない場合、プレーヤーは灰色のプレースホルダーを表示します。

Bluetoothとヘッドフォンからのメディアコマンドの処理

BluetoothヘッドセットはAVRCP 1.6+プロファイルを介してコマンドを送信します。AndroidはこれらのコマンドをACTION_MEDIA_BUTTONインテントとしてブロードキャストし、FLAG_HANDLES_MEDIA_BUTTONSフラグが設定されている場合、MediaSessionがインターセプトします。

ユーザーがBluetoothヘッドフォンの再生ボタンを押すと、システムはKEYCODE_MEDIA_PLAYコードのKeyEventを作成し、CallbackのonMediaButtonEventメソッドにディスパッチします。CallbackにonPlay()が実装されている場合、システムは直接呼び出します。ヘッドセットボタンを1回押すとKEYCODE_MEDIA_PLAY_PAUSEが送信され、プレーヤーは状態を切り替える必要があります。

複数ボタンによる複雑なシナリオの処理

最近のBluetoothヘッドフォンには最大5つのボタン(音量+/−、再生/一時停止、次へ、前へ)がある場合があります。各ボタンは独自のKeyEventを生成し、Callbackで適切に処理する必要があります。多くのヘッドセットでは、再生/一時停止のダブルプレスは通常、次のトラック(ACTION_SKIP_TO_NEXT)へのスキップとして解釈されます。

Android互換性定義ドキュメント(2026年)によると、メディアコンテンツを持つすべてのアプリはKEYCODE_MEDIA_PLAY_PAUSEを適切に処理する必要があります。この要件を無視すると、Google Playの音楽およびオーディオカテゴリでアプリの評価が自動的に低下します。

システムメディアセンターとの同期

Android 11以降、システムメディアセンター(メディアコントロールパネル)は、通知シェードに最大5つの最近のMediaSessionを表示します。ユーザーはアプリを開かずにプレーヤーを制御できます。正しく表示するには、MediaBrowserServiceを実装し、PlaybackStateを適切に設定する必要があります。

メディアコントロールパネルには、トラックのタイトル、アーティスト、カバーアート(MediaMetadataから)、コントロールボタン(PlaybackStateの利用可能なアクションから)が表示されます。アプリがアクティブな再生中に少なくとも10秒に1回PlaybackStateを更新しない場合、メディアセンターはパネルからセッションを非表示にします。

通知付きフォアグラウンドサービス

kotlin
private fun startForegroundService() {
    val notification = NotificationCompat.Builder(this, "media_channel")
        .setSmallIcon(R.drawable.ic_play)
        .setContentTitle("再生中")
        .setContentText(currentTrackTitle)
        .setPriority(NotificationCompat.PRIORITY_LOW)
        .setStyle(
            androidx.media.app.NotificationCompat.MediaStyle()
                .setMediaSession(mediaSession.sessionToken)
        )
        .build()
    startForeground(1001, notification)
}

MediaStyle通知はsessionTokenを介してMediaSessionにリンクし、標準のメディアボタンを表示します。MediaStyleがない場合、通知はコントロールボタンのない通常のアラートとして表示されます。Android 13+では、表示に明示的なPOST_NOTIFICATIONS権限が必要です。

よくある質問

アプリは同時に複数のアクティブなMediaSessionを持つことができますか?

技術的には可能ですが、任意の時点でアクティブと見なされるセッションは1つだけです。setActive(true)を呼び出さずに新しいセッションを作成すると、前のセッションがアクティブのままになります。アプリごとに1つのセッション、またはアクティブ状態の切り替えを行う独立したオーディオソースごとに1つのセッションを持つことをお勧めします。

MediaSessionはAudio Focusとどのように連携しますか?

MediaSessionはAudio Focusを自動的に管理しません。これは別のメカニズムです。onPlayコマンドを受信すると、開発者はAudioManagerを介してAudioFocusを個別にリクエストし、フォーカスを失った場合はセッションを介して再生を一時停止する必要があります。

ヘッドフォンのメディアボタンがアプリで機能しないのはなぜですか?

FLAG_HANDLES_MEDIA_BUTTONSFLAG_HANDLES_TRANSPORT_CONTROLSフラグが設定されているか確認してください。また、セッションがアクティブ(setActive(true))であることを確認してください。Android 12+では、メディアボタンはMediaSessionを介してのみ機能します。古いregisterMediaButtonEventReceiverはサポートされていません。

MediaSessionを機能させるためにMediaBrowserServiceは必要ですか?

基本的なボタン処理には不要です。ただし、Android Auto、Wear OS、システムメディアセンターとの統合にはMediaBrowserServiceが必要です。Googleは、長時間のオーディオ再生を行うすべてのアプリでMediaBrowserServiceを実装することを推奨しています。

MediaSessionが正しく構成されているかどうかを確認するには?

adb shell dumpsys media_sessionコマンドを使用して、アクティブなセッション、そのCallback、PlaybackStateを表示します。このユーティリティは、タグ、アクティビティステータス、最後の既知の状態とともに、登録されているすべてのセッションを表示します。デバッグに便利なツールです。

まとめ

  • MediaSessionは、API 21以降のRemoteControlClientに代わる、Androidでの再生管理の標準的な方法です。
  • セッションはCallbackシステムを介してBluetooth、ヘッドフォン、Android Auto、システムメディアセンターからコマンドを受信します。
  • PlaybackStateMediaMetadataは、システムUIとの適切な同期に必要な2つの必須コンポーネントです。
  • 統合はAndroidXメディアのMediaSessionCompatを介して行われ、API 14+との互換性を提供します。
  • システムメディアセンターに表示するには、MediaBrowserServiceとMediaStyle通知付きのフォアグラウンドサービスが必要です。
  • Audio Focusの管理は別のタスクであり、MediaSessionでは自動化されません。開発者が個別にフォーカスを管理します。
  • デバッグには、adb shell dumpsys media_sessionを使用してアクティブなセッションとその状態を表示します。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください