媒体会话回调

您的媒体会话回调调用多个 API 中的方法来控制播放器,管理音频焦点以及与媒体会话和媒体浏览器服务通信。请注意,响应回调的 MediaSession 逻辑必须保持一致。回调的行为不得依赖于调用方的身份,该调用方可能是运行 MediaSession 的同一应用中的 Activity,也可能是任何其他带有已连接到 MediaSessionMediaController 应用中的 Activity。

下表总结了这些任务在回调中的分布情况。

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