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

El siguiente procedimiento te permite convertir la app emisora de Android del SDK de Cast v2 en una app emisora de CAF, que se basa en el singleton CastContext.

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

Introducción

  • El remitente de CAF aún se distribuye como parte de los Servicios de Google Play mediante SDK Manager 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.*).
  • El remitente de CAF proporciona widgets que cumplen con los requisitos de UX de Cast. La versión 2 no proporciona ningún componente de IU y requiere que los implementes.
  • Ya no se requiere el uso de GoogleApiClient para utilizar la API de Cast.
  • Los subtítulos opcionales en el remitente de CAF son similares a los de la versión 2.

Dependencias

V2 y CAF tienen las mismas dependencias en las bibliotecas de compatibilidad y los Servicios de Google Play (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 aplicación del 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 en 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>

Inicializa de forma diferida el CastContext en el método onCreate de cada Activity:

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 automáticamente el proceso de descubrimiento cuando la app pasa a primer plano y a segundo plano, respectivamente. No se deben usar MediaRouteSelector ni MediaRouter.Callback.

Botón y diálogo para transmitir

Al igual que en la versión 2, la biblioteca de compatibilidad de MediaRouter proporciona estos componentes.

El botón para transmitir se implementa a través de MediaRouteButton y se puede agregar a tu actividad (mediante un ActionBar o un Toolbar) como elemento de menú del 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 mediante 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, se presenta automáticamente el diálogo de transmisión.

Control de dispositivos

En CAF, el framework se encarga en gran medida del control de dispositivos. La aplicación emisora no necesita controlar (ni debe intentar controlar) la conexión al dispositivo y el inicio de la aplicación receptora web con GoogleApiClient. La interacción entre el remitente y el receptor web ahora se representa como una “sesión”. La clase SessionManager 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 de transmisión en el diálogo de transmisión y finaliza cuando el usuario presiona el botón "Detener transmisión" en el diálogo de transmisión o cuando finaliza la app emisora. La aplicación emisora puede recibir una notificación sobre los eventos del ciclo de vida de la sesión registrando un SessionManagerListener con el SessionManager. Las devoluciones de llamada SessionManagerListener definen los métodos de devolución de llamada para todos los eventos del ciclo de vida de la sesión.

La clase CastSession representa una sesión con un dispositivo de transmisión. 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 devoluciones de llamada Cast.Listener proporcionaban notificaciones de los cambios en el estado del dispositivo, incluidos el volumen, el estado de silencio y el estado en espera, entre otros.

En CAF, las notificaciones de cambio de estado de volumen y sonido se siguen entregando a través de métodos de devolución de llamada en Cast.Listener. Estos objetos de escucha se registran con CastSession. Todas las notificaciones de estado restantes del dispositivo se entregan a través de devoluciones de llamada de CastStateListener; 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 asociados pasen a segundo plano.

Lógica de reconexión

Al igual que con la versión 2, el CAF intenta restablecer las conexiones de red que se pierden debido a la pérdida temporal de la señal Wi-Fi o a otros errores de red. Esto se hace a nivel de la sesión; una sesión puede entrar en un estado "suspendido" cuando se pierde la conexión y regresará al estado "Conectada" cuando se restablezca la conectividad. El framework se encarga de volver a establecer la conexión con la aplicación receptora web y de cualquier canal de transmisión como parte del proceso.

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

Registro de canales personalizados

En la versión 2, los canales personalizados (implementados mediante 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 método de devolución de llamada SessionManagerListener.onSessionStarted. En el caso de las aplicaciones de música, ya no es necesario registrar explícitamente el canal de control de contenido multimedia a través de Cast.CastApi.setMessageReceivedCallbacks. Consulta la siguiente sección para obtener más detalles.

Control multimedia

La clase RemoteMediaPlayer de la v2 dejó de estar disponible y no se debe usar. En CAF, se reemplazó por la nueva clase RemoteMediaClient, que proporciona una funcionalidad equivalente en una API más conveniente. No es necesario inicializar o registrar este objeto de forma explícita. El framework creará automáticamente una instancia del objeto y registrará el canal de medios subyacente en el momento de inicio de la sesión si la aplicación receptora web a la que se conecta es compatible con el espacio de nombres de contenido multimedia.

Se puede acceder a RemoteMediaClient como el método getRemoteMediaClient 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 RemoteMediaClient muestran un RemoteMediaClient.MediaChannelResult a través de una devolución de llamada PendingResult que se puede usar para realizar un seguimiento del progreso y el resultado final de la solicitud.

La versión 2 RemoteMediaPlayer enviaría notificaciones sobre los cambios en el estado del reproductor de contenido multimedia en Web Receiver a través de RemoteMediaPlayer.OnStatusUpdatedListener.

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

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

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

Superposición introductoria

V2 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 deseas mostrar el minicontrolador.

Notificaciones y pantalla de bloqueo

En la versión 2, el SDK no proporciona controladores para las notificaciones y 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 la notificación y la pantalla de bloqueo en la app emisora. Los controles de notificaciones y de pantalla de bloqueo se pueden habilitar con CastOptions cuando se inicializa 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 controlador expandido desde cero en la app emisora.

CAF proporciona una clase de ayuda UIMediaController que te facilita la compilación de tu propio controlador expandido.

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

Foco de audio

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

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

Registro de depuración

En CAF, no hay opciones de registro.

Apps de ejemplo

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