Esegui la migrazione dell'app CCL Sender a Cast Application Framework (CAF)

La procedura che segue ti consente di convertire l'app mittente Android da Trasmetti SDK v2 con CCL a CAF. Tutte le funzionalità di CCL sono state implementato in CAF. Pertanto, una volta eseguita la migrazione, non dovrai più utilizzare CCL.

L'SDK Cast CAF Sender utilizza CastContext per gestire GoogleAPIClient per tuo conto. CastContext gestisce per te cicli di vita, errori e callback, il che semplifica lo sviluppo di un'app Google Cast.

Introduzione

  • Poiché il design del mittente CAF è stato influenzato dalla libreria di Google Cast companion, il la migrazione da CCL a CAF Sender prevede principalmente mappature one-to-one classi e i relativi metodi.
  • Il mittente CAF è ancora distribuito come parte di Google Play Services con Android SDK Manager.
  • I nuovi pacchetti (com.google.android.gms.cast.framework.*) sono stati aggiunto a CAF Sender, con funzionalità simili a CCL, la responsabilità di rispettare Elenco di controllo per la progettazione di Google Cast.
  • CAF Sender fornisce widget conformi ai requisiti di Cast UX. questi widget sono simili a quelli forniti da CCL.
  • Il mittente CAF fornisce callback asincroni simili a CCL, per tenere traccia stati e ottenere dati. A differenza di CCL, il mittente CAF non fornisce alcuna implementazioni dei vari metodi dell'interfaccia.

Nelle sezioni seguenti ci concentreremo principalmente sugli basate su VideoCastManager di CCL, ma in molti casi la stessa si applicano anche a DataCastManager.

Dipendenze

CCL e CAF hanno le stesse dipendenze nella libreria di supporto AppCompat, La libreria di supporto MediaRouter v7 e Google Play Services. Tuttavia, la differenza è che il CAF dipende dal nuovo framework Cast disponibile su Google Play. 9.2.0 o versioni successive.

Nel file build.gradle, rimuovi le dipendenze com.google.android.gms:play-services-cast e com.google.android.libraries.cast.companionlibrary:ccl, quindi aggiungi il nuovo 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'
}

Puoi anche rimuovere i metadati di Google Play Services:

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

Tutti i servizi, le attività e le risorse che fanno parte del CAF vengono automaticamente unito al manifest e alle risorse dell'app.

La versione minima dell'SDK Android supportata da CAF è 9 (Gingerbread); La versione minima dell'SDK Android di CCL è 10.

CCL offre un metodo pratico, BaseCastManager.checkGooglePlayServices(activity), per verificare che sia compatibile di Google Play Services sia disponibile sul dispositivo. CAF non fornisce questa funzionalità nell'ambito dell'SDK Cast. Segui la procedura. Assicurati che i dispositivi dispongano dell'APK di Google Play Services per assicurarti che sul sito di un utente sia installato l'APK di Google Play Services corretto dispositivo poiché gli aggiornamenti potrebbero non raggiungere immediatamente tutti gli utenti.

Devi comunque utilizzare una variante di Theme.AppCompat per il tema.

Inizializzazione

Per CCL, doveva essere chiamato VideoCastManager.initialize() nel Metodo onCreate() dell'istanza Applications. Questa logica dovrebbe essere rimosso dal codice della classe dell'applicazione.

Nel CAF è richiesto anche un passaggio di inizializzazione esplicito per il modello di machine learning. Ciò comporta l'inizializzazione del singleton CastContext, utilizzando un OptionsProvider appropriato per specificare l'ID applicazione destinatario ed eventuali altre opzioni globali. Il CastContext svolge un ruolo simile a quello delle VideoCastManager fornendo un singleton con cui interagiscono i clienti. OptionsProvider è simile a CastConfiguration di CCL per consentirti per configurare le funzionalità del framework di trasmissione.

Se l'attuale CCL CastConfiguration.Builder ha il seguente aspetto:

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

Poi in CAF il seguente CastOptionsProvider utilizzando CastOptions.Builder sarebbe simile:

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

Dai un'occhiata alla nostra app di esempio per un'implementazione completa di OptionsProvider.

Dichiarare il valore di OptionsProvider all'interno dell'"application" dell' File 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>

Inizializza lentamente CastContext in ogni metodo onCreate di Activity (e non l'istanza Application):

private CastContext mCastContext;

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

    mCastContext = CastContext.getSharedInstance(this);
}

Per accedere al singleton CastContext, utilizza:

mCastContext = CastContext.getSharedInstance(this);

Rilevamento dispositivi

I valori VideoCastManager incrementUiCounter e decrementUiCounter di CCL devono verrà rimossa dai metodi onResume e onPause del tuo Activities.

In CAF, il processo di rilevamento viene avviato e arrestato automaticamente dal quando l'app passa in primo piano e passa in background, rispettivamente.

Pulsante Trasmetti e finestra di dialogo Trasmetti

Come per CCL, questi componenti sono forniti dal supporto MediaRouter v7 libreria.

Il pulsante Trasmetti è ancora implementato da MediaRouteButton e può essere aggiunto alla tua attività (utilizzando ActionBar o Toolbar), come voce di menu nel menu.

La dichiarazione di MediaRouteActionProvider nel file XML del menu è la stessa di 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"/>

Analogamente a CCL, sostituisci il metodo onCreateOptionMenu() di ogni attività, ma invece di utilizzare CastManager.addMediaRouterButton, usa CastButtonFA della CAF per collegare MediaRouteButton al 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;
}

Controllo del dispositivo

Analogamente a CCL, in CAF, il controllo dei dispositivi è gestito in gran parte dal framework. L'applicazione del mittente non ha bisogno di gestirla (e non dovrebbe provare a gestirla) il collegamento al dispositivo e l'avvio dell'applicazione di ricezione utilizzando GoogleApiClient.

L'interazione tra mittente e destinatario è ora rappresentata come "sessione". La La classe SessionManager gestisce il ciclo di vita della sessione e si avvia automaticamente e interrompe le sessioni in risposta ai gesti dell'utente: una sessione viene avviata quando l'utente seleziona un dispositivo di trasmissione nella finestra di dialogo Trasmetti e termina quando tocca l'utente seleziona l'opzione "Interrompi trasmissione" nella finestra di dialogo Trasmetti o quando è l'app del mittente viene terminato.

In CCL devi estendere la classe VideoCastConsumerImpl per monitorare la trasmissione stato sessione:

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

In CAF, l'applicazione del mittente può ricevere notifiche sugli eventi del ciclo di vita delle sessioni tramite registrazione di un SessionManagerListener con SessionManager. La I callback SessionManagerListener definiscono i metodi di callback per tutte le sessioni degli eventi del ciclo di vita.

I seguenti metodi SessionManagerListener sono mappati dalla CCL Interfaccia VideoCastConsumer:

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

Dichiara una classe che implementa l'interfaccia SessionManagerListener e sposta la logica VideoCastConsumerImpl ai metodi di corrispondenza:

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 rappresenta una sessione con un dispositivo di trasmissione. Il corso ha per controllare il volume del dispositivo e gli stati di disattivazione dell'audio, come avviene da CCL BaseCastManager.

Anziché utilizzare l'opzione CCL VideoCastManager per aggiungere un consumatore:

VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);

Ora registra il tuo SessionManagerListener:

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

Per interrompere l'ascolto degli eventi in CCL:

VideoCastManager.getInstance().removeVideoCastConsumer(mCastConsumer);

Ora utilizza SessionManager per interrompere l'ascolto degli eventi della sessione:

mCastSessionManager.removeSessionManagerListener(mCastSessionManagerListener,
                    CastSession.class);

Per disconnettersi esplicitamente dal dispositivo di trasmissione, CCL ha utilizzato:

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

Per CAF, utilizza SessionManager:

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

Per determinare se il mittente è connesso al destinatario, CCL fornisce VideoCastManager.getInstance().isConnected(), ma in CAF utilizza il valore SessionManager:

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

Nel CAF, le notifiche relative al cambio di stato/volume/audio vengono comunque inviate tramite callback in Cast.Listener; con cui questi ascoltatori sono registrati CastSession. Tutte le altre notifiche sullo stato del dispositivo vengono inviate tramite callback CastStateListener; questi listener sono registrati con CastSession. Assicurati di annullare comunque la registrazione dei listener quando viene associato in background frammenti, attività o app.

Logica di riconnessione

Il CAF tenta di ristabilire le connessioni di rete perse a causa a causa di una perdita temporanea del segnale Wi-Fi o altri errori di rete. A questo punto puoi livello di sessione; una sessione può inserire uno stato "sospesa" quando la connessione persa e tornerà allo stato "connesso" quando la connettività è ripristinato. Il framework si occupa di riconnettersi all'applicazione ricevente e ricollegare eventuali canali di trasmissione come parte di questa procedura.

CAF fornisce il proprio servizio di riconnessione, quindi puoi rimuovere la CCL ReconnectionService dal file manifest:

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

Inoltre, nel manifest non sono necessarie le seguenti autorizzazioni per l'attributo logica di riconnessione:

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

Il servizio di riconnessione CAF è abilitato per impostazione predefinita, ma può essere disattivato utilizzando CastOptions.

Inoltre, CAF aggiunge anche la ripresa automatica delle sessioni, che viene attivata predefinita (e può essere disattivata tramite CastOptions). Se l'applicazione del mittente è inviati in background o terminati (scorrimento verso l'esterno o a causa di un incidente) mentre è in corso una sessione di trasmissione, il framework tenterà di riprendere sessione quando l'applicazione del mittente torna in primo piano o viene riavviata; questa operazione viene gestita automaticamente dal SessionManager, che emetterà il i callback appropriati su qualsiasi istanza SessionManagerListener registrata.

Registrazione a canali personalizzati

CCL offre due modi per creare un canale di messaggi personalizzato per il destinatario:

  • CastConfiguration ti consente di specificare più spazi dei nomi e CCL e poi creare il canale per te.
  • DataCastManager è simile a VideoCastManager, ma è incentrato sui contenuti non multimediali e casi d'uso specifici.

Il CAF non supporta nessuno di questi metodi per creare un canale personalizzato: seguire la procedura Aggiungere un canale personalizzato per l'app del mittente.

Come per CCL, per le applicazioni multimediali non è necessario specificare registrare il canale di controllo multimediale.

Controllo dei contenuti multimediali

In CAF, la classe RemoteMediaClient equivale alla VideoCastManager i metodi multimediali. RemoteMediaClient.Listener equivale a VideoCastConsumer metodi. In particolare, onRemoteMediaPlayerMetadataUpdated e onRemoteMediaPlayerStatusUpdated di VideoCastConsumer vengono mappati al onMetadataUpdated e onStatusUpdated metodi rispettivamente di 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() {
    }
}

Non è necessario inizializzare o registrare esplicitamente RemoteMediaClient object; il framework creerà automaticamente l'istanza dell'oggetto e registrerà canale multimediale sottostante all'ora di inizio della sessione se l'applicazione ricevente viene a cui è connesso supporta lo spazio dei nomi multimediale.

È possibile accedere a RemoteMediaClient come metodo getRemoteMediaClient di l'oggetto CastSession.

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

Al posto delle CCL:

VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);

Ora utilizza CAF:

mRemoteMediaClient.addListener(mRemoteMediaClientListener);

È possibile registrare un numero qualsiasi di ascoltatori con RemoteMediaClient, che consente a più componenti mittente di condividere la singola istanza di RemoteMediaClient associato alla sessione.

VideoCastManager di CCL fornisce metodi per gestire la riproduzione di contenuti multimediali:

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

Questi vengono ora implementati da RemoteMediaClient in CAF:

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

In CAF, tutte le richieste di contenuti multimediali emesse il RemoteMediaClient restituiscono un RemoteMediaClient.MediaChannelResult tramite chiamata PendingResult che possono essere utilizzate per monitorare l'avanzamento e l'esito finale della richiesta.

Sia CCL che CAF utilizzano le classi MediaInfo e MediaMetadata per rappresentare elementi multimediali e per caricare contenuti multimediali.

Per caricare contenuti multimediali in CCL, viene utilizzato VideoCastManager:

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

In CAF, viene utilizzato RemoteMediaClient per caricare i contenuti multimediali:

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

Per ottenere le informazioni Media e lo stato di una sessione multimediale corrente sul ricevente, CCL utilizza VideoCastManager:

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

In CAF, utilizza RemoteMediaClient per ottenere le stesse informazioni:

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

Overlay introduttivo

Come per CCL, CAF fornisce una visualizzazione personalizzata IntroductoryOverlay per evidenziare sul pulsante Trasmetti quando viene mostrato per la prima volta agli utenti.

Anziché utilizzare il metodo VideoCastConsumer onCastAvailabilityChanged di CCL per sapere quando visualizzare l'overlay, dichiara un CastStateListener per determinare quando il pulsante Trasmetti diventa visibile dopo aver rilevato i dispositivi di trasmissione sulla rete locale da 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);
    ...
}

Tieni traccia dell'istanza 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;
}

Controlla se MediaRouteButton è visibile in modo che l'overlay introduttivo possono essere mostrati:

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

Dai un'occhiata al nostro app di esempio per il codice completo per la visualizzazione dell'overlay introduttivo.

Per personalizzare lo stile dell'overlay introduttivo, segui la procedura Personalizza l'overlay introduttivo.

Mini controller

Invece di MiniController di CCL, utilizza MiniControllerFragment del CAF in il file di layout dell'app delle attività in cui vuoi mostrare il file mini un controller:

<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" />

Il CAF non supporta la configurazione manuale supportata dall'MiniController di CCL e non supporta la funzionalità Autoplay.

Per personalizzare lo stile e i pulsanti del mini controller, segui le procedura Personalizza il mini controller.

Notifica e schermata di blocco

Analogamente a VideoCastNotificationService di CCL, CAF offre un MediaNotificationService per gestire la visualizzazione delle notifiche relative ai contenuti multimediali durante la trasmissione.

Devi rimuovere quanto segue dal file manifest:

  • VideoIntentReceiver
  • VideoCastNotificationService

CCL supporta la fornitura di un servizio di notifica personalizzato CastConfiguration.Builder; non supportato dal CAF.

Considera la seguente inizializzazione di 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());

Per la configurazione equivalente in CAF, l'SDK fornisce una NotificationsOptions.Builder per aiutarti a creare controlli multimediali per delle notifiche e della schermata di blocco nell'app del mittente. La notifica e il blocco i controlli dello schermo possono essere abilitati con il CastOptions durante l'inizializzazione del 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();
}

Le notifiche e i controlli della schermata di blocco sono sempre attivi in CAF. Inoltre, tieni presente che i pulsanti di riproduzione, pausa e interruzione trasmissione sono forniti per impostazione predefinita. CAF monitorerà automaticamente la visibilità delle attività per decidere quando visualizzare la notifica dei contenuti multimediali, ad eccezione di Gingerbread. Per Gingerbread, vedi la nota precedente sulla utilizzando registerLifecycleCallbacksBeforeIceCreamSandwich(); CCL VideoCastManager incrementUiCounter e decrementUiCounter chiamate deve essere rimosso.)

Per personalizzare i pulsanti visualizzati nelle notifiche, segui le procedura Aggiungi Controlli multimediali a Notifica e Schermata di blocco.

Controller espanso

CCL fornisce i VideoCastControllerActivity e VideoCastControllerFragment per visualizzare un controller espanso durante la trasmissione di contenuti multimediali.

Puoi rimuovere la dichiarazione VideoCastControllerActivity nel file manifest.

Nel CAF, devi estendere l'ExpandedControllerActivity e aggiungere il pulsante Trasmetti.

Per personalizzare gli stili e i pulsanti visualizzati nell'area espansa il controller, segui la procedura Personalizza il controller espanso.

Focus audio

Come per CCL, il focus audio viene gestito automaticamente.

Controllo del volume

Per Gingerbread, è richiesto dispatchKeyEvent come per CCL. In ICS e versioni successive sia per CCL che per CAF, il controllo del volume viene gestito automaticamente.

CAF consente di controllare il volume di trasmissione tramite il tasto del volume rigido telefono all'interno delle attività delle app e mostra anche una barra del volume visiva la trasmissione su versioni supportate. CAF gestisce anche la variazione di volume tramite volume elevato anche se l'app non è davanti, è bloccata o lo schermo è disattivata.

Sottotitoli codificati

In Android KitKat e versioni successive, i sottotitoli possono essere personalizzati tramite i sottotitoli codificati Impostazioni, disponibili in Impostazioni > Accessibilità. Nelle versioni precedenti di Android, ma non dispongono di questa funzionalità. CCL gestisce questo compito fornendo impostazioni per le versioni precedenti e delega alle impostazioni di sistema su KitKat e superiori.

CAF non fornisce impostazioni personalizzate per modificare le preferenze dei sottotitoli codificati. Tu deve rimuovere i riferimenti CaptionsPreferenceActivity nel file manifest e il tuo file XML delle preferenze.

Il parametro TracksChooserDialog di CCL non è più necessario dopo la modifica della finestra di dialogo chiusa le tracce dei sottotitoli codificati vengono gestite dall'interfaccia utente del controller espansa.

L'API Closed captioning in CAF è simile alla v2.

Logging del debug

Il CAF non fornisce impostazioni di logging di debug.

Varie

Le seguenti funzionalità di CCL non sono supportate nel CAF:

  • Ottenere l'autorizzazione prima della riproduzione fornendo un MediaAuthService
  • Messaggi configurabili dell'interfaccia utente

App di esempio

Dai un'occhiata al diff per eseguire la migrazione della nostra app di esempio Universal Music Player per Android (uamp) da CCL a CAF.

Abbiamo anche tutorial codelab e app di esempio che utilizzano CAF.