El siguiente procedimiento te permite convertir tu app emisora de Android de la versión 2 del SDK de Cast a la de CAF, que se basa en el singleton 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, lo que simplifica enormemente el desarrollo de una app de Cast.
Introducción
- CAF Sender se sigue distribuyendo como parte de los Servicios de Google Play a través de Android SDK Manager.
- 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 proporcionaba ningún componente de IU y requería que implementaras estos widgets.
- Ya no es necesario usar GoogleApiClient para utilizar la API de Cast.
- Los subtítulos en CAF Sender 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
apropiado 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
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>
Inicializa de forma diferida 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 v2.
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 para transmitir y diálogo de transmisión
Al igual que en la v2, la biblioteca de compatibilidad de MediaRouter proporciona estos componentes.
El botón para transmitir aún se implementa en MediaRouteButton
y se puede agregar a tu actividad (mediante un ActionBar
o un Toolbar
), como un elemento de menú en el 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 usando 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 presione el botón, se presentará automáticamente el diálogo para transmitir.
Control de dispositivos
En CAF, el control de dispositivos lo controla en gran medida el framework. La aplicación emisora no necesita controlar (ni debe intentar controlar) la conexión al dispositivo y el inicio de la aplicación del receptor 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 e inicia y detiene las sesiones automáticamente en respuesta a los gestos del usuario: se inicia una sesión cuando el usuario selecciona un dispositivo de transmisión en el diálogo de transmisión y finaliza cuando presiona el botón "Detener la transmisión" en el diálogo de transmisión o cuando se cierra la app emisora. Se puede notificar a la aplicación emisora sobre los eventos del ciclo de vida de la sesión si se registra un SessionManagerListener
con el SessionManager
. Las devoluciones de llamada SessionManagerListener
definen métodos de devolución de llamada para todos los eventos de ciclo de vida de la sesión.
La clase CastSession
representa una sesión con un dispositivo de transmisión. La clase tiene métodos para controlar el volumen del dispositivo y los estados de silencio, lo que antes se hacía en la v2 con métodos en Cast.CastApi
.
En la versión 2, las devoluciones de llamada Cast.Listener
proporcionaban notificaciones de cambios en el estado del dispositivo, incluidos el volumen, el estado de silencio y el estado de espera, entre otros.
En CAF, las notificaciones de cambio de estado de volumen/silencio 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 v2, el CAF intenta restablecer las conexiones de red que se pierden debido a la pérdida temporal de la señal de Wi-Fi, o bien a otros errores de red. Esto ahora se hace a nivel de la sesión. Una sesión puede entrar en un estado de "suspendida" 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 del receptor web y de volver a conectar cualquier canal de transmisión como parte de este proceso.
Además, el CAF también agrega la reanudación automática de 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 a segundo plano o se cierra (mediante el deslizamiento 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 correspondientes en cualquier instancia 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 contenido multimedia, 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
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 de manera explícita este objeto; el framework creará automáticamente una instancia del objeto y registrará el canal multimedia subyacente al momento de inicio de la sesión si la aplicación del receptor web a la que se conecta admite el espacio de nombres 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
mostrarían un RemoteMediaPlayer.MediaChannelResult
mediante 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 de RemoteMediaPlayer
enviaría notificaciones sobre los cambios en el estado del reproductor multimedia en el receptor web a través de RemoteMediaPlayer.OnStatusUpdatedListener
.
En CAF, RemoteMediaClient
proporciona devoluciones de llamada equivalentes a través de su interfaz de RemoteMediaClient.Listener
. Cualquier cantidad de objetos de escucha se puede registrar con
RemoteMediaClient
, lo que permite que varios componentes de remitente compartan la
única instancia de RemoteMediaClient
asociada con la sesión.
En la v2, la aplicación emisora tenía que encargarse 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
que permite destacar el botón para transmitir cuando se muestra por primera vez a los usuarios.
Minicontrolador
En la v2, 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 v2, 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 notificación y de pantalla de bloqueo se pueden habilitar con CastOptions
cuando se inicializa 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.
El CAF proporciona una clase auxiliar UIMediaController
que te permite compilar fácilmente tu propio control expandido.
CAF agrega un widget de control expandido previamente compilado ExpandedControllerActivity
que puedes agregar 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.