미디어 세션 콜백

미디어 세션 콜백은 플레이어를 제어하고 오디오 포커스를 관리하며 미디어 세션 및 미디어 브라우저 서비스와 통신하기 위해 여러 API의 메서드를 호출합니다. 콜백에 응답하는 MediaSession 로직은 일관성이 있어야 합니다. 콜백의 동작은 호출자의 ID에 따라 달라져서는 안 됩니다. 호출자는 MediaSession을 실행하는 동일한 앱 또는 MediaSession에 연결된 MediaController가 있는 다른 앱의 활동일 수 있습니다.

다음 표에는 이러한 작업이 콜백 전체에 분산되는 방법이 요약되어 있습니다.

onPlay() onPause() onStop()
오디오 포커스 OnAudioFocusChangeListener에서 requestFocus()가 전달됨.
항상 requestFocus()를 먼저 호출하고 포커스가 허용된 경우에만 진행.
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)
    }
    

자바

    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);
            }
        };