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

メディア セッション コールバックでは、いくつかの API のメソッドを呼び出して、プレーヤーの制御、音声フォーカスの管理、メディア セッションやメディア ブラウザ サービスとの通信を行います。コールバックに応答する MediaSession ロジックは一貫している必要があります。コールバックの動作は、呼び出し元にかかわらず同じでなければなりません。呼び出し元は、MediaSession を実行しているアプリのアクティビティである場合も、MediaSession に接続された MediaController を持つ別のアプリのアクティビティである場合もあります。

次の表は、どのタスクをどのコールバックで行うかをまとめたものです。

onPlay() onPause() onStop()
音声フォーカス requestFocus()OnAudioFocusChangeListener で渡します。
必ず先に を呼び出し、フォーカスが付与された場合にのみ続行します。
abandonAudioFocus()
サービス startService() stopSelf()
メディア セッション setActive(true)
- メタデータと状態の更新
- メタデータと状態の更新 setActive(false)
- メタデータと状態の更新
プレーヤーの実装 プレーヤーの起動 プレーヤーの一時停止 プレーヤーの停止
音声出力先の切り替え BroadcastReceiver の登録 BroadcastReceiver の登録解除
通知 startForeground(notification) stopForeground(false) stopForeground(false)

コールバックの構成例を次に示します。

Kotlin

    private val intentFilter = IntentFilter(ACTION_AUDIO_BECOMING_NOISY)

    // Defined elsewhere...
    private lateinit var afChangeListener: AudioManager.OnAudioFocusChangeListener
    private val myNoisyAudioStreamReceiver = BecomingNoisyReceiver()
    private lateinit var myPlayerNotification: MediaStyleNotification
    private lateinit var mediaSession: MediaSessionCompat
    private lateinit var service: MediaBrowserService
    private lateinit var player: SomeKindOfPlayer

    private lateinit var audioFocusRequest: AudioFocusRequest

    private val callback = object: MediaSessionCompat.Callback() {
        override fun onPlay() {
            val am = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
            // Request audio focus for playback, this registers the afChangeListener

            audioFocusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).run {
                setOnAudioFocusChangeListener(afChangeListener)
                setAudioAttributes(AudioAttributes.Builder().run {
                    setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                    build()
                })
                build()
            }
            val result = am.requestAudioFocus(audioFocusRequest)
            if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                // Start the service
                startService(Intent(context, MediaBrowserService::class.java))
                // Set the session active  (and update metadata and state)
                mediaSession.isActive = true
                // start the player (custom call)
                player.start()
                // Register BECOME_NOISY BroadcastReceiver
                registerReceiver(myNoisyAudioStreamReceiver, intentFilter)
                // Put the service in the foreground, post notification
                service.startForeground(id, myPlayerNotification)
            }
        }

        public override fun onStop() {
            val am = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
            // Abandon audio focus
            am.abandonAudioFocusRequest(audioFocusRequest)
            unregisterReceiver(myNoisyAudioStreamReceiver)
            // Stop the service
            service.stopSelf()
            // Set the session inactive  (and update metadata and state)
            mediaSession.isActive = false
            // stop the player (custom call)
            player.stop()
            // Take the service out of the foreground
            service.stopForeground(false)
        }

        public override fun onPause() {
            val am = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
            // Update metadata and state
            // pause the player (custom call)
            player.pause()
            // unregister BECOME_NOISY BroadcastReceiver
            unregisterReceiver(myNoisyAudioStreamReceiver)
            // Take the service out of the foreground, retain the notification
            service.stopForeground(false)
        }
    }
    

Java

    private IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);

    // Defined elsewhere...
    private AudioManager.OnAudioFocusChangeListener afChangeListener;
    private BecomingNoisyReceiver myNoisyAudioStreamReceiver = new BecomingNoisyReceiver();
    private MediaStyleNotification myPlayerNotification;
    private MediaSessionCompat mediaSession;
    private MediaBrowserService service;
    private SomeKindOfPlayer player;

    private AudioFocusRequest audioFocusRequest;

    MediaSessionCompat.Callback callback = new
        MediaSessionCompat.Callback() {
            @Override
            public void onPlay() {
                AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
                // Request audio focus for playback, this registers the afChangeListener
                AudioAttributes attrs = new AudioAttributes.Builder()
                        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                        .build();
                audioFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
                        .setOnAudioFocusChangeListener(afChangeListener)
                        .setAudioAttributes(attrs)
                        .build();
                int result = am.requestAudioFocus(audioFocusRequest);

                if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                    // Start the service
                    startService(new Intent(context, MediaBrowserService.class));
                    // Set the session active  (and update metadata and state)
                    mediaSession.setActive(true);
                    // start the player (custom call)
                    player.start();
                    // Register BECOME_NOISY BroadcastReceiver
                    registerReceiver(myNoisyAudioStreamReceiver, intentFilter);
                    // Put the service in the foreground, post notification
                    service.startForeground(id, myPlayerNotification);
                }
            }

            @Override
            public void onStop() {
                AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
                // Abandon audio focus
                am.abandonAudioFocusRequest(audioFocusRequest);
                unregisterReceiver(myNoisyAudioStreamReceiver);
                // Stop the service
                service.stopSelf();
                // Set the session inactive  (and update metadata and state)
                mediaSession.setActive(false);
                // stop the player (custom call)
                player.stop();
                // Take the service out of the foreground
                service.stopForeground(false);
            }

            @Override
            public void onPause() {
                AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
                // Update metadata and state
                // pause the player (custom call)
                player.pause();
                // unregister BECOME_NOISY BroadcastReceiver
                unregisterReceiver(myNoisyAudioStreamReceiver);
                // Take the service out of the foreground, retain the notification
                service.stopForeground(false);
            }
        };