Las devoluciones de llamada de sesiones multimedia llaman a métodos en varias APIs para controlar el reproductor, administrar el foco de audio
y comunicarse con la sesión multimedia
y el servicio de navegador multimedia. Ten en cuenta que
La lógica de MediaSession
que responde a las devoluciones de llamada debe ser coherente. El comportamiento
de la devolución de llamada no debe depender de la identidad del emisor, que podría
una actividad en la misma app que ejecuta MediaSession
o cualquier otra app con una
MediaController
se conectó a MediaSession
.
En la siguiente tabla, se resume la forma en la que se distribuyen estas tareas entre las devoluciones de llamada.
onPlay() | onPause() | onStop() | |
Foco de audio | requestFocus() y pasa tu OnAudioFocusChangeListener .Siempre llama a requestFocus() primero y procede solo si se otorga el foco.
|
abandonAudioFocus()
|
|
Servicio | startService()
|
stopSelf()
|
|
Sesión multimedia | setActive(true)
- Actualiza los metadatos y el estado |
- Actualiza los metadatos y el estado | setActive(false)
- Actualiza los metadatos y el estado |
Implementación del reproductor | Inicia el reproductor | Pausar el reproductor | Detén el reproductor |
Demasiado ruidoso | Registra tu BroadcastReceiver
|
Cancela el registro de tu BroadcastReceiver
|
|
Notificaciones | startForeground(notification)
|
stopForeground(false)
|
stopForeground(false)
|
A continuación, se detalla un ejemplo de marco de trabajo para la devolución de llamada:
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);
}
};