Callback ของเซสชันสื่อ

Callback ของเซสชันสื่อจะเรียกใช้เมธอดใน API หลายรายการเพื่อควบคุมโปรแกรมเล่น จัดการโฟกัสของเสียง และสื่อสารกับเซสชันสื่อและบริการเบราว์เซอร์สื่อ โปรดทราบว่า ตรรกะ MediaSession ที่ตอบสนองต่อ Callback จะต้องสอดคล้องกัน ลักษณะการทำงาน ของ Callback ต้องไม่ขึ้นอยู่กับข้อมูลระบุตัวตนของผู้โทร ซึ่งอาจเป็น กิจกรรมในแอปเดียวกับที่เรียกใช้ MediaSession หรือแอปอื่นๆ ที่มี MediaController เชื่อมต่ออยู่กับ MediaSession

ตารางต่อไปนี้สรุปวิธีกระจายงานเหล่านี้ใน Callback

onPlay() onPause() onStop()
โฟกัสเสียง requestFocus() ผ่านใน OnAudioFocusChangeListener ของคุณ
โปรดโทรหา requestFocus() ก่อนเสมอ ให้ดำเนินการต่อเฉพาะเมื่อได้รับโฟกัส
abandonAudioFocus()
บริการ startService() stopSelf()
เซสชันสื่อ setActive(true) วันที่
- อัปเดตข้อมูลเมตาและสถานะ
- อัปเดตข้อมูลเมตาและสถานะ setActive(false) วันที่
- อัปเดตข้อมูลเมตาและสถานะ
การใช้งานโปรแกรมเล่น เริ่มโปรแกรมเล่น หยุดโปรแกรมเล่นวิดีโอชั่วคราว หยุดโปรแกรมเล่น
เริ่มเสียงดัง ลงทะเบียน BroadcastReceiver ยกเลิกการลงทะเบียน BroadcastReceiver
การแจ้งเตือน startForeground(notification) stopForeground(false) stopForeground(false)

ต่อไปนี้เป็นตัวอย่างเฟรมเวิร์กสำหรับ Callback

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