El siguiente procedimiento te permite convertir tu app emisora de Android de Versión 2 del SDK de Cast con CCL a CAF. Todas las funciones de CCL implementada en CAF, por lo que, una vez que realices la migración, ya no necesitarás usar CCL.
El SDK de Cast CAF Sender usa CastContext para administrar GoogleAPIClient en tu nombre. CastContext administra ciclos de vida, errores y devoluciones de llamada por ti, lo que en gran medida simplifica el desarrollo de una app de Cast.
Introducción
- Como la Biblioteca complementaria de Cast influyó en el diseño del remitente de CAF, la migración de CCL a CAF Sender implica principalmente asignaciones uno a uno de clases y sus métodos.
- CAF Sender se sigue distribuyendo como parte de Google Play Services. con SDK Manager de Android.
- Paquetes nuevos (
com.google.android.gms.cast.framework.*
) que se agregado a CAF Sender, con una funcionalidad similar a CCL, la responsabilidad de cumplir con las Lista de tareas de diseño de Google Cast - El remitente de CAF proporciona widgets que cumplen con los requisitos de UX de Cast. estos widgets son similares a los que proporciona CCL.
- CAF Sender proporciona devoluciones de llamada asíncronas que son similares a CCL, para rastrear estados y obtener datos. A diferencia de CCL, CAF Sender no proporciona ningún de los diversos métodos de interfaz.
En las siguientes secciones, nos enfocaremos principalmente en basadas en VideoCastManager de CCL, pero en muchos casos, la misma se aplican a DataCastManager también.
Dependencias
CCL y CAF tienen las mismas dependencias en la biblioteca de compatibilidad de AppCompat, Biblioteca de compatibilidad de MediaRouter v7 y Servicios de Google Play. Sin embargo, la diferencia es que CAF depende del nuevo framework de Cast disponible en Google Play. services 9.2.0 o versiones posteriores.
En tu archivo build.gradle, quita las dependencias en
com.google.android.gms:play-services-cast
y
com.google.android.libraries.cast.companionlibrary:ccl
,
Luego, agrega el nuevo framework de Cast:
dependencies {
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:mediarouter-v7:23.4.0'
compile 'com.google.android.gms:play-services-cast-framework:9.4.0'
}
También puedes quitar los metadatos de los Servicios de Google Play de la siguiente manera:
<meta‐data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>
Todos los servicios, actividades y recursos que formen parte de CAF se se combinarán con el manifiesto y los recursos de tu app.
La versión mínima del SDK de Android compatible con CAF es la 9 (Gingerbread); La versión mínima del SDK de Android para CCL es la 10.
CCL proporciona un método conveniente,
BaseCastManager.checkGooglePlayServices(activity)
para verificar que se haya
versión de los Servicios de Google Play esté disponible en el dispositivo. El CAF no
proporcionarla como parte del SDK de Cast. Sigue el procedimiento
Asegúrate de que los dispositivos tengan el APK de Servicios de Google Play
para asegurarte de que el APK correcto de los Servicios de Google Play esté instalado en el
dispositivo, ya que es posible que
las actualizaciones no lleguen a todos los usuarios de inmediato.
Aún debes usar una variante de Theme.AppCompat para la configuración el tema.
Inicialización
Para CCL, se requería llamar a VideoCastManager.initialize()
en el
El método onCreate()
de la instancia de Aplicaciones Esta lógica debería ser
del código de la clase Application.
En CAF, también se requiere un paso de inicialización explícito para la transmisión
en un framework de aplicaciones. Esto implica inicializar el singleton CastContext
con un
el OptionsProvider
apropiado para especificar el ID de aplicación del receptor y cualquier
otras opciones globales. CastContext
cumple una función similar a la de CCL.
VideoCastManager
proporcionando un singleton con el que los clientes pueden interactuar
OptionsProvider
es similar a CastConfiguration
de CCL para permitirte
para configurar las funciones del framework de Cast.
Si tu CastConfiguration.Builder
de CCL actual se ve de la siguiente manera:
VideoCastManager.initialize(
getApplicationContext(),
new CastConfiguration.Builder(context.getString(R.string.app_id))
.enableWifiReconnection()
.enableAutoReconnect()
.build());
Luego, en CAF, el siguiente CastOptionsProvider
con CastOptions.Builder
sería similar:
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;
}
}
Consulta nuestra app de ejemplo. para obtener una implementación completa de OptionsProvider.
Declara el OptionsProvider dentro de la “aplicación” elemento de la Archivo AndroidManifest.xml:
<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 cada método onCreate
de Activity
.
(y no la instancia Application
):
private CastContext mCastContext;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video_browser);
setupActionBar();
mCastContext = CastContext.getSharedInstance(this);
}
Para acceder al singleton CastContext
, usa lo siguiente:
mCastContext = CastContext.getSharedInstance(this);
Cómo detectar dispositivos
Los VideoCastManager
incrementUiCounter
y decrementUiCounter
de CCL deben
Se quitarán de los métodos onResume
y onPause
de tu Activities
.
En CAF, el proceso de detección se inicia y se detiene automáticamente cuando la app pasa a primer plano y a segundo plano, respectivamente.
Botón para transmitir y diálogo de transmisión
Al igual que con CCL, la asistencia de MediaRouter v7 proporciona estos componentes. biblioteca.
MediaRouteButton
aún implementa el botón para transmitir, y puedes agregarlo
a tu actividad (mediante un ActionBar
o un Toolbar
), como un elemento de menú
del menú.
La declaración de MediaRouteActionProvider
en el XML del menú es la misma que
con CCL:
<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"/>
Similar a CCL, anula el método onCreateOptionMenu() de cada Activity, pero en lugar de usar CastManager.addMediaRouterButton, usa CastButtonFactory de CAF Para conectar el MediaRouteButton al framework de Cast, haz lo siguiente:
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.browse, menu);
CastButtonFactory.setUpMediaRouteButton(getApplicationContext(),
menu,
R.id.media_route_menu_item);
return true;
}
Control de dispositivos
Al igual que en CCL, en CAF, el control de dispositivos lo maneja en gran medida el framework.
La aplicación emisora no necesita controlarla (ni debe intentar hacerlo).
conectarse al dispositivo e iniciar la aplicación receptora mediante
GoogleApiClient
La interacción entre el remitente y el receptor ahora se representa como una "sesión". El
La clase SessionManager
controla el ciclo de vida de la sesión y se inicia automáticamente
y detiene las sesiones 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 lo presiona.
el botón "Detener la transmisión" en el diálogo Transmitir o cuando la propia app emisora
y finaliza el proceso.
En CCL, debes extender la clase VideoCastConsumerImpl
para hacer un seguimiento de la transmisión
estado de la sesión:
private final VideoCastConsumer mCastConsumer = new VideoCastConsumerImpl() {
public void onApplicationConnected(ApplicationMetadata appMetadata,
String sessionId,
boolean wasLaunched) {}
public void onDisconnectionReason(int reason) {}
public void onDisconnected() {}
}
En CAF, la aplicación emisora puede recibir notificaciones de los eventos del ciclo de vida de la sesión
registrando un SessionManagerListener
con SessionManager
. El
Las devoluciones de llamada de SessionManagerListener definen métodos de devolución de llamada para todas las sesiones
de ciclo de vida de los objetos.
Los siguientes métodos SessionManagerListener
se asignan a partir de CCL
Interfaz de VideoCastConsumer
:
VideoCastConsumer.onApplicationConnected
->SessionManagerListener.onSessionStarted
VideoCastConsumer.onDisconnected
->SessionManagerListener.onSessionEnded
Declara una clase que implemente la interfaz SessionManagerListener
y mueve
la lógica VideoCastConsumerImpl
con los métodos coincidentes:
private class CastSessionManagerListener implements SessionManagerListener<CastSession> {
public void onSessionEnded(CastSession session, int error) {}
public void onSessionStarted(CastSession session, String sessionId) {}
public void onSessionEnding(CastSession session) {}
...
}
La clase CastSession
representa una sesión con un dispositivo de transmisión. La clase tiene
métodos para controlar los estados de volumen y silencio del dispositivo, lo que hace CCL en el
BaseCastManager
En lugar de usar la CCL VideoCastManager
para agregar un consumidor, haz lo siguiente:
VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);
Ahora registra tu SessionManagerListener
:
mCastSessionManager =
CastContext.getSharedInstance(this).getSessionManager();
mCastSessionManagerListener = new CastSessionManagerListener();
mCastSessionManager.addSessionManagerListener(mCastSessionManagerListener,
CastSession.class);
Para dejar de escuchar eventos en CCL, haz lo siguiente:
VideoCastManager.getInstance().removeVideoCastConsumer(mCastConsumer);
Ahora, usa SessionManager
para dejar de escuchar los eventos de sesión:
mCastSessionManager.removeSessionManagerListener(mCastSessionManagerListener,
CastSession.class);
Para desconectarse explícitamente del dispositivo de transmisión, CCL usó lo siguiente:
VideoCastManager.disconnectDevice(boolean stopAppOnExit,
boolean clearPersistedConnectionData,
boolean setDefaultRoute)
Para CAF, usa SessionManager
:
CastContext.getSharedInstance(this).getSessionManager()
.endCurrentSession(true);
Para determinar si el remitente está conectado con el receptor, CCL proporciona
VideoCastManager.getInstance().isConnected()
, pero, en CAF, usa el
SessionManager
public boolean isConnected() {
CastSession castSession = CastContext.getSharedInstance(mAppContext)
.getSessionManager()
.getCurrentCastSession();
return (castSession != null && castSession.isConnected());
}
En CAF, las notificaciones sobre cambios de volumen o silencio se siguen entregando mediante devolución de llamada
métodos en Cast.Listener
; estos objetos de escucha están registrados con
CastSession
Todas las notificaciones restantes sobre el estado del dispositivo se envían a través de
CastStateListener
devoluciones de llamada; estos objetos de escucha se registran con el
CastSession
Asegúrate de cancelar el registro de los objetos de escucha cuando
Los fragmentos, las actividades o las apps pasan a segundo plano.
Lógica de reconexión
El CAF intenta restablecer las conexiones de red que se pierden debido a una pérdida temporal de la señal de Wi-Fi u otros errores de red. Ahora esto se hace en la nivel de sesión; una sesión puede entrar en estado "suspendido" el estado cuando la conexión está se pierde y vuelve a cambiar a una cuenta “conectada” cuando la conectividad está restaurado. El framework se encarga de volver a conectarse a la aplicación receptora y volver a conectar cualquier canal de transmisión como parte del proceso.
CAF proporciona su propio servicio de reconexión, por lo que puedes quitar
la CCL ReconnectionService
de tu manifiesto:
<service android:name="com.google.android.libraries.cast.companionlibrary.cast.reconnection.ReconnectionService"/>
Tampoco necesitas los siguientes permisos en tu manifiesto para el lógica de reconexión:
<uses‐permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses‐permission android:name="android.permission.ACCESS_WIFI_STATE"/>
El servicio de reconexión de CAF se habilita de forma predeterminada, pero se puede inhabilitar usando el
CastOptions
Además, el CAF también agrega la reanudación automática de la sesión, que se habilita mediante
de forma predeterminada (y se puede desactivar mediante CastOptions
). Si la aplicación remitente está
se envía a segundo plano o se finaliza (cuando se desliza o debido a una falla)
mientras una sesión de transmisión está en curso, el framework intentará reanudar esa
cuando la aplicación emisora vuelve al primer plano o se reinicia;
SessionManager
se encarga automáticamente de esto, que emitirá el
las devoluciones de llamada correspondientes en cualquier instancia SessionManagerListener
registrada.
Registro de canales personalizados
CCL proporciona dos formas de crear un canal de mensajes personalizado para el receptor:
CastConfiguration
te permite especificar varios espacios de nombres, y CCL y, luego, crear el canal por ti.DataCastManager
es similar a VideoCastManager, pero se enfoca en contenido que no es multimedia. casos de uso.
CAF no admite ninguna de estas formas de crear canales personalizados: en su lugar, deberás seguir el procedimiento Agrega un canal personalizado para tu app emisora.
Al igual que con CCL, para las aplicaciones de medios, no es necesario registrar el canal de control de contenido multimedia.
Control multimedia
En CAF, la clase RemoteMediaClient
es equivalente a VideoCastManager
.
métodos multimedia. RemoteMediaClient.Listener
es equivalente a
VideoCastConsumer
. En particular, el
onRemoteMediaPlayerMetadataUpdated
y onRemoteMediaPlayerStatusUpdated
métodos de VideoCastConsumer
se mapean a onMetadataUpdated
y
onStatusUpdated
de RemoteMediaClient.Listener
, respectivamente:
private class CastMediaClientListener implements RemoteMediaClient.Listener {
@Override
public void onMetadataUpdated() {
setMetadataFromRemote();
}
@Override
public void onStatusUpdated() {
updatePlaybackState();
}
@Override
public void onSendingRemoteMediaRequest() {
}
@Override
public void onQueueStatusUpdated() {
}
@Override
public void onPreloadStatusUpdated() {
}
}
No es necesario inicializar ni registrar de forma explícita el RemoteMediaClient
.
object; el framework creará automáticamente una instancia del objeto y registrará
canal de medios subyacente al momento de inicio de la sesión si la aplicación receptora
conectado admite el espacio de nombres de contenido multimedia.
Se puede acceder a RemoteMediaClient
como el método getRemoteMediaClient
de
el objeto CastSession
.
CastSession castSession = CastContext.getSharedInstance(mAppContext)
.getSessionManager()
.getCurrentCastSession();
mRemoteMediaClient = castSession.getRemoteMediaClient();
mRemoteMediaClientListener = new CastMediaClientListener();
En lugar de las CCL:
VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);
Ahora, usa CAF:
mRemoteMediaClient.addListener(mRemoteMediaClientListener);
Se puede registrar cualquier cantidad de objetos de escucha con el RemoteMediaClient
,
que permite que múltiples componentes de remitente compartan una sola instancia de
RemoteMediaClient
asociada con la sesión.
VideoCastManager
de CCL proporciona métodos para controlar la reproducción de contenido multimedia:
VideoCastManager manager = VideoCastManager.getInstance();
if (manager.isRemoteMediaLoaded()) {
manager.pause();
mCurrentPosition = (int) manager.getCurrentMediaPosition();
}
RemoteMediaClient ahora las implementa en CAF:
if (mRemoteMediaClient.hasMediaSession()) {
mRemoteMediaClient.pause();
mCurrentPosition =
(int)mRemoteMediaClient.getApproximateStreamPosition();
}
En CAF, todas las solicitudes de contenido multimedia emitidas en RemoteMediaClient
muestran un
RemoteMediaClient.MediaChannelResult
mediante una devolución de llamada de PendingResult
que puede usarse para hacer un seguimiento del progreso y el resultado final de la solicitud.
Tanto CCL como CAF usan las clases MediaInfo
y MediaMetadata
para representar
elementos multimedia y cargar contenido multimedia.
Para cargar contenido multimedia en CCL, se usa VideoCastManager
:
VideoCastManager.getInstance().loadMedia(media, autoPlay, mCurrentPosition, customData);
En CAF, se usa RemoteMediaClient
para cargar los medios:
mRemoteMediaClient.load(media, autoPlay, mCurrentPosition, customData);
Para obtener la información y el estado de Media
de una sesión multimedia actual en la
CCL usa VideoCastManager
:
MediaInfo mediaInfo = VideoCastManager.getInstance()
.getRemoteMediaInformation();
int status = VideoCastManager.getInstance().getPlaybackStatus();
int idleReason = VideoCastManager.getInstance().getIdleReason();
En CAF, usa RemoteMediaClient
para obtener la misma información:
MediaInfo mediaInfo = mRemoteMediaClient.getMediaInfo();
int status = mRemoteMediaClient.getPlayerState();
int idleReason = mRemoteMediaClient.getIdleReason();
Superposición introductoria
Al igual que CCL, CAF proporciona una vista personalizada IntroductoryOverlay
para destacar.
el botón para transmitir cuando se muestre por primera vez a los usuarios.
En lugar de usar el método VideoCastConsumer
onCastAvailabilityChanged
de CCL
Para saber cuándo mostrar la superposición, declara un CastStateListener
para determinar
cuando el botón para transmitir se vuelva visible una vez que se detecten dispositivos de transmisión en la
red local por el MediaRouter
:
private IntroductoryOverlay mIntroductoryOverlay;
private MenuItem mMediaRouteMenuItem;
protected void onCreate(Bundle savedInstanceState) {
...
mCastStateListener = new CastStateListener() {
@Override
public void onCastStateChanged(int newState) {
if (newState != CastState.NO_DEVICES_AVAILABLE) {
showIntroductoryOverlay();
}
}
};
mCastContext = CastContext.getSharedInstance(this);
mCastContext.registerLifecycleCallbacksBeforeIceCreamSandwich(this,
savedInstanceState);
}
protected void onResume() {
mCastContext.addCastStateListener(mCastStateListener);
...
}
protected void onPause() {
mCastContext.removeCastStateListener(mCastStateListener);
...
}
Realiza un seguimiento de la instancia MediaRouteMenuItem
:
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.browse, menu);
mMediaRouteMenuItem = CastButtonFactory.setUpMediaRouteButton(
getApplicationContext(), menu,
R.id.media_route_menu_item);
showIntroductoryOverlay();
return true;
}
Verifica si el elemento MediaRouteButton
es visible para que la superposición introductoria
se pueden mostrar:
private void showIntroductoryOverlay() {
if (mIntroductoryOverlay != null) {
mIntroductoryOverlay.remove();
}
if ((mMediaRouteMenuItem != null) && mMediaRouteMenuItem.isVisible()) {
new Handler().post(new Runnable() {
@Override
public void run() {
mIntroductoryOverlay = new IntroductoryOverlay.Builder(
VideoBrowserActivity.this, mMediaRouteMenuItem)
.setTitleText(getString(R.string.introducing_cast))
.setOverlayColor(R.color.primary)
.setSingleTime()
.setOnOverlayDismissedListener(
new IntroductoryOverlay
.OnOverlayDismissedListener() {
@Override
public void onOverlayDismissed() {
mIntroductoryOverlay = null;
}
})
.build();
mIntroductoryOverlay.show();
}
});
}
}
Consulta nuestra app de ejemplo para ver el código funcional completo para mostrar la superposición introductoria.
Para personalizar el estilo de la superposición introductoria, sigue el procedimiento Cómo personalizar la superposición introductoria
Minicontrolador
En lugar de MiniController
de CCL, usa MiniControllerFragment
de CAF en tu
archivo de diseño de app de las actividades en las que quieres mostrar la mini
responsable del tratamiento de datos:
<fragment
android:id="@+id/cast_mini_controller"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:castShowImageThumbnail="true"
android:visibility="gone"
class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment" />
CAF no admite la configuración manual compatible con MiniController
de CCL
Tampoco es compatible con la función Autoplay
.
Para personalizar el estilo y los botones del minicontrol, sigue las procedimiento Personalizar el minicontrol.
Notificaciones y pantalla de bloqueo
Al igual que VideoCastNotificationService
de CCL, CAF proporciona un
MediaNotificationService
para administrar la visualización de las notificaciones multimedia
durante la transmisión.
Debes quitar lo siguiente de tu manifiesto:
VideoIntentReceiver
VideoCastNotificationService
CCL admite proporcionar un servicio de notificación personalizado con el
CastConfiguration.Builder
; que no es compatible con CAF.
Considera la siguiente inicialización de CastManager
mediante CCL:
VideoCastManager.initialize(
getApplicationContext(),
new CastConfiguration.Builder(
context.getString(R.string.app_id))
.addNotificationAction(
CastConfiguration.NOTIFICATION_ACTION_PLAY_PAUSE,true)
.addNotificationAction(
CastConfiguration.NOTIFICATION_ACTION_DISCONNECT,true)
.build());
Para la configuración equivalente en CAF, el SDK proporciona una
NotificationsOptions.Builder
para ayudarte a crear controles multimedia para la
y la pantalla de bloqueo para acceder a la app emisora. La notificación y el bloqueo
los controles de pantalla pueden habilitarse con CastOptions
al inicializar la
CastContext
public CastOptions getCastOptions(Context context) {
NotificationOptions notificationOptions =
new NotificationOptions.Builder()
.setActions(Arrays.asList(
MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK,
MediaIntentReceiver.ACTION_STOP_CASTING), new int[]{0, 1})
.build();
CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
.setNotificationOptions(notificationOptions)
.build();
return new CastOptions.Builder()
.setReceiverApplicationId(context.getString(R.string.app_id))
.setCastMediaOptions(mediaOptions)
.build();
}
Las notificaciones y los controles de la pantalla de bloqueo siempre están habilitados en CAF. Además, ten en cuenta que
los botones para reproducir/pausar y detener la transmisión se incluyen de forma predeterminada. CAF
hará un seguimiento automático de la visibilidad de las actividades para decidir
cuándo mostrar la notificación multimedia, excepto Gingerbread.
(Para Gingerbread, consulta la nota anterior sobre
usando registerLifecycleCallbacksBeforeIceCreamSandwich()
; CCL
VideoCastManager
llamadas a incrementUiCounter
y decrementUiCounter
se debe quitar).
Para personalizar los botones que se muestran en las notificaciones, sigue las procedimiento Agrega controles multimedia a las notificaciones y a la pantalla de bloqueo.
Control expandido
CCL proporciona VideoCastControllerActivity
y VideoCastControllerFragment
para mostrar un control expandido cuando se transmite contenido multimedia.
Puedes quitar la declaración VideoCastControllerActivity
en el manifiesto.
En CAF, debes Extiende ExpandedControllerActivity y agrega el botón para transmitir.
Para personalizar los estilos y botones que se muestran en el responsable del tratamiento de datos, sigue el procedimiento Personaliza el control expandido.
Enfoque de audio
Al igual que con CCL, el foco de audio se administra automáticamente.
Control de volumen
Para Gingerbread, se requiere dispatchKeyEvent
como para CCL. En ICS y versiones posteriores
para el control de volumen de CCL y CAF.
CAF permite controlar el volumen de la transmisión con el botón de volumen forzado en la teléfono dentro de las actividades de la aplicación y muestra una barra de volumen visual cuando transmitir en versiones compatibles. CAF también se encarga de los cambios de volumen volumen intenso, incluso si la app no está al frente, está bloqueada o incluso si la pantalla está desactivado.
Subtítulos
En Android KitKat y versiones posteriores, puedes usar subtítulos para personalizar los subtítulos. Configuración, en Configuración > Accesibilidad. Las versiones anteriores de Android, pero no tienen esta capacidad. CCL se encarga de esto proporcionando configuración de versiones anteriores y delegación de la configuración del sistema en KitKat y superiores.
CAF no ofrece una configuración personalizada para cambiar las preferencias de subtítulos. Tú
Debes quitar las referencias a CaptionsPreferenceActivity
en tu manifiesto
y tus preferencias XML.
Ya no se necesita TracksChooserDialog
de CCL porque se cambió la opción de cierre
las pistas de subtítulos se controlan mediante la IU del controlador expandido.
La API de subtítulos opcionales en CAF es similar a v2.
Registro de depuración
CAF no proporciona la configuración de registro de depuración.
Varios
Las siguientes funciones de CCL no son compatibles con CAF:
- Obtención de autorización antes de la reproducción proporcionando un
MediaAuthService
- Mensajes configurables de la IU
Apps de ejemplo
Consulta las diferencias para migrar nuestra app de ejemplo Universal Music Player para Android (uamp) de CCL a CAF.
También tenemos instructivos de codelabs y apps de ejemplo que usan CAF.