Cómo usar sesiones multimedia

Las sesiones multimedia proporcionan una forma universal de interactuar con un audio o video de fútbol favorito. Si informas a Android que se está reproduciendo contenido multimedia en una app, la reproducción controles se pueden delegar a la aplicación. La integración con la sesión multimedia permite Una app para anunciar la reproducción de contenido multimedia externamente y recibir comandos de reproducción de fuentes externas. Estas fuentes pueden ser botones físicos (como los botones de de los auriculares o del control remoto de la TV) o de comandos indirectos (como instrucción de "pausar" al Asistente de Google). Luego, la sesión multimedia delega estos comandos a la app que los aplica al reproductor multimedia para el que se creó transparente de dónde se originaron los comandos.

Una sesión multimedia existe junto al reproductor que administra. Deberías crear e inicializar una sesión multimedia en el método onCreate() de la actividad o que posee la sesión multimedia y su reproductor asociado.

Cómo inicializar la sesión multimedia

Una sesión multimedia recién creada no tiene capacidades. Debes inicializar la sesión con estos pasos:

  • Establece marcas para que la sesión multimedia pueda recibir devoluciones de llamada desde controladores multimedia y botones de medios.
  • Crea e inicializa una instancia de PlaybackStateCompat y asígnala a la sesión. El estado de reproducción cambia a lo largo de la sesión, por lo que recomendamos almacenar en caché el objeto PlaybackStateCompat.Builder para su reutilización.
  • Crea una instancia de MediaSessionCompat.Callback y asígnala a la sesión (más abajo se brinda información sobre las devoluciones de llamada).

Debes crear e inicializar una sesión multimedia en el método onCreate() de la actividad o el servicio propietario de la sesión.

Para que los botones multimedia funcionen Cuando tu app se inicializa (o se detiene), su PlaybackState debe contienen una acción de reproducción que coincida con el intent que envía el botón multimedia. Este es por qué ACTION_PLAY se asigna al estado de la sesión durante de inicio. Para obtener más información, consulta Cómo responder a contenido multimedia Botones.

Cómo mantener el estado y los metadatos de la reproducción

Existen dos clases que representan el estado de una sesión multimedia.

El PlaybackStateCompat describe el estado operativo actual del reproductor. Esto incluye lo siguiente:

  • El estado del transporte (si el reproductor está reproduciendo contenido, detenido, almacenando contenido en el búfer, etc., consulta getState())
  • Un código de error y un mensaje de error opcional cuando corresponda (consulta getErrorCode() y lee la sección Estados y errores, que se incluye más abajo)
  • La posición del reproductor
  • Las acciones válidas del controlador que se pueden manejar en el estado actual

El MediaMetadataCompat describe el material que se está reproduciendo:

  • El nombre del artista, el álbum y la pista
  • La duración de la pista
  • La portada del álbum para mostrar en la pantalla de bloqueo (la imagen es un mapa de bits con un tamaño máximo de 320 x 320 dp; si es más grande, se reduce)
  • Una instancia de ContentUris que dirige a una versión más grande de la portada

El estado y los metadatos del reproductor pueden cambiar durante el ciclo de vida de una sesión multimedia. Cada vez que cambien el estado o los metadatos, debes usar el compilador correspondiente para cada clase, PlaybackStateCompat.Builder() o MediaMetadataCompat.Builder(), y, luego, pasar la instancia nueva a la sesión multimedia con una llamada a setPlaybackState() o setMetaData() Para reducir el consumo general de memoria de estas operaciones frecuentes, conviene crear los compiladores una vez y reutilizarlos durante el ciclo de vida de la sesión.

Estados y errores

Ten en cuenta que PlaybackState es un objeto que contiene valores separados para el estado de reproducción de la sesión (getState()) y, cuando sea necesario, un código de error asociado (getErrorCode()) Los errores pueden ser irrecuperables o recuperables:

Cuando se interrumpe la reproducción, se debe generar un error grave: configura el el estado de transporte en STATE_ERROR y especifica un error asociado con setErrorMessage(int, CharSequence). Mientras el error bloquee la reproducción, PlaybackState debería continuar para informar STATE_ERROR y el error.

Se produce un error recuperable cuando tu app no puede controlar una solicitud, pero puede continuar con la reproducción: El transporte permanece en un estado "normal" (como STATE_PLAYING), pero PlaybackState contiene un código de error. Por ejemplo, si se está reproduciendo la última canción y el usuario solicita pasar a la siguiente canción, La reproducción puede continuar, pero debes crear una PlaybackState nueva con el código de error ERROR_CODE_END_OF_QUEUE y y, luego, llama a setPlaybackState(). Los controladores multimedia adjuntos a la sesión recibirán la devolución de llamada. onPlaybackStateChanged() y explícale al usuario lo que sucedió. Un error recuperable solo se debe informar una vez, en el momento en que ocurre. La próxima vez que la sesión actualice el PlaybackState, no vuelvas a establecer el mismo error recuperable (a menos que el error se haya producido en respuesta a una nueva solicitud).

Pantallas de bloqueo de la sesión multimedia

A partir de Android 4.0 (nivel de API 14), el sistema puede acceder a los archivos el estado de reproducción y los metadatos. Así es como la pantalla de bloqueo puede mostrar los controles multimedia y obras de arte. El comportamiento varía según el Versión de Android.

Portada del álbum

En Android 4.0 (nivel de API 14) hasta Android 10 (nivel de API 29), la configuración de la pantalla de bloqueo muestra la carátula del álbum, pero solo si la sesión multimedia incluye un mapa de bits de fondo.

Controles de transporte

En Android 4.0 (API nivel 14) y hasta Android 4.4 (API nivel 19), cuando una sesión multimedia está activa y los metadatos de la sesión multimedia incluyen un mapa de bits en segundo plano, la pantalla de bloqueo muestra automáticamente los controles de transporte.

En Android 5.0 (nivel de API 21) o versiones posteriores, el sistema no proporciona transporte controles en la pantalla de bloqueo. En su lugar, debes usar un objeto MediaStyle notificación para mostrar los controles de transporte.

Agrega acciones personalizadas

Las aplicaciones multimedia pueden definir acciones personalizadas. por ejemplo: Me gusta, Me gusta o retroceder 30 segundos. Una acción personalizada debería implementar un comportamiento completamente nuevo. Lo que debes hacer No deben usar una acción personalizada para reemplazar una de las acciones de control de transporte estándar. definidos en PlaybackStateCompat:

Agrega acciones personalizadas con addCustomAction(). En el siguiente ejemplo, se muestra cómo agregar un control para una acción de me gusta:

Kotlin

stateBuilder.addCustomAction(
        PlaybackStateCompat.CustomAction.Builder(
                CUSTOM_ACTION_THUMBS_UP,
                resources.getString(R.string.thumbs_up),
                thumbsUpIcon
        ).run {
            setExtras(customActionExtras)
            build()
        }
)

Java

stateBuilder.addCustomAction(new PlaybackStateCompat.CustomAction.Builder(
    CUSTOM_ACTION_THUMBS_UP, resources.getString(R.string.thumbs_up), thumbsUpIcon)
    .setExtras(customActionExtras)
    .build());

Consulta el Universal Music Player para ver un ejemplo completo.

Responde a la acción con onCustomAction().

Kotlin

override fun onCustomAction(action: String, extras: Bundle?) {
    when(action) {
        CUSTOM_ACTION_THUMBS_UP -> {
            ...
        }
    }
}

Java

@Override
public void onCustomAction(@NonNull String action, Bundle extras) {
    if (CUSTOM_ACTION_THUMBS_UP.equals(action)) {
        ...
    }
}

Consulta también el Universal Music Player.

Devoluciones de llamada de sesiones multimedia

Los métodos principales de devolución de llamada son onPlay(), onPause() y onStop(). Aquí es donde agregas el código que controla tu reproductor.

Dado que creas una instancia de la devolución de llamada de la sesión y la estableces en el entorno de ejecución (en onCreate()), tu app puede definir devoluciones de llamada alternativas que usen reproductores distintos y elegir la combinación apropiada de devolución de llamada/reproductor en función del nivel del dispositivo o sistema. Puedes cambiar el reproductor sin modificar el resto de la app. Por ejemplo, puedes usar ExoPlayer si ejecutas Android 4.1 (API nivel 16) o versiones posteriores y usar MediaPlayer en sistemas previos.

Además de controlar el reproductor y administrar las transiciones de estado de la sesión multimedia, las devoluciones de llamada también habilitan e inhabilitan las funciones de tu app y controlan la forma en la que interactúa con otras aplicaciones y con el hardware del dispositivo. (Consulta Cómo controlar la salida de audio).

La implementación de los métodos de devolución de llamada de la sesión multimedia depende de la estructura de tu app. Consulta las páginas separadas que describen cómo usar devoluciones de llamada en apps de audio y apps de video, describen cómo se deben implementar las devoluciones de llamada para cada tipo de app.