Migra la app Sender de Android del SDK de Cast v2 al framework de aplicaciones de Cast (CAF)

El siguiente procedimiento te permite convertir tu app emisora de Android del SDK de Cast v2 a CAF Sender, que se basa en el CastContext CastContext.

El SDK de Cast CAF Sender usa CastContext para administrar GoogleAPIClient en tu nombre. CastContext administra los ciclos de vida, los errores y las devoluciones de llamada por ti, lo que simplifica en gran medida el desarrollo de una app de Cast.

Introducción

  • CAF Sender aún se distribuye como parte de los Servicios de Google Play con el administrador del SDK de Android.
  • Se agregaron paquetes nuevos que asumen la responsabilidad de cumplir con la lista de tareas de diseño de Google Cast (com.google.android.gms.cast.framework.*).
  • CAF Sender proporciona widgets que cumplen con los requisitos de UX de Cast. La versión 2 no proporcionó ningún componente de IU y requirió que implementaras estos widgets.
  • Ya no es necesario usar GoogleApiClient para usar la API de Cast.
  • Los subtítulos opcionales en CAF Sender son similares a la versión 2.

Dependencias

Las versiones 2 y CAF tienen las mismas dependencias en las bibliotecas de compatibilidad y los Servicios de Google Play services (9.2.0 o versiones posteriores), como se describe en la Guía de funciones de la biblioteca de compatibilidad

La versión mínima del SDK de Android que admite CAF es 9 (Gingerbread).

Inicialización

En CAF, se requiere un paso de inicialización explícito para el framework de Cast. Esto implica inicializar el singleton CastContext con un OptionsProvider adecuado para especificar el ID de la aplicación de receptor web y cualquier otra opción global.

public class CastOptionsProvider implements OptionsProvider {

    @Override
    public CastOptions getCastOptions(Context context) {
        return new CastOptions.Builder()
                .setReceiverApplicationId(context.getString(R.string.app_id))
                .build();
    }

    @Override
    public List<SessionProvider> getAdditionalSessionProviders(Context context) {
        return null;
    }
}

Declara el OptionsProvider dentro de la etiqueta "application" del archivo AndroidManifest.xml de la app:

<application>
...
    <meta-data
        android:name=
            "com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
        android:value="com.google.sample.cast.refplayer.CastOptionsProvider" />
</application>

Inicia el CastContext de manera diferida en el método onCreate de cada actividad:

private CastContext mCastContext;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.video_browser);
    setupActionBar();

    mCastContext = CastContext.getSharedInstance(this);
}

Estos pasos no eran necesarios en la versión 2.

Detección de dispositivos

En CAF, el framework inicia y detiene el proceso de detección automáticamente cuando la app pasa al primer plano y al segundo plano, respectivamente. No se deben usar MediaRouteSelector ni MediaRouter.Callback.

Botón para transmitir y diálogo de Cast

Al igual que en la versión 2, estos componentes se proporcionan a través de la biblioteca de compatibilidad de MediaRouter.

El botón para transmitir aún se implementa con MediaRouteButton y se puede agregar a tu actividad (con una ActionBar o una Toolbar), como un elemento de menú en tu menú.

<item
    android:id="@+id/media_route_menu_item"
    android:title="@string/media_route_menu_title"
    app:actionProviderClass="android.support.v7.app.MediaRouteActionProvider"
    app:showAsAction="always"/>

Anula el método onCreateOptionMenu() de cada actividad con CastButtonFactory para conectar MediaRouteButton al framework de Cast:

private MenuItem mediaRouteMenuItem;

public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    getMenuInflater().inflate(R.menu.browse, menu);
    mediaRouteMenuItem =
        CastButtonFactory.setUpMediaRouteButton(getApplicationContext(),
                                                menu,
                                                R.id.media_route_menu_item);
    return true;
}

Cuando alguien presiona el botón, el diálogo de Cast se presenta automáticamente.

Control de dispositivos

En CAF, el framework controla en gran medida el control de dispositivos. La aplicación emisora no necesita controlar (y no debería intentar controlar) la conexión al dispositivo ni iniciar la aplicación de receptor web con GoogleApiClient. La interacción entre el emisor y el receptor web ahora se representa como una "sesión". La SessionManager clase controla el ciclo de vida de la sesión y la inicia y detiene automáticamente en respuesta a los gestos del usuario: una sesión se inicia cuando el usuario selecciona un dispositivo Cast en el diálogo de Cast y finaliza cuando el usuario presiona el botón "Detener transmisión" en el diálogo de Cast o cuando finaliza la app emisora. Para recibir notificaciones sobre los eventos del ciclo de vida de la sesión, la aplicación emisora puede registrar un SessionManagerListener con el SessionManager. Las devoluciones de llamada SessionManagerListener definen métodos de devolución de llamada para todos los eventos del ciclo de vida de la sesión.

La CastSession clase representa una sesión con un dispositivo Cast. La clase tiene métodos para controlar el volumen del dispositivo y los estados de silencio, lo que antes se hacía en la versión 2 con métodos en Cast.CastApi.

En la versión 2, las Cast.Listener devoluciones de llamada proporcionaban notificaciones de cambios en el estado del dispositivo, incluido el volumen, el estado de silencio, el estado de espera, etcétera.

En CAF, las notificaciones de cambio de estado de volumen o silencio aún se entregan a través de métodos de devolución de llamada en los Cast.Listener; estos objetos de escucha se registran con CastSession. Todas las notificaciones restantes del estado del dispositivo se entregan a través de CastStateListener devoluciones de llamada. Estos objetos de escucha se registran con CastSession. Asegúrate de cancelar el registro de los objetos de escucha cuando los fragmentos, las actividades o las apps asociadas pasen al segundo plano.

Lógica de reconexión

Al igual que con la versión 2, CAF intenta restablecer las conexiones de red que se pierden debido a la pérdida temporal de la señal de Wi-Fi o a otros errores de red. Esto ahora se realiza a nivel de la sesión. Una sesión puede ingresar a un estado "suspendido" cuando se pierde la conexión y volverá a un estado "conectado" cuando se restablezca la conectividad. El framework se encarga de volver a conectarse a la aplicación de receptor web y de volver a conectar cualquier canal de Cast como parte de este proceso.

Además, CAF también agrega la reanudación automática de la sesión, que está habilitada de forma predeterminada (y se puede desactivar a través de CastOptions. Si la aplicación emisora se envía al segundo plano o finaliza (deslizando el dedo o debido a una falla) mientras una sesión de Cast está en curso, el framework intentará reanudar esa sesión cuando la aplicación emisora vuelva al primer plano o se vuelva a iniciar. Esto se controla automáticamente con SessionManager, que emitirá las devoluciones de llamada adecuadas en cualquier instancia SessionManagerListener registrada.

Registro de canales personalizados

En la versión 2, los canales personalizados (implementados con Cast.MessageReceivedCallback) se registran con Cast.CastApi. En CAF, los canales personalizados se registran con la instancia CastSession. El registro se puede realizar en el SessionManagerListener.onSessionStarted método de devolución de llamada. En el caso de las aplicaciones de contenido multimedia, ya no es necesario registrar explícitamente el canal de control multimedia a través de Cast.CastApi.setMessageReceivedCallbacks. Consulta la siguiente sección para obtener más detalles.

Control multimedia

La clase de la versión 2 RemoteMediaPlayer está obsoleta y no se debe usar. En CAF, se reemplaza por la nueva RemoteMediaClient clase, que proporciona una funcionalidad equivalente en una API más conveniente. No es necesario inicializar ni registrar explícitamente este objeto. El framework creará una instancia del objeto automáticamente y registrará el canal de contenido multimedia subyacente en el momento de inicio de la sesión si la aplicación de receptor web a la que se conecta admite el espacio de nombres de contenido multimedia.

Se puede acceder a RemoteMediaClient como el getRemoteMediaClient método del objeto CastSession.

En la versión 2, todas las solicitudes de contenido multimedia emitidas en el RemoteMediaPlayer mostraban un RemoteMediaPlayer.MediaChannelResult a través de una devolución de llamada PendingResult.

En CAF, todas las solicitudes de contenido multimedia emitidas en el RemoteMediaClient muestran un RemoteMediaClient.MediaChannelResult a través de una devolución de llamada PendingResult que se puede usar para hacer un seguimiento del progreso y el resultado final de la solicitud.

La versión 2 RemoteMediaPlayer enviaba notificaciones sobre los cambios en el estado del reproductor de contenido multimedia en el receptor web a través de RemoteMediaPlayer.OnStatusUpdatedListener.

En CAF, el RemoteMediaClient proporciona devoluciones de llamada equivalentes a través de su RemoteMediaClient.Listener interfaz. Se puede registrar cualquier cantidad de objetos de escucha con RemoteMediaClient, lo que permite que varios componentes emisores compartan la instancia única de RemoteMediaClient asociada con la sesión.

En la versión 2, la aplicación emisora tenía que asumir la carga de mantener la interfaz de usuario sincronizada con el estado del reproductor de contenido multimedia en el receptor web.

En CAF, la clase UIMediaController asume la mayor parte de esta responsabilidad.

Superposición introductoria

La versión 2 no proporciona una IU de superposición introductoria.

CAF proporciona una vista personalizada IntroductoryOverlay para destacar el botón para transmitir cuando se muestra por primera vez a los usuarios.

Minicontrolador

En la versión 2, debes implementar un minicontrolador desde cero en la app emisora.

En CAF, el SDK proporciona una vista personalizada, MiniControllerFragment, que puedes agregar al archivo de diseño de la app de las actividades en las que quieras mostrar el minicontrolador.

Notificaciones y pantalla de bloqueo

En la versión 2, el SDK no proporciona controladores para las notificaciones ni la pantalla de bloqueo. Para ese SDK, debes compilar estas funciones en tu app emisora con las APIs del framework de Android.

En CAF, el SDK proporciona un NotificationsOptions.Builder para ayudarte a compilar controles multimedia para las notificaciones y la pantalla de bloqueo en la app emisora. Los controles de notificación y pantalla de bloqueo se pueden habilitar con las CastOptions cuando inicialices el CastContext.

public CastOptions getCastOptions(Context context) {
    NotificationOptions notificationOptions = new NotificationOptions.Builder()
            .setTargetActivityClassName(VideoBrowserActivity.class.getName())
            .build();
    CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
            .setNotificationOptions(notificationOptions)
            .build();

    return new CastOptions.Builder()
            .setReceiverApplicationId(context.getString(R.string.app_id))
            .setCastMediaOptions(mediaOptions)
            .build();
}

Control expandido

En la versión 2, debes implementar un control expandido desde cero en la app emisora.

CAF proporciona una clase auxiliar UIMediaController que te permite compilar tu propio control expandido con facilidad.

CAF agrega un widget de control expandido precompilado ExpandedControllerActivity que puedes agregar a tu app. Ya no necesitas implementar un control expandido personalizado con UIMediaController.

Enfoque de audio

En la versión 2, debes usar MediaSessionCompat para administrar el enfoque de audio.

En CAF, el enfoque de audio se administra automáticamente.

Registro de depuración

En CAF, no hay opciones de registro.

Apps de ejemplo

Tenemos instructivos de codelab y apps de ejemplo que usan CAF.