Implementare una sessione multimediale

Crea un MediaSession quando la tua app si sta preparando a riprodurre contenuti multimediali. Il seguente snippet di codice Ecco un esempio di come impostare il callback e i flag appropriati:

KotlinJava
session = MediaSession(this, "MusicService").apply {
    setCallback
(MediaSessionCallback())
    setFlags
(
           
MediaSession.FLAG_HANDLES_MEDIA_BUTTONS or MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS
   
)
}
session = new MediaSession(this, "MusicService");
session
.setCallback(new MediaSessionCallback());
session
.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS |
       
MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);

Avviare una sessione multimediale

Assicurati inoltre di chiamare setActive(true) all'inizio della riproduzione. L'app deve anche richiedere l'attenzione audio, come descritto in Gestire l'attenzione audio. Questi passaggi sono come mostrato nell'esempio seguente:

KotlinJava
private fun handlePlayRequest() {

    tryToGetAudioFocus
()

   
if (!session.isActive) {
        session
.isActive = true
   
}
   
...
}
private void handlePlayRequest() {

    tryToGetAudioFocus
();

   
if (!session.isActive()) {
        session
.setActive(true);
   
}
   
...
}

Aggiornare lo stato di riproduzione

Aggiorna lo stato di riproduzione nel MediaSession per riflettere lo stato dei contenuti multimediali attuali:

KotlinJava
private fun updatePlaybackState() {
   
val position: Long =
            mediaPlayer
                   
?.takeIf { it.isPlaying }
                   
?.currentPosition?.toLong()
                   
?: PlaybackState.PLAYBACK_POSITION_UNKNOWN

   
val stateBuilder = PlaybackState.Builder()
           
.setActions(getAvailableActions()).apply {
                setState
(mState, position, 1.0f)
           
}
    session
.setPlaybackState(stateBuilder.build())
}

private fun getAvailableActions(): Long {
   
var actions = (PlaybackState.ACTION_PLAY_PAUSE
            or
PlaybackState.ACTION_PLAY_FROM_MEDIA_ID
            or
PlaybackState.ACTION_PLAY_FROM_SEARCH)

    playingQueue
?.takeIf { it.isNotEmpty() }?.apply {
        actions
= if (mState == PlaybackState.STATE_PLAYING) {
            actions or
PlaybackState.ACTION_PAUSE
       
} else {
            actions or
PlaybackState.ACTION_PLAY
       
}
       
if (currentIndexOnQueue > 0) {
            actions
= actions or PlaybackState.ACTION_SKIP_TO_PREVIOUS
       
}
       
if (currentIndexOnQueue < size - 1) {
            actions
= actions or PlaybackState.ACTION_SKIP_TO_NEXT
       
}
   
}
   
return actions
}
private void updatePlaybackState() {
   
long position = PlaybackState.PLAYBACK_POSITION_UNKNOWN;
   
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
        position
= mediaPlayer.getCurrentPosition();
   
}
   
PlaybackState.Builder stateBuilder = new PlaybackState.Builder()
           
.setActions(getAvailableActions());
    stateBuilder
.setState(mState, position, 1.0f);
    session
.setPlaybackState(stateBuilder.build());
}

private long getAvailableActions() {
   
long actions = PlaybackState.ACTION_PLAY_PAUSE |
           
PlaybackState.ACTION_PLAY_FROM_MEDIA_ID |
           
PlaybackState.ACTION_PLAY_FROM_SEARCH;
   
if (playingQueue == null || playingQueue.isEmpty()) {
       
return actions;
   
}
   
if (mState == PlaybackState.STATE_PLAYING) {
        actions
|= PlaybackState.ACTION_PAUSE;
   
} else {
        actions
|= PlaybackState.ACTION_PLAY;
   
}
   
if (currentIndexOnQueue > 0) {
        actions
|= PlaybackState.ACTION_SKIP_TO_PREVIOUS;
   
}
   
if (currentIndexOnQueue < playingQueue.size() - 1) {
        actions
|= PlaybackState.ACTION_SKIP_TO_NEXT;
   
}
   
return actions;
}

Aggiorna i metadati dei contenuti multimediali

Imposta MediaMetadata con il metodo setMetadata(). Questo metodo viene chiamato una sola volta per ogni oggetto riprodotto. Ti consente di fornire informazioni a la sessione multimediale sui contenuti multimediali, inclusi titolo, sottotitolo artista, artwork, ecc. Il seguente esempio è pensato su misura per musica e presuppone che i dati della traccia siano memorizzati in una classe di dati personalizzata, MediaData:

KotlinJava
private fun updateMetadata(myData: MediaData) {
   
val metadataBuilder = MediaMetadata.Builder().apply {
       
// To provide most control over how an item is displayed set the
       
// display fields in the metadata
        putString
(MediaMetadata.METADATA_KEY_DISPLAY_TITLE, myData.displayTitle)
        putString
(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE, myData.displaySubtitle)
        putString
(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, myData.artUri)
       
// And at minimum the title and artist for legacy support
        putString
(MediaMetadata.METADATA_KEY_TITLE, myData.title)
        putString
(MediaMetadata.METADATA_KEY_ARTIST, myData.artist)
       
// A small bitmap for the artwork is also recommended
        putBitmap
(MediaMetadata.METADATA_KEY_ART, myData.artBitmap)
       
// Add any other fields you have for your data as well
   
}
    session
.setMetadata(metadataBuilder.build())
}
private void updateMetadata(MediaData myData) {
   
MediaMetadata.Builder metadataBuilder = new MediaMetadata.Builder();
   
// To provide most control over how an item is displayed set the
   
// display fields in the metadata
    metadataBuilder
.putString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE,
            myData
.displayTitle);
    metadataBuilder
.putString(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE,
            myData
.displaySubtitle);
    metadataBuilder
.putString(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI,
            myData
.artUri);
   
// And at minimum the title and artist for legacy support
    metadataBuilder
.putString(MediaMetadata.METADATA_KEY_TITLE,
            myData
.title);
    metadataBuilder
.putString(MediaMetadata.METADATA_KEY_ARTIST,
            myData
.artist);
   
// A small bitmap for the artwork is also recommended
    metadataBuilder
.putBitmap(MediaMetadata.METADATA_KEY_ART,
            myData
.artBitmap);
   
// Add any other fields you have for your data as well
    session
.setMetadata(metadataBuilder.build());
}