Habilita el control de reproducción

Para habilitar la reproducción de contenido multimedia en Android Auto y el SO Android Automotive (AAOS), registra una sesión multimedia y controla sus métodos de devolución de llamada para implementar los controles de reproducción. En esta página se explica la manera de:

  • Registra un objeto MediaSessionCompat en tu servicio de navegador multimedia.

  • Implementa métodos MediaSessionCompat.Callback para responder a las solicitudes de reproducción del usuario.

  • Configura acciones de reproducción estándar y personalizadas.

  • Establece el estado de reproducción inicial para tu sesión multimedia.

  • Se agregaron íconos para indicar el formato de audio.

  • Crear vínculos a partir de elementos multimedia que se reproducen de forma activa

Android Auto y AAOS envían comandos de control de reproducción a través de MediaSessionCompat para tu servicio. Debes registrar una sesión y, luego, implementar los métodos de devolución de llamada asociados.

Registra una sesión multimedia

En el método onCreate del servicio de tu navegador multimedia, crea una instancia de MediaSessionCompat y, luego, llama a setSessionToken para registrar la sesión multimedia. En el siguiente fragmento de código, se muestra cómo crear y registrar una sesión multimedia:

Kotlin

override fun onCreate() {
    super.onCreate()
    ...
    // Start a new MediaSession.
    val session = MediaSessionCompat(this, "session tag").apply {
        // Set a callback object that implements MediaSession.Callback
        // to handle play control requests.
        setCallback(MyMediaSessionCallback())
    }
    sessionToken = session.sessionToken
    ...
}

Java

public void onCreate() {
    super.onCreate();
    ...
    // Start a new MediaSession.
    MediaSessionCompat session = new MediaSessionCompat(this, "session tag");
    setSessionToken(session.getSessionToken());

    // Set a callback object that implements MediaSession.Callback
    // to handle play control requests.
    session.setCallback(new MyMediaSessionCallback());
    ...
}

Cuando creas el objeto de la sesión multimedia, estableces un objeto de devolución de llamada que se usa a fin de manejar las solicitudes de control de reproducción. A los efectos de crear este objeto de devolución de llamada, debes proporcionar una implementación de la clase MediaSessionCompat.Callback para tu app. En la siguiente sección, se explica cómo implementar este objeto.

Implementa comandos de reproducción

Cuando un usuario solicita la reproducción de un elemento multimedia de tu app, el SO Android Automotive y Android Auto usan la clase MediaSessionCompat.Callback del objeto MediaSessionCompat de tu app que se obtuvo del servicio de navegador multimedia de la app. Cuando un usuario desea controlar la reproducción de contenido, como pausar la reproducción u omitir la siguiente pista, Android Auto y el SO Android Automotive invocan uno de los métodos del objeto de devolución de llamada.

Para controlar la reproducción de contenido, tu app debe extender la clase abstracta MediaSessionCompat.Callback e implementar los métodos compatibles con tu app.

Implementa cada uno de estos métodos de devolución de llamada que correspondan al tipo de contenido que ofrece tu app:

onPrepare
AAOS invoca este método cuando cambia la fuente multimedia.
onPlay

Se invoca cuando el usuario selecciona reproducir contenido sin elegir un elemento específico. Tu app debe reproducir su contenido predeterminado o, si se pausó la reproducción con onPause, esta se reanuda.

onPlayFromMediaId

Se invoca cuando el usuario elige reproducir un elemento específico. El método recibe el ID que tu servicio de navegador multimedia asignó al elemento multimedia en la jerarquía de contenido.

onPlayFromSearch

Se invoca cuando el usuario elige reproducir un elemento desde una búsqueda. La app debe hacer una elección apropiada según la cadena de búsqueda que se pasa.

onPause

Se invoca cuando el usuario elige pausar la reproducción.

onSkipToNext

Se invoca cuando el usuario elige omitir el elemento siguiente.

onSkipToPrevious

Se invoca cuando el usuario elige omitir el elemento anterior.

onStop

Se invoca cuando el usuario elige detener la reproducción. Anula estos métodos en tu app para proporcionar el resultado elegido. No es necesario que implementes un método si tu app no admite su propósito. Por ejemplo, si tu app reproduce una transmisión en vivo, como una transmisión deportiva, no necesitas implementar onSkipToNext. En su lugar, usa la implementación predeterminada de onSkipToNext.

La app no necesita una lógica especial para reproducir contenido en las bocinas del vehículo. Cuando tu app recibe una solicitud para reproducir contenido, reproduce audio de la misma manera que el contenido se reproduce a través de los altavoces o los auriculares del teléfono del usuario. Android Auto y AAOS envían automáticamente el contenido de audio al sistema del automóvil para reproducirlo en las bocinas del automóvil.

Para obtener más información sobre la reproducción de contenido de audio, consulta la descripción general de MediaPlayer, la de la app de audio y la de ExoPlayer.

Establece acciones de reproducción estándar

Android Auto y AAOS muestran los controles de reproducción según las acciones habilitadas en el objeto PlaybackStateCompat. De forma predeterminada, la app debe admitir las siguientes acciones:

También puede admitir las siguientes acciones si son relevantes para su contenido:

Además, puedes crear de forma opcional una cola de reproducción para que se le muestre al usuario. Para ello, llama a los métodos setQueue y setQueueTitle, habilita la acción ACTION_SKIP_TO_QUEUE_ITEM y define la devolución de llamada onSkipToQueueItem.

Además, agrega compatibilidad con el ícono Está sonando, que indica lo que se está reproduciendo. Para ello, llama al método setActiveQueueItemId y pasa el ID del elemento que se está reproduciendo en la cola. Debes actualizar setActiveQueueItemId cada vez que haya un cambio en la cola.

Android Auto y AAOS muestran los botones para cada acción habilitada, así como la cola de reproducción. Cuando los usuarios hacen clic en estos botones, el sistema invoca la devolución de llamada correspondiente desde MediaSessionCompat.Callback.

Reserva un espacio sin usar

Android Auto y AAOS reservan espacio en la IU para las acciones ACTION_SKIP_TO_PREVIOUS y ACTION_SKIP_TO_NEXT. Si tu app no admite una de estas funciones, Android Auto y AAOS usarán el espacio para mostrar cualquier acción personalizada que crees.

Si no quieres llenar esos espacios con acciones personalizadas, puedes reservarlos para que Android Auto y AAOS dejen el espacio en blanco cuando tu app no admita la función correspondiente.

Para ello, llama al método setExtras con un paquete de extras que contenga constantes que correspondan a las funciones reservadas. SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_NEXT corresponde a ACTION_SKIP_TO_NEXT, y SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_PREV corresponde a ACTION_SKIP_TO_PREVIOUS. Usa estas constantes como claves en el paquete y usa el valor booleano true como valores.

Establece el PlaybackState inicial

A medida que Android Auto y AAOS se comunican con tu servicio de navegador multimedia, tu sesión multimedia comunica el estado de la reproducción de contenido con PlaybackStateCompat.

Tu app no debería iniciar automáticamente la reproducción de música cuando AAOS o Android Auto se conecten a tu servicio de navegador multimedia. En cambio, utiliza Android Auto y AAOS para reanudar o iniciar la reproducción según el estado del automóvil o las acciones del usuario.

Para ello, configura el elemento inicial PlaybackStateCompat de tu sesión multimedia en STATE_STOPPED, STATE_PAUSED, STATE_NONE o STATE_ERROR.

Las sesiones multimedia dentro de Android Auto y AAOS duran solo lo que dure el viaje, por lo que los usuarios inician y detienen estas sesiones con frecuencia. Para promover una experiencia fluida entre viajes, lleva un registro del estado de sesión anterior del usuario, de modo que cuando la app de música reciba una solicitud de reanudación, el usuario pueda retomar automáticamente desde donde dejó; por ejemplo, el último elemento multimedia que se reprodujo, el PlaybackStateCompat y la cola.

Agrega acciones de reproducción personalizadas

Puedes agregar acciones de reproducción personalizadas para mostrar las acciones adicionales que admite tu app de música. Si el espacio lo permite (y no lo reservas), Android agrega las acciones personalizadas a los controles de transporte. De lo contrario, las acciones personalizadas aparecerán en el menú Overflow. Android muestra las acciones personalizadas en el orden en que las agregas a PlaybackStateCompat.

Usa acciones personalizadas para proporcionar un comportamiento distinto de las acciones estándar. No las uses para reemplazar o duplicar acciones estándar.

Para agregar acciones personalizadas, usa el método addCustomAction en la clase PlaybackStateCompat.Builder. En este fragmento de código, se muestra cómo agregar una acción personalizada a "Iniciar un canal de radio":

Kotlin

val customActionExtras = Bundle()
customActionExtras.putInt(
  androidx.media3.session.MediaConstants.EXTRAS_KEY_COMMAND_BUTTON_ICON_COMPAT,
  androidx.media3.session.CommandButton.ICON_RADIO)

stateBuilder.addCustomAction(
    PlaybackStateCompat.CustomAction.Builder(
        CUSTOM_ACTION_START_RADIO_FROM_MEDIA,
        resources.getString(R.string.start_radio_from_media),
        startRadioFromMediaIcon // or R.drawable.media3_icon_radio
    ).run {
        setExtras(customActionExtras)
        build()
    }
)

Java

Bundle customActionExtras = new Bundle();
customActionExtras.putInt(
  androidx.media3.session.MediaConstants.EXTRAS_KEY_COMMAND_BUTTON_ICON_COMPAT,
  androidx.media3.session.CommandButton.ICON_RADIO);

stateBuilder.addCustomAction(
    new PlaybackStateCompat.CustomAction.Builder(
        CUSTOM_ACTION_START_RADIO_FROM_MEDIA,
        resources.getString(R.string.start_radio_from_media),
        startRadioFromMediaIcon) // or R.drawable.media3_icon_radio
    .setExtras(customActionExtras)
    .build());

Para obtener un ejemplo detallado de este método, consulta el método setCustomAction en la app de ejemplo de Universal Android Music Player en GitHub. Después de crear tu acción personalizada, la sesión multimedia puede responder a las acciones anulando el método onCustomAction.

En el siguiente fragmento de código, se muestra cómo tu app puede responder a una acción "Iniciar un canal de radio":

Kotlin

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

Java

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

Para obtener más información, consulta el método onCustomAction en la app de ejemplo de Universal Android Music Player en GitHub.

Crea íconos para acciones personalizadas

Cada acción personalizada que creas requiere un ícono.

Si la descripción de ese ícono coincide con una de las constantes de CommandButton.ICON_, establece el valor entero para la clave EXTRAS_KEY_COMMAND_BUTTON_ICON_COMPAT de los elementos adicionales de la acción personalizada. En los sistemas compatibles, esta acción anula el recurso de ícono que se pasa a CustomAction.Builder, lo que permite que los componentes del sistema rendericen de forma coherente tu acción y otras acciones de reproducción.

También debes especificar un recurso de ícono. Las apps para vehículos se pueden ejecutar en diferentes tamaños y densidades de pantallas, de modo que los íconos que proporciones deben ser elementos de diseño de vectores. Usa un elemento de diseño vectorial para escalar elementos sin perder detalles. Una interfaz dibujable en vector puede alinear los bordes y las esquinas con los límites de píxeles en resoluciones más pequeñas.

Si tienes una acción personalizada con estado (si activa o desactiva una configuración de reproducción), proporciona diferentes íconos para los distintos estados de manera que los usuarios puedan ver los cambios cuando seleccionen la acción.

Proporciona un estilo de ícono alternativo para las acciones inhabilitadas

Si una acción personalizada no está disponible en el contexto actual, reemplaza el ícono de acción personalizada por uno alternativo que muestre que la acción está inhabilitada.

Ejemplos de íconos de acción personalizada que no están relacionados con el estilo.
Figura 1: Ejemplos de íconos de acción personalizada que no están relacionados con el estilo.

Indica el formato de audio

Para indicar que el contenido multimedia que se está reproduciendo usa un formato de audio especial, puedes especificar los íconos que se renderizan en vehículos compatibles con esta función. Puedes configurar KEY_CONTENT_FORMAT_TINTABLE_LARGE_ICON_URI y KEY_CONTENT_FORMAT_TINTABLE_SMALL_ICON_URI en el paquete de extras del elemento multimedia en reproducción (pasado a MediaSession.setMetadata). Establece ambos elementos adicionales para que se adapten a los diferentes diseños.

Además, puedes configurar el elemento adicional KEY_IMMERSIVE_AUDIO para indicarles a los OEMs de automóviles que se trata de audio envolvente, y ellos deben tener mucho cuidado a la hora de decidir si aplican efectos de audio que podrían interferir con el contenido envolvente.

Puedes configurar el elemento multimedia que se está reproduciendo para que el subtítulo, la descripción o ambos sean vínculos a otros elementos multimedia. Eso permite al usuario saltar rápidamente a elementos relacionados, por ejemplo, a otras canciones del mismo artista o a otros episodios de un podcast. Si el vehículo admite esta función, los usuarios pueden presionar el vínculo para explorar ese contenido.

Para agregar vínculos, configura los metadatos KEY_SUBTITLE_LINK_MEDIA_ID (para vincular desde el subtítulo) o KEY_DESCRIPTION_LINK_MEDIA_ID (para vincular desde la descripción). Para obtener más detalles, consulta la documentación de referencia de esos campos de metadatos.