CCL-Sender-App zum Cast Application Framework (CAF) migrieren

Mit dem folgenden Verfahren können Sie Ihre Android-Sender-App von Streamen Sie SDK v2 mit CCL zu CAF. Alle Funktionen von CCL wurden die in CAF implementiert ist, sodass Sie CCL nach der Migration nicht mehr verwenden müssen.

Das Cast CAF Sender SDK verwendet CastContext, um den GoogleAPIClient in deinem Namen zu verwalten. CastContext verwaltet Lebenszyklen, Fehler und Rückrufe für Sie, was sehr vereinfacht die Entwicklung einer Cast-App.

Einführung

  • Da das CAF-Senderdesign von der Cast Companion-Bibliothek beeinflusst wurde, Die Migration von CCL zu CAF-Sender umfasst meistens 1:1-Zuordnungen von Klassen und ihren Methoden.
  • Der CAF-Sender wird weiterhin über die Google Play-Dienste bereitgestellt mit dem Android SDK Manager.
  • Neue Pakete (com.google.android.gms.cast.framework.*), die CAF-Sender mit ähnlichen Funktionen wie CCL für die Einhaltung der Checkliste für das Google Cast-Design.
  • Der CAF-Sender stellt Widgets bereit, die den Cast UX-Anforderungen entsprechen. Diese Widgets ähneln denen von CCL.
  • CAF-Sender bietet asynchrone Callbacks, die CCL ähneln, um das Tracking und Daten zu erhalten. Im Gegensatz zu CCL bietet der CAF-Sender keine No-Op Implementierungen der verschiedenen Methoden der Benutzeroberfläche.

In den folgenden Abschnitten geht es hauptsächlich um basierend auf dem VideoCastManager von CCL. In vielen Fällen gelten auch für DataCastManager.

Abhängigkeiten

CCL und CAF haben dieselben Abhängigkeiten von der AppCompat-Supportbibliothek, Supportbibliothek für MediaRouter v7 und Google Play-Dienste. Der Unterschied dass CAF vom neuen Cast-Framework abhängt, das bei Google Play Services 9.2.0 oder höher.

Entfernen Sie in der Datei build.gradle die Abhängigkeiten von com.google.android.gms:play-services-cast und com.google.android.libraries.cast.companionlibrary:ccl, Fügen Sie dann das neue Cast-Framework hinzu:

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

Sie können auch die Metadaten des Google Play-Dienstes entfernen:

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

Alle Dienste, Aktivitäten und Ressourcen, die Teil von CAF sind, werden automatisch mit dem Manifest und den Ressourcen Ihrer App zusammengeführt.

CAF muss mindestens die Android SDK-Version 9 haben (Gingerbread); Die Mindestversion des Android SDK von CCL ist 10.

CCL bietet eine einfache Methode, BaseCastManager.checkGooglePlayServices(activity), um zu prüfen, ob ein kompatibles Version der Google Play-Dienste auf dem Gerät verfügbar ist. CAF nicht als Teil des Cast SDK zur Verfügung stellen. Folge der Anleitung Sicherstellen, dass auf den Geräten das APK für die Google Play-Dienste installiert ist damit das richtige APK für die Google Play-Dienste auf der da die Updates möglicherweise nicht sofort allen Nutzern zur Verfügung stehen.

Sie müssen weiterhin eine Variante von Theme.AppCompat für die aus.

Initialisierung

Für CCL musste VideoCastManager.initialize() im onCreate()-Methode der Anwendungsinstanz. Diese Logik sollte wurde aus deinem Anwendungsklassencode entfernt.

In CAF ist außerdem für das Cast ein expliziter Initialisierungsschritt erforderlich. Framework. Dabei wird das Singleton-Element CastContext mit einem Entsprechender OptionsProvider zur Angabe der Anwendungs-ID des Empfängers und aller und weitere globale Optionen. CastContext spielt eine ähnliche Rolle wie CCLs. VideoCastManager durch Angabe eines Singletons, mit dem Kunden interagieren. Das OptionsProvider ähnelt dem CastConfiguration von CCL, damit du um die Funktionen des Cast-Frameworks zu konfigurieren.

Wenn dein aktueller CCL-CastConfiguration.Builder so aussieht:

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

Dann in CAF das folgende CastOptionsProvider mit dem CastOptions.Builder wäre ähnlich:

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

Sehen Sie sich unsere Beispiel-App an. finden Sie eine vollständige Implementierung von OptionsProvider.

OptionsProvider innerhalb der Anwendung deklarieren -Elements des AndroidManifest.xml-Datei:

<application>
...
    <meta-data
        android:name=
          "com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
        android:value="com.google.sample.cast.refplayer.CastOptionsProvider"    
    />
</application>

Initialisieren Sie CastContext verzögert in der onCreate-Methode jeder Activity (und nicht die Application-Instanz):

private CastContext mCastContext;

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

    mCastContext = CastContext.getSharedInstance(this);
}

So greifen Sie auf die Singleton-Anwendung CastContext zu:

mCastContext = CastContext.getSharedInstance(this);

Geräteerkennung

Die CCL-Werte VideoCastManager incrementUiCounter und decrementUiCounter sollten wird aus den onResume- und onPause-Methoden Ihrer Activities entfernt.

In CAF wird der Erkennungsprozess automatisch vom wenn die App in den Vordergrund wechselt und in den Hintergrund wechselt, .

Cast-Symbol und Streaming-Dialogfeld

Wie bei CCL werden diese Komponenten vom Support von MediaRouter v7 bereitgestellt. Bibliothek.

Das Cast-Symbol ist weiterhin vom MediaRouteButton implementiert und kann hinzugefügt werden für Ihre Aktivität (entweder mithilfe von ActionBar oder Toolbar) als Menüpunkt in Ihrem Menü.

Die Deklaration von MediaRouteActionProvider im XML-Menü des Menüs entspricht der mit 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"/>

Ähnlich wie bei CCL wird die Methode „onCreateOptionMenu()“ jeder Aktivität überschrieben, aber statt CastManager.addMediaRouterButton zu verwenden, verwenden Sie CastButtonFactory von CAF. um den MediaRouteButton mit dem Cast-Framework zu verbinden:

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

Gerätesteuerung

Ähnlich wie bei CCL wird in CAF die Gerätesteuerung weitgehend vom Framework übernommen. Die Absenderanwendung muss nicht (und sollte sie auch nicht) selbst verarbeiten. eine Verbindung zum Gerät herstellen und die Receiver-App über GoogleApiClient

Die Interaktion zwischen Sender und Empfänger wird jetzt als „Sitzung“ dargestellt. Die Die Klasse SessionManager steuert den Sitzungslebenszyklus und startet automatisch und stoppt Sitzungen als Reaktion auf Nutzergesten: Eine Sitzung wird gestartet, wenn die Der Nutzer wählt im Cast-Dialogfeld ein Übertragungsgerät aus und wird beendet, wenn der Nutzer auf „Streaming beenden“ im Streaming-Dialogfeld oder in der Sender-App selbst endet.

In CCL müssen Sie die VideoCastConsumerImpl-Klasse erweitern, um die Besetzung zu erfassen. Sitzungsstatus:

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 kann die Absenderanwendung über Sitzungslebenszyklus-Ereignisse benachrichtigt werden, und dabei wird ein SessionManagerListener mit der SessionManager registriert. Die SessionManagerListener-Callbacks definieren Callback-Methoden für alle Sitzungen Lebenszyklus-Ereignisse.

Die folgenden SessionManagerListener-Methoden werden von CCLs zugeordnet. VideoCastConsumer-Schnittstelle:

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

Deklarieren Sie eine Klasse, die die SessionManagerListener-Schnittstelle implementiert, und verschieben Sie VideoCastConsumerImpl-Logik den Abgleichmethoden hinzufügen:

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

Die Klasse CastSession steht für eine Sitzung mit einem Übertragungsgerät. Der Kurs hat Methoden zum Einstellen der Gerätelautstärke und zum Stummschalten, was die CCL in der BaseCastManager

Anstatt einen Nutzer mit dem CCL-VideoCastManager hinzuzufügen, gehen Sie so vor:

VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);

Registrieren Sie jetzt Ihr SessionManagerListener:

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

So beenden Sie das Warten auf Ereignisse in CCL:

VideoCastManager.getInstance().removeVideoCastConsumer(mCastConsumer);

Verwenden Sie jetzt SessionManager, um das Warten auf Sitzungsereignisse zu beenden:

mCastSessionManager.removeSessionManagerListener(mCastSessionManagerListener,
                    CastSession.class);

Um die Verbindung zum Übertragungsgerät explizit zu trennen, wird die CCL so verwendet:

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

Verwenden Sie für CAF SessionManager:

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

Um festzustellen, ob der Sender mit dem Empfänger verbunden ist, VideoCastManager.getInstance().isConnected(), aber in CAF die Methode SessionManager:

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

In CAF werden Benachrichtigungen über Statusänderungen der Lautstärke/Stummschaltung weiterhin per Rückruf zugestellt. Methoden in Cast.Listener; Diese Listener sind registriert mit CastSession. Alle verbleibenden Gerätestatusbenachrichtigungen werden über CastStateListener-Callbacks werden diese Listener im CastSession. Achten Sie darauf, die Registrierung von Listenern immer noch aufzuheben, wenn die zugehörigen Fragmente, Aktivitäten oder Apps werden in den Hintergrund verschoben.

Logik für die erneute Verbindung

CAF versucht, Netzwerkverbindungen wiederherzustellen, die aufgrund an vorübergehenden Verlust des WLAN-Signals oder andere Netzwerkfehler zu erkennen. Dies erfolgt jetzt im Sitzungsebene; kann eine Sitzung in eine "gesperrte" wenn die Verbindung und geht dann wieder in den Status, wenn die Verbindung wiederhergestellt. Das Framework sorgt dafür, dass die Verbindung zur Empfängeranwendung wiederhergestellt wird. und die Verbindung aller Übertragungskanäle neu herzustellen.

CAF bietet einen eigenen Dienst zur erneuten Verbindung, sodass Sie die CCL-ReconnectionService aus deinem Manifest:

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

Außerdem benötigen Sie die folgenden Berechtigungen in Ihrem Manifest für die Wiederverbindungslogik:

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

Der CAF-Dienst zur erneuten Verbindung ist standardmäßig aktiviert, kann jedoch mit der CastOptions

Außerdem fügt CAF die automatische Wiederaufnahme von Sitzungen hinzu, Standardeinstellung (kann über CastOptions deaktiviert werden). Wenn die Absenderanwendung in den Hintergrund gesendet oder beendet wird (durch Wegwischen oder durch einen Absturz) Während das Streaming läuft, versucht das Framework, die Übertragung fortzusetzen. Sitzung, wenn die Senderanwendung zum Vordergrund zurückkehrt oder neu gestartet wird; wird dies automatisch vom SessionManager durchgeführt, das den geeignete Callbacks für registrierte SessionManagerListener-Instanzen.

Registrierung eines benutzerdefinierten Channels

CCL bietet zwei Möglichkeiten, einen benutzerdefinierten Nachrichtenkanal an den Empfänger zu erstellen:

  • Mit CastConfiguration können Sie mehrere Namespaces angeben. und erstelle den Kanal für dich.
  • DataCastManager ähnelt VideoCastManager, konzentriert sich aber auf Nicht-Medien Anwendungsfälle.

Keine dieser Methoden zur Erstellung eines benutzerdefinierten Channels wird vom CAF unterstützt. Sie müssen Sie stattdessen wie im Benutzerdefinierten Channel hinzufügen für Ihre Absender-App.

Ähnlich wie bei CCL ist es auch bei Medienanwendungen nicht erforderlich, um den Medienkontrollkanal zu registrieren.

Mediensteuerung

In CAF entspricht die Klasse RemoteMediaClient der Klasse VideoCastManager Medienmethoden. RemoteMediaClient.Listener entspricht VideoCastConsumer-Methoden. Insbesondere onRemoteMediaPlayerMetadataUpdated und onRemoteMediaPlayerStatusUpdated von VideoCastConsumer sind den onMetadataUpdated und onStatusUpdated-Methoden von 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() {
    }
}

Die RemoteMediaClient muss nicht explizit initialisiert oder registriert werden Objekt; instanziiert das Framework automatisch das Objekt und registriert das zugrunde liegender Medienkanal beim Start der Sitzung, wenn die Empfängeranwendung verbunden ist, unterstützt den Medien-Namespace.

Auf RemoteMediaClient kann über die Methode getRemoteMediaClient von Das CastSession-Objekt

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

Anstelle von CCLs:

VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);

Verwenden Sie jetzt CAF:

mRemoteMediaClient.addListener(mRemoteMediaClientListener);

Mit RemoteMediaClient kann eine beliebige Anzahl von Listenern registriert werden. Dadurch können mehrere Absenderkomponenten RemoteMediaClient, die der Sitzung zugeordnet sind.

VideoCastManager von CCL bietet Methoden für die Medienwiedergabe:

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

Diese werden jetzt von RemoteMediaClient in CAF implementiert:

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

In CAF geben alle am RemoteMediaClient gesendeten Medienanfragen einen Fehler zurück: RemoteMediaClient.MediaChannelResult über einen PendingResult-Callback mit der der Fortschritt und das Endergebnis der Anfrage verfolgt werden kann.

Sowohl CCL als auch CAF verwenden die Klassen MediaInfo und MediaMetadata, um Medienelemente und zum Laden von Medien.

Zum Laden von Medien in CCL wird VideoCastManager verwendet:

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

In CAF wird RemoteMediaClient zum Laden der Medien verwendet:

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

Um die Informationen zu Media und den Status einer aktuellen Mediensitzung auf der -Empfänger verwendet, verwendet CCL den VideoCastManager:

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

Verwenden Sie in CAF RemoteMediaClient, um dieselben Informationen abzurufen:

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

Einleitendes Overlay

Ähnlich wie CCL bietet CAF eine benutzerdefinierte Ansicht IntroductoryOverlay, um auf das Cast-Symbol, wenn es dem Nutzer zum ersten Mal angezeigt wird.

Statt die VideoCastConsumer-onCastAvailabilityChanged-Methode von CCL zu verwenden um zu erfahren, wann das Overlay angezeigt werden soll, deklarieren Sie ein CastStateListener, wenn das Cast-Symbol sichtbar wird, sobald Übertragungsgeräte im lokales Netzwerk durch 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);
    ...
}

Behalten Sie den Überblick über die MediaRouteMenuItem-Instanz:

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

Prüfe, ob MediaRouteButton sichtbar ist, damit das Einleitungs-Overlay erscheint. angezeigt werden kann:

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

Werfen Sie einen Blick in unsere Beispiel-App den vollständigen funktionierenden Code zum Einblenden des einführenden Overlays.

Um den Stil des einführenden Overlays anzupassen, folgen Sie der Anleitung. Einführendes Overlay anpassen:

Mini-Controller

Verwenden Sie anstelle von MiniController der CCL-Datei den MiniControllerFragment des CAF in Ihrem App-Layoutdatei der Aktivitäten, in denen die Miniversion angezeigt werden soll 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" />

CAF unterstützt nicht die manuelle Konfiguration, die von CCLs MiniController unterstützt wird Außerdem wird die Funktion Autoplay nicht unterstützt.

Wenn Sie Stil und Tasten des Mini-Controllers anpassen möchten, folgen Sie der Prozedur Mini-Controller anpassen

Benachrichtigungen und Sperrbildschirm

Ähnlich wie VideoCastNotificationService der CCL bietet CAF ein MediaNotificationService, um die Anzeige von Medienbenachrichtigungen zu verwalten beim Streamen.

Entferne Folgendes aus deinem Manifest:

  • VideoIntentReceiver
  • VideoCastNotificationService

CCL unterstützt die Bereitstellung eines benutzerdefinierten Benachrichtigungsdienstes mit dem CastConfiguration.Builder; das vom CAF nicht unterstützt wird.

Sehen Sie sich die folgende CastManager-Initialisierung mit CCL an:

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

Für die entsprechende Konfiguration in CAF stellt das SDK eine NotificationsOptions.Builder, mit dem du Mediensteuerelemente für die Benachrichtigungs- und Sperrbildschirm in die Absender-App ein. Die Benachrichtigung und das Schloss Bildschirmsteuerelemente können bei der Initialisierung der Funktion mit dem CastOptions aktiviert werden. 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();
}

Benachrichtigungen und Steuerelemente für den Sperrbildschirm sind im CAF immer aktiviert. Beachten Sie außerdem, dass Standardmäßig sind die Schaltflächen für Wiedergabe/Pause und Stoppen des Streamings vorhanden. CAF verfolgt automatisch die Sichtbarkeit der Aktivitäten, um zu entscheiden, wann die Medienbenachrichtigung angezeigt werden soll, mit Ausnahme von Gingerbread. Weitere Informationen zu Gingerbread finden Sie im vorherigen Hinweis zu mit registerLifecycleCallbacksBeforeIceCreamSandwich(); CCL VideoCastManager incrementUiCounter- und decrementUiCounter-Aufrufe entfernt werden sollte.)

Um die Schaltflächen anzupassen, die in Benachrichtigungen angezeigt werden, folgen Sie den Prozedur Fügen Sie Mediensteuerelemente zu Benachrichtigungen und Sperrbildschirm hinzu.

Maximierter Controller

CCL stellt VideoCastControllerActivity und VideoCastControllerFragment bereit. um beim Streamen von Medien einen erweiterten Controller anzuzeigen.

Du kannst die VideoCastControllerActivity-Deklaration im Manifest entfernen.

Im CAF müssen Sie erweitern Sie die ExtendedControllerActivity und fügen Sie das Cast-Symbol hinzu.

Zum Anpassen der Stile und Schaltflächen, die im maximierten des Verantwortlichen, Erweiterten Controller anpassen:

Audiofokus

Wie bei der CCL wird der Audiofokus automatisch verwaltet.

Lautstärkeregelung

Für Gingerbread ist wie bei CCL dispatchKeyEvent erforderlich. In ICS und höher Die Lautstärkeregelung für sowohl CCL als auch CAF erfolgt automatisch.

Mit CAF können Sie die Streaminglautstärke über die entsprechende Taste auf der in Ihren App-Aktivitäten angezeigt. Außerdem wird ein Lautstärkebalken angezeigt, in unterstützten Versionen streamen. CAF verarbeitet auch Lautstärkeänderungen hohe Lautstärke einstellen, selbst wenn sich die App nicht im Vordergrund befindet, gesperrt ist oder deaktiviert.

Untertitel

Ab Android KitKat können Untertitel mithilfe von Untertiteln angepasst werden. Einstellungen unter „Einstellungen“ > Zugänglichkeits- Frühere Versionen von Android, verfügen jedoch nicht über diese Möglichkeit. Hierzu stellt CCL benutzerdefinierte Einstellungen für ältere Versionen und Delegieren an die Systemeinstellungen auf KitKat und höher.

CAF bietet keine benutzerdefinierten Einstellungen zum Ändern der Untertiteleinstellungen. Ich Sie sollten die CaptionsPreferenceActivity-Verweise in Ihrem Manifest entfernen. und die XML-Datei Ihrer Einstellungen.

TracksChooserDialog der CCL wird nicht mehr benötigt, da der geschlossene Wert geändert wird werden von der erweiterten Controller-Benutzeroberfläche verwaltet.

Die Closed Captioning API in CAF ähnelt v2.

Fehlerprotokollierung

CAF bietet keine Protokollierungseinstellungen für die Fehlerbehebung.

Verschiedenes

Die folgenden CCL-Funktionen werden in CAF nicht unterstützt:

  • Einholen der Autorisierung vor der Wiedergabe durch Angabe eines MediaAuthService
  • Konfigurierbare UI-Meldungen

Beispielapps

Sehen Sie sich die Unterschiede für die Migration unserer Beispiel-App Universal Music Player for Android (uamp) von CCL zu CAF an.

Außerdem bieten wir Codelab-Anleitungen und Beispiel-Apps, die CAF verwenden.