Migrer l'application CCL Sender vers le framework d'application Cast (CAF)

La procédure suivante vous permet de convertir votre application Android émettrice du SDK Cast v2 avec CCL en CAF. Toutes les fonctionnalités des CCL ont été implémentées dans CAF. Vous n'aurez donc plus besoin d'utiliser CCL une fois la migration effectuée.

Le SDK Cast de l'expéditeur CAF utilise CastContext pour gérer le GoogleAPIClient en votre nom. CastContext gère à votre place les cycles de vie, les erreurs et les rappels, ce qui simplifie considérablement le développement d'une application Cast.

Introduction

  • La conception de l'expéditeur CAF étant influencée par la bibliothèque associée Cast, la migration de CCL vers l'expéditeur CAF implique principalement des mappages un à un de classes et de leurs méthodes.
  • L'émetteur CAF est toujours distribué dans le cadre des services Google Play à l'aide d'Android SDK Manager.
  • Les nouveaux packages (com.google.android.gms.cast.framework.*) ajoutés à CAF Sender, avec des fonctionnalités semblables à CCL, assument la responsabilité du respect de la checklist de conception de Google Cast.
  • CAF Sender fournit des widgets conformes aux exigences de Cast pour l'expérience utilisateur. Ces widgets sont semblables à ceux fournis par CCL.
  • CAF Sender fournit des rappels asynchrones semblables à CCL pour suivre les états et obtenir des données. Contrairement à CCL, l'expéditeur CAF ne fournit aucune mise en œuvre no-op des différentes méthodes d'interface.

Dans les sections suivantes, nous nous concentrerons principalement sur les applications vidéo axées sur VideoCastManager de CCL. Toutefois, dans de nombreux cas, les mêmes concepts s'appliquent également à DataCastManager.

Dépendances

CCL et CAF ont les mêmes dépendances sur la bibliothèque de support AppCompat, la bibliothèque de support MediaRouter v7 et les services Google Play. La différence réside toutefois dans le fait que CAF dépend du nouveau framework Cast disponible dans les services Google Play 9.2.0 ou version ultérieure.

Dans votre fichier build.gradle, supprimez les dépendances sur com.google.android.gms:play-services-cast et com.google.android.libraries.cast.companionlibrary:ccl, puis ajoutez le nouveau framework 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'
}

Vous pouvez également supprimer les métadonnées du service Google Play:

<meta‐data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>

Tous les services, activités et ressources faisant partie de CAF sont automatiquement fusionnés avec le fichier manifeste et les ressources de votre application.

La version minimale du SDK Android compatible avec CAF est la version 9 (Gingerbread) ; la version minimale du SDK Android de CCL est 10.

CCL fournit une méthode pratique, BaseCastManager.checkGooglePlayServices(activity), pour vérifier qu'une version compatible des services Google Play est disponible sur l'appareil. CAF ne le fournit pas dans le cadre du SDK Cast. Suivez la procédure Assurez-vous que les appareils disposent du fichier APK des services Google Play pour vous assurer que l'APK des services Google Play approprié est installé sur l'appareil de l'utilisateur, car les mises à jour risquent de ne pas être accessibles à tous les utilisateurs immédiatement.

Vous devez toujours utiliser une variante de Theme.AppCompat pour le thème de l'application.

Initialisation

Pour CCL, il était nécessaire d'appeler VideoCastManager.initialize() dans la méthode onCreate() de l'instance Applications. Cette logique doit être supprimée du code de la classe d'application.

Dans CAF, une étape d'initialisation explicite est également requise pour le framework Cast. Cela implique d'initialiser le singleton CastContext, en utilisant un OptionsProvider approprié pour spécifier l'ID d'application du récepteur et les autres options globales. CastContext joue un rôle semblable au VideoCastManager de CCL en fournissant un singleton avec lequel les clients interagissent. Le OptionsProvider est semblable au CastConfiguration de CCL pour vous permettre de configurer les fonctionnalités du framework Cast.

Si votre CCL CastConfiguration.Builder actuel se présente comme suit:

VideoCastManager.initialize(
   getApplicationContext(),
   new CastConfiguration.Builder(context.getString(R.string.app_id))
       .enableWifiReconnection()
       .enableAutoReconnect()
       .build());

Dans CAF, la valeur CastOptionsProvider suivante utilisant CastOptions.Builder serait similaire:

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;
    }
}

Consultez notre exemple d'application pour une mise en œuvre complète d'OptionsProvider.

Déclarez OptionsProvider dans l'élément "application" du fichier 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>

Initialisez de manière différée CastContext dans la méthode onCreate de chaque Activity (et non dans l'instance Application):

private CastContext mCastContext;

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

    mCastContext = CastContext.getSharedInstance(this);
}

Pour accéder au singleton CastContext, utilisez:

mCastContext = CastContext.getSharedInstance(this);

Détection d'appareils

Les valeurs VideoCastManager incrementUiCounter et decrementUiCounter du CCL doivent être supprimées des méthodes onResume et onPause de votre Activities.

Dans CAF, le processus de découverte est lancé et arrêté automatiquement par le framework lorsque l'application est exécutée au premier plan et passe en arrière-plan, respectivement.

Icône et boîte de dialogue Cast

Comme pour CCL, ces composants sont fournis par la bibliothèque d'assistance MediaRouter v7.

L'icône Cast est toujours implémentée par MediaRouteButton et peut être ajoutée à votre activité (à l'aide de ActionBar ou Toolbar) en tant qu'élément de menu dans votre menu.

La déclaration de MediaRouteActionProvider dans le menu xml est identique à celle avec 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"/>

Comme pour CCL, remplacez la méthode onCreateOptionMenu() de chaque activité, mais au lieu d'utiliser CastManager.addMediaRouterButton, utilisez CastButtonFactory de CAF pour relier MediaRouteButton au framework Cast:

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;
}

Contrôle des appareils

Comme pour CCL, le contrôle des appareils est largement géré par le framework dans la CAF. L'application émetteur n'a pas besoin de gérer (et ne doit pas essayer d'être) de se connecter à l'appareil et de lancer l'application réceptrice à l'aide de GoogleApiClient.

L'interaction entre l'expéditeur et le destinataire est désormais représentée par une "session". La classe SessionManager gère le cycle de vie de la session, et démarre et arrête automatiquement les sessions en réponse aux gestes de l'utilisateur: une session est démarrée lorsque l'utilisateur sélectionne un appareil Cast dans la boîte de dialogue Cast et se termine lorsque l'utilisateur appuie sur le bouton "Arrêter la diffusion" dans la boîte de dialogue Cast ou lorsque l'application de l'expéditeur elle-même s'arrête.

Dans CCL, vous devez étendre la classe VideoCastConsumerImpl pour suivre l'état de la session Cast:

private final VideoCastConsumer mCastConsumer = new VideoCastConsumerImpl() {
  public void onApplicationConnected(ApplicationMetadata appMetadata, 
                                     String sessionId,
                                     boolean wasLaunched) {}
  public void onDisconnectionReason(int reason) {}
  public void onDisconnected() {}
}

Dans CAF, l'application expéditeur peut être informée des événements de cycle de vie de session en enregistrant un SessionManagerListener auprès de SessionManager. Les rappels SessionManagerListener définissent des méthodes de rappel pour tous les événements de cycle de vie de session.

Les méthodes SessionManagerListener suivantes sont mappées à partir de l'interface VideoCastConsumer de CCL:

  • VideoCastConsumer.onApplicationConnected -> SessionManagerListener.onSessionStarted
  • VideoCastConsumer.onDisconnected -> SessionManagerListener.onSessionEnded

Déclarez une classe qui implémente l'interface SessionManagerListener, puis déplacez la logique VideoCastConsumerImpl vers les méthodes correspondantes:

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 classe CastSession représente une session avec un appareil Cast. La classe dispose de méthodes permettant de contrôler le volume de l'appareil et de désactiver les états, ce que fait CCL dans BaseCastManager.

Au lieu d'utiliser le CCL VideoCastManager pour ajouter un consommateur:

VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);

Enregistrez maintenant votre SessionManagerListener:

mCastSessionManager = 
    CastContext.getSharedInstance(this).getSessionManager();
mCastSessionManagerListener = new CastSessionManagerListener();
mCastSessionManager.addSessionManagerListener(mCastSessionManagerListener,
                  CastSession.class);

Pour arrêter d'écouter des événements dans CCL:

VideoCastManager.getInstance().removeVideoCastConsumer(mCastConsumer);

Utilisez maintenant SessionManager pour arrêter l'écoute des événements de session:

mCastSessionManager.removeSessionManagerListener(mCastSessionManagerListener,
                    CastSession.class);

Pour se déconnecter explicitement de l'appareil Cast, CCL a utilisé les éléments suivants:

VideoCastManager.disconnectDevice(boolean stopAppOnExit, 
            boolean clearPersistedConnectionData,
            boolean setDefaultRoute)

Pour CAF, utilisez SessionManager:

CastContext.getSharedInstance(this).getSessionManager()
                                   .endCurrentSession(true);

Pour déterminer si l'expéditeur est connecté au destinataire, CCL fournit VideoCastManager.getInstance().isConnected(), mais dans CAF, utilisez SessionManager :

public boolean isConnected() {
    CastSession castSession = CastContext.getSharedInstance(mAppContext)
                                  .getSessionManager()
                                  .getCurrentCastSession();
    return (castSession != null && castSession.isConnected());
}

Dans CAF, les notifications de changement d'état de volume/désactivation du son sont toujours envoyées via des méthodes de rappel dans Cast.Listener. Ces écouteurs sont enregistrés avec CastSession. Toutes les autres notifications d'état de l'appareil sont transmises via des rappels CastStateListener. Ces écouteurs sont enregistrés avec CastSession. Veillez à toujours annuler l'enregistrement des écouteurs lorsque les fragments, les activités ou les applications associés sont mis en arrière-plan.

Logique de reconnexion

CAF tente de rétablir les connexions réseau perdues en raison de la perte temporaire du signal Wi-Fi ou d'autres erreurs réseau. Cette opération est maintenant effectuée au niveau de la session. Une session peut passer à l'état "suspendue" lorsque la connexion est perdue, puis repasser à l'état "connectée" une fois la connectivité rétablie. Dans le cadre de ce processus, le framework se charge de se reconnecter à l'application réceptrice et de reconnecter les canaux Cast.

CAF fournit son propre service de reconnexion. Vous pouvez donc supprimer la CCL ReconnectionService de votre fichier manifeste:

<service android:name="com.google.android.libraries.cast.companionlibrary.cast.reconnection.ReconnectionService"/>

Vous n'avez pas non plus besoin des autorisations suivantes dans votre fichier manifeste pour la logique de reconnexion:

<uses‐permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses‐permission android:name="android.permission.ACCESS_WIFI_STATE"/>

Le service de reconnexion CAF est activé par défaut, mais peut être désactivé à l'aide de CastOptions.

De plus, CAF ajoute également la reprise automatique de la session, qui est activée par défaut (et peut être désactivée via CastOptions). Si l'application d'expéditeur est envoyée en arrière-plan ou est arrêtée (en balayant l'application ou en raison d'un plantage) lorsqu'une session Cast est en cours, le framework tente de reprendre cette session lorsque l'application de l'expéditeur revient au premier plan ou est redémarrée. Cette opération est gérée automatiquement par SessionManager, qui enverra les appels enregistrés aux appels appropriés.

Enregistrement de critères personnalisés

CCL propose deux méthodes pour créer un canal de message personnalisé vers le destinataire:

  • CastConfiguration vous permet de spécifier plusieurs espaces de noms. CCL crée ensuite le canal à votre place.
  • DataCastManager est semblable à VideoCastManager, mais se concentre sur les cas d'utilisation non multimédias.

Ces méthodes ne permettent pas de créer un critère personnalisé. Vous devez suivre la procédure Ajouter un critère personnalisé pour votre application émettrice.

Comme CCL, pour les applications multimédias, il n'est pas nécessaire d'enregistrer explicitement le canal de contrôle multimédia.

Commande multimédia

Dans CAF, la classe RemoteMediaClient est équivalente aux méthodes multimédias VideoCastManager. La méthode RemoteMediaClient.Listener équivaut aux méthodes VideoCastConsumer. Plus spécifiquement, les méthodes onRemoteMediaPlayerMetadataUpdated et onRemoteMediaPlayerStatusUpdated de VideoCastConsumer correspondent respectivement aux méthodes onMetadataUpdated et onStatusUpdated de RemoteMediaClient.Listener:

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() {
    }
}

Il n'est pas nécessaire d'initialiser ou d'enregistrer explicitement l'objet RemoteMediaClient. Le framework instancie automatiquement l'objet et enregistre le canal multimédia sous-jacent au moment de la session si l'application réceptrice connectée est compatible avec l'espace de noms multimédia.

RemoteMediaClient est accessible en tant que méthode getRemoteMediaClient de l'objet CastSession.

CastSession castSession = CastContext.getSharedInstance(mAppContext)
                                     .getSessionManager()
                                     .getCurrentCastSession();
mRemoteMediaClient = castSession.getRemoteMediaClient();
mRemoteMediaClientListener = new CastMediaClientListener();

Au lieu des CCL:

VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);

Maintenant, utilisez CAF:

mRemoteMediaClient.addListener(mRemoteMediaClientListener);

Vous pouvez enregistrer un nombre illimité d'écouteurs avec RemoteMediaClient, ce qui permet à plusieurs composants expéditeurs de partager la même instance de RemoteMediaClient associée à la session.

La méthode VideoCastManager de CCL fournit des méthodes pour gérer la lecture de contenus multimédias:

VideoCastManager manager = VideoCastManager.getInstance();
if (manager.isRemoteMediaLoaded()) {
    manager.pause();
    mCurrentPosition = (int) manager.getCurrentMediaPosition();
}

Celles-ci sont désormais implémentées par RemoteMediaClient dans CAF:

if (mRemoteMediaClient.hasMediaSession()) {
    mRemoteMediaClient.pause();
    mCurrentPosition = 
        (int)mRemoteMediaClient.getApproximateStreamPosition();
}

Dans CAF, toutes les requêtes média émises sur le RemoteMediaClient renvoient un RemoteMediaClient.MediaChannelResult via un rappel PendingResult qui peut être utilisé pour suivre la progression et le résultat final de la requête.

CCL et CAF utilisent tous deux les classes MediaInfo et MediaMetadata pour représenter les éléments multimédias et pour charger les médias.

Pour charger des contenus multimédias dans CCL, VideoCastManager est utilisé:

VideoCastManager.getInstance().loadMedia(media, autoPlay, mCurrentPosition, customData);

Dans CAF, RemoteMediaClient permet de charger le média:

mRemoteMediaClient.load(media, autoPlay, mCurrentPosition, customData);

Pour obtenir les informations Media et l'état d'une session multimédia actuelle sur le destinataire, CCL utilise le VideoCastManager :

MediaInfo mediaInfo = VideoCastManager.getInstance()
                                      .getRemoteMediaInformation();
int status = VideoCastManager.getInstance().getPlaybackStatus();
int idleReason = VideoCastManager.getInstance().getIdleReason();

Dans CAF, utilisez RemoteMediaClient pour obtenir les mêmes informations:

MediaInfo mediaInfo = mRemoteMediaClient.getMediaInfo();
int status = mRemoteMediaClient.getPlayerState();
int idleReason = mRemoteMediaClient.getIdleReason();

Message d'annonce en superposition

Comme CCL, CAF fournit une vue personnalisée IntroductoryOverlay pour mettre en surbrillance l'icône Cast lorsqu'elle est présentée aux utilisateurs pour la première fois.

Au lieu d'utiliser la méthode VideoCastConsumer onCastAvailabilityChanged de CCL pour savoir quand afficher la superposition, déclarez un CastStateListener pour déterminer quand l'icône Cast devient visible une fois que les appareils Cast ont été détectés sur le réseau local par 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);
    ...
}

Effectuez le suivi de l'instance 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;
}

Vérifiez si MediaRouteButton est visible pour que la superposition d'introduction puisse être affichée:

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();
            }
        });
    }
}

Consultez notre exemple d'application pour obtenir le code de travail complet permettant d'afficher la superposition d'introduction.

Pour personnaliser le style de la superposition d'introduction, suivez la procédure Personnaliser la superposition d'introduction.

Mini-télécommande

Au lieu de MiniController de CCL, utilisez MiniControllerFragment de CAF dans votre fichier de mise en page d'application des activités dans lesquelles vous souhaitez afficher le mini-contrôleur:

<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 n'est pas compatible avec la configuration manuelle prise en charge par le CCL MiniController et n'est pas compatible avec la fonctionnalité Autoplay.

Pour personnaliser le style et les boutons de la mini-télécommande, suivez la procédure Personnaliser la mini-télécommande.

Notifications et écran de verrouillage

Comme pour le CCL VideoCastNotificationService, CAF fournit un MediaNotificationService permettant de gérer l'affichage des notifications multimédias lors de la diffusion.

Vous devez supprimer les éléments suivants de votre fichier manifeste:

  • VideoIntentReceiver
  • VideoCastNotificationService

CCL permet de fournir un service de notification personnalisé avec CastConfiguration.Builder, ce qui n'est pas compatible avec CAF.

Examinez l'initialisation CastManager suivante à l'aide de 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());

Pour la configuration équivalente dans CAF, le SDK fournit un NotificationsOptions.Builder pour vous aider à créer des commandes multimédias pour l'écran de notification et de verrouillage dans l'application expéditeur. Les commandes de notification et d'écran de verrouillage peuvent être activées avec CastOptions lors de l'initialisation de 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();
}

Les notifications et les commandes de verrouillage d'écran sont toujours activées dans CAF. Notez également que les boutons de lecture/pause et d'arrêt de la diffusion sont fournis par défaut. CAF suit automatiquement la visibilité des activités pour décider quand afficher la notification multimédia, sauf pour Gingerbread. (Pour Gingerbread, consultez la remarque précédente sur l'utilisation de registerLifecycleCallbacksBeforeIceCreamSandwich(). Les appels VideoCastManager incrementUiCounter et decrementUiCounter de CCL doivent être supprimés.)

Pour personnaliser les boutons affichés dans les notifications, suivez la procédure Ajouter des commandes multimédias à l'écran de notification et de verrouillage.

Télécommande agrandie

CCL fournit VideoCastControllerActivity et VideoCastControllerFragment pour afficher une télécommande agrandie lors de la diffusion de contenus multimédias.

Vous pouvez supprimer la déclaration VideoCastControllerActivity dans le fichier manifeste.

Dans CAF, vous devez étendre la classe ExpandedControllerActivity et ajouter l'icône Cast.

Pour personnaliser les styles et les boutons affichés dans le contrôleur développé, suivez la procédure Personnaliser le contrôleur développé.

Priorité audio

Comme pour le CCL, la sélection audio est gérée automatiquement.

Contrôle du volume

Pour Gingerbread, dispatchKeyEvent est requis, comme CCL. Dans ICS et dans les versions ultérieures, les commandes de volume CCL et CAF sont gérées automatiquement.

CAF permet de contrôler le volume de diffusion via le bouton de volume dur du téléphone dans les activités de votre application et affiche également une barre de volume visuel lorsque vous castez sur des versions compatibles. CAF gère également les changements de volume via le volume dur, même si votre application n'est pas devant, est verrouillée ou même si l'écran est éteint.

Sous-titres

Sur Android KitKat et versions ultérieures, vous pouvez personnaliser les sous-titres via les paramètres des sous-titres, accessibles sous Paramètres > Accessibilité. Les versions antérieures d'Android ne disposent toutefois pas de cette fonctionnalité. CCL gère cela en fournissant des paramètres personnalisés pour les versions antérieures et en déléguant les paramètres système sur KitKat et les versions ultérieures.

CAF ne fournit pas de paramètres personnalisés permettant de modifier les préférences concernant les sous-titres. Vous devez supprimer les références CaptionsPreferenceActivity dans votre fichier manifeste et dans vos préférences XML.

La méthode TracksChooserDialog de CCL n'est plus nécessaire, car la modification des pistes de sous-titres est gérée par l'interface utilisateur étendue de la télécommande.

L'API de sous-titrage de CAF est semblable à celle de la version 2.

Journalisation des données de débogage

CAF ne fournit pas de paramètres de journalisation de débogage.

Divers :

Les fonctionnalités CCL suivantes ne sont pas compatibles avec CAF:

  • Obtenir une autorisation avant la lecture en fournissant un MediaAuthService
  • Messages configurables de l'interface utilisateur

Applications exemples

Consultez le Diff pour migrer notre exemple d'application Universal Music Player for Android (CAMP) du CCL vers le CAF.

Nous proposons également des tutoriels d'atelier de programmation et des exemples d'applications utilisant CAF.