Implementare una sessione multimediale

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

Kotlin

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

Java

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 di chiamare anche setActive(true) quando inizia la riproduzione. L'app deve richiedere anche il focus audio, come descritto in Gestire il focus audio. Questi passaggi sono mostrati nell'esempio seguente:

Kotlin

private fun handlePlayRequest() {

    tryToGetAudioFocus()

    if (!session.isActive) {
        session.isActive = true
    }
    ...
}

Java

private void handlePlayRequest() {

    tryToGetAudioFocus();

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

Aggiornare lo stato di riproduzione

Aggiorna lo stato di riproduzione in MediaSession in modo che rifletta lo stato del contenuto multimediale corrente:

Kotlin

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
}

Java

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

Aggiornare 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 alla sessione multimediale informazioni sui contenuti multimediali, tra cui titolo, sottotitolo, artista, artwork e così via. Il seguente esempio è personalizzato in base alla musica e presuppone che i dati della traccia siano archiviati in una classe di dati personalizzata MediaData:

Kotlin

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

Java

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