Für Google Cast optimierte Android-App

1. Übersicht

Google Cast-Logo

In diesem Codelab erfahren Sie, wie Sie eine vorhandene Android-Video-App so ändern, dass Inhalte auf einem für Google Cast optimierten Gerät gestreamt werden können.

Was ist Google Cast?

Mit Google Cast können Nutzer Inhalte von einem Mobilgerät auf einen Fernseher streamen. Nutzer können dann ihr Mobilgerät als Fernbedienung für die Medienwiedergabe auf dem Fernseher verwenden.

Mit dem Google Cast SDK können Sie Ihre App erweitern, um einen Fernseher oder ein Soundsystem zu steuern. Mit dem Cast SDK können Sie die erforderlichen UI-Komponenten anhand der Google Cast-Design-Checkliste hinzufügen.

Die Google Cast-Design-Checkliste soll die Nutzung von Google Cast auf allen unterstützten Plattformen einfach und vorhersehbar machen.

Ziele

Wenn Sie dieses Codelab abgeschlossen haben, haben Sie eine Android-Video-App, mit der Sie Videos auf ein Google Cast-kompatibles Gerät streamen können.

Lerninhalte

  • So fügen Sie einer Beispiel-Video-App das Google Cast SDK hinzu.
  • Hier erfahren Sie, wie Sie das Cast-Symbol zur Auswahl eines Google Cast-Geräts hinzufügen.
  • Verbindung zu einem Übertragungsgerät herstellen und einen Medienempfänger starten
  • So streamen Sie ein Video.
  • So fügen Sie Ihrer App einen Cast Mini-Controller hinzu.
  • Unterstützung von Medienbenachrichtigungen und Sperrbildschirmsteuerungen
  • So fügst du einen erweiterten Controller hinzu.
  • So fügst du ein Einführungs-Overlay hinzu.
  • So passen Sie Cast-Widgets an.
  • Cast Connect einbinden

Voraussetzungen

  • Das neueste Android SDK.
  • Android Studio Version 3.2 oder höher
  • Ein Mobilgerät mit Android 4.1 oder höher (Jelly Bean, API-Level 16)
  • Ein USB-Datenkabel, um Ihr Mobilgerät mit Ihrem Entwicklungscomputer zu verbinden.
  • Ein Google Cast-Gerät wie Chromecast oder Android TV mit Internetzugang
  • Einen Fernseher oder Monitor mit HDMI-Eingang
  • Für den Test der Cast Connect-Integration ist Chromecast mit Google TV erforderlich, für den Rest des Codelabs ist es optional. Wenn Sie keinen haben, können Sie den Schritt Unterstützung für Cast Connect hinzufügen am Ende dieser Anleitung überspringen.

Erfahrung

  • Sie benötigen Vorkenntnisse in Kotlin und Android-Entwicklung.
  • Außerdem solltest du schon einmal ferngesehen haben.

Wie möchten Sie diese Anleitung nutzen?

Nur durchlesen Durchlesen und die Übungen absolvieren

Wie würden Sie Ihre Erfahrung mit der Entwicklung von Android-Apps bewerten?

Anfänger Fortgeschrittene Erfahren

Wie würden Sie Ihre Erfahrung mit dem Fernsehen bewerten?

Anfänger Mittelstufe Fortgeschritten

2. Beispielcode abrufen

Sie können den gesamten Beispielcode auf Ihren Computer herunterladen…

und entpacken Sie die heruntergeladene ZIP-Datei.

3. Beispiel-App ausführen

Symbol eines Kompasses

Sehen wir uns zuerst an, wie die fertige Beispiel-App aussieht. Die App ist ein einfacher Videoplayer. Der Nutzer kann ein Video aus einer Liste auswählen und es dann lokal auf dem Gerät abspielen oder auf ein Google Cast-Gerät streamen.

Nachdem Sie den Code heruntergeladen haben, können Sie die fertige Beispiel-App in Android Studio öffnen und ausführen. Gehen Sie dazu so vor:

Wählen Sie auf dem Begrüßungsbildschirm Projekt importieren oder im Menü Datei > Neu > Projekt importieren… aus.

Wählen Sie im Ordner mit dem Beispielcode das Verzeichnis Ordnersymbolapp-done aus und klicken Sie auf „OK“.

Klicken Sie auf File (Datei) > Schaltfläche „Sync Project with Gradle“ in Android Studio Sync Project with Gradle Files (Projekt mit Gradle-Dateien synchronisieren).

Aktivieren Sie USB-Debugging auf Ihrem Android-Gerät. Unter Android 4.2 und höher ist der Bildschirm mit den Entwickleroptionen standardmäßig ausgeblendet. Wenn Sie sie sehen möchten, rufen Sie Einstellungen > Über das Telefon auf und tippen Sie siebenmal auf Build-Nummer. Kehren Sie zum vorherigen Bildschirm zurück, gehen Sie zu System > Erweitert und tippen Sie unten auf Entwickleroptionen. Tippen Sie dann auf USB-Debugging, um die Funktion zu aktivieren.

Schließen Sie Ihr Android-Gerät an und klicken Sie in Android Studio auf die Schaltfläche Die Schaltfläche „Ausführen“ in Android Studio, ein grünes Dreieck, das nach rechts zeigtRun (Ausführen). Nach einigen Sekunden sollte die Video-App Videos streamen angezeigt werden.

Klicke in der Video-App auf das Cast-Symbol und wähle dein Google Cast-Gerät aus.

Wähle ein Video aus und klicke auf die Wiedergabeschaltfläche.

Die Wiedergabe des Videos beginnt auf Ihrem Google Cast-Gerät.

Der erweiterte Controller wird angezeigt. Mit der Wiedergabe-/Pause-Schaltfläche kannst du die Wiedergabe steuern.

Kehren Sie zur Liste der Videos zurück.

Unten auf dem Bildschirm ist jetzt ein Mini-Controller zu sehen. Abbildung eines Android-Smartphones, auf dem die App „Videos streamen“ ausgeführt wird, mit dem Mini-Controller, der unten auf dem Bildschirm erscheint

Klicke auf die Pause-Schaltfläche auf der Minifernbedienung, um das Video auf dem Receiver anzuhalten. Klicke auf die Wiedergabeschaltfläche im Mini-Controller, um die Wiedergabe des Videos fortzusetzen.

Klicken Sie auf die Startbildschirmtaste Ihres Mobilgeräts. Wischen Sie nach unten zu den Benachrichtigungen. Jetzt sollte eine Benachrichtigung für die Übertragungssitzung angezeigt werden.

Sperren Sie Ihr Smartphone und entsperren Sie es dann. Sie sollten dann eine Benachrichtigung auf dem Sperrbildschirm sehen, mit der Sie die Medienwiedergabe steuern oder das Streaming beenden können.

Kehren Sie zur Video-App zurück und klicken Sie auf das Cast-Symbol, um das Streamen auf das Google Cast-Gerät zu beenden.

Häufig gestellte Fragen

4. Startprojekt vorbereiten

Abbildung eines Android-Smartphones mit der App „Videos streamen“

Wir müssen der von Ihnen heruntergeladenen Start-App Google Cast hinzufügen. Im Folgenden finden Sie einige Google Cast-Begriffe, die wir in diesem Codelab verwenden:

  • eine Absender-App auf einem Mobilgerät oder Laptop ausgeführt wird,
  • eine Empfänger-App auf dem Google Cast-Gerät ausgeführt wird.

Jetzt können Sie mit Android Studio auf dem Starterprojekt aufbauen:

  1. Wählen Sie das Verzeichnis Ordnersymbolapp-start aus dem heruntergeladenen Beispielcode aus. Wählen Sie dazu auf dem Begrüßungsbildschirm Import Project (Projekt importieren) oder die Menüoption File > New > Import Project... (Datei > Neu > Projekt importieren…) aus.
  2. Klicken Sie auf die Schaltfläche Schaltfläche „Projekt mit Gradle synchronisieren“ in Android Studio Projekt mit Gradle-Dateien synchronisieren.
  3. Klicken Sie auf die Schaltfläche Die Schaltfläche „Ausführen“ in Android Studio, ein grünes Dreieck, das nach rechts zeigtAusführen, um die App auszuführen und die Benutzeroberfläche zu erkunden.

App-Design

Die App ruft eine Liste mit Videos von einem Remote-Webserver ab und stellt eine Liste für den Nutzer zum Stöbern bereit. Nutzer können ein Video auswählen, um die Details zu sehen, oder es lokal auf dem Mobilgerät abspielen.

Die App besteht aus zwei Hauptaktivitäten: VideoBrowserActivity und LocalPlayerActivity. Damit die Google Cast-Funktionen eingebunden werden können, müssen die Aktivitäten entweder von AppCompatActivity oder von ihrem übergeordneten Element FragmentActivity abgeleitet werden. Diese Einschränkung besteht, da wir das MediaRouteButton, das in der MediaRouter-Supportbibliothek bereitgestellt ist, als MediaRouteActionProvider hinzufügen müssen. Dies funktioniert nur, wenn die Aktivität von den oben genannten Klassen übernommen wird. Die MediaRouter-Unterstützungsbibliothek hängt von der AppCompat-Unterstützungsbibliothek ab, die die erforderlichen Klassen bereitstellt.

VideoBrowserActivity

Diese Aktivität enthält eine Fragment (VideoBrowserFragment). Diese Liste wird von einer ArrayAdapter (VideoListAdapter) unterstützt. Die Liste der Videos und die zugehörigen Metadaten werden auf einem Remote-Server als JSON-Datei gehostet. Ein AsyncTaskLoader (VideoItemLoader) ruft dieses JSON ab und verarbeitet es, um eine Liste von MediaItem-Objekten zu erstellen.

Ein MediaItem-Objekt modelliert ein Video und die zugehörigen Metadaten, z. B. Titel, Beschreibung, URL für den Stream, URL für die unterstützenden Bilder und ggf. zugehörige Texttracks (für Untertitel). Das MediaItem-Objekt wird zwischen Aktivitäten übergeben. Daher gibt es Dienstmethoden, mit denen es in ein Bundle-Objekt umgewandelt werden kann und umgekehrt.MediaItem

Wenn der Lader die Liste der MediaItems erstellt, übergibt er diese Liste an den VideoListAdapter, der die MediaItems-Liste dann im VideoBrowserFragment anzeigt. Dem Nutzer wird eine Liste von Video-Thumbnails mit einer kurzen Beschreibung für jedes Video angezeigt. Wenn ein Element ausgewählt wird, wird die entsprechende MediaItem in eine Bundle konvertiert und an LocalPlayerActivity übergeben.

LocalPlayerActivity

Bei dieser Aktivität werden die Metadaten zu einem bestimmten Video angezeigt und der Nutzer kann das Video lokal auf dem Mobilgerät abspielen.

Die Aktivität enthält ein VideoView, einige Mediensteuerelemente und ein Textfeld, in dem die Beschreibung des ausgewählten Videos angezeigt wird. Der Player deckt den oberen Teil des Bildschirms ab und lässt darunter Platz für die detaillierte Videobeschreibung. Der Nutzer kann die lokale Wiedergabe von Videos wiedergeben/pausieren oder zu einer anderen Stelle springen.

Abhängigkeiten

Da wir AppCompatActivity verwenden, benötigen wir die AppCompat-Supportbibliothek. Für die Verwaltung der Videoliste und das asynchrone Abrufen der Bilder für die Liste verwenden wir die Volley-Bibliothek.

Häufig gestellte Fragen

5. Cast-Symbol hinzufügen

Abbildung des oberen Teils eines Android-Smartphones, auf dem die Cast Video App ausgeführt wird. Die Schaltfläche „Streamen“ wird oben rechts auf dem Display angezeigt.

In einer für Google Cast optimierten App wird die Cast-Schaltfläche in jeder Aktivität angezeigt. Wenn du auf die Schaltfläche „Streamen“ klickst, wird eine Liste der Übertragungsgeräte angezeigt, die du auswählen kannst. Wenn der Nutzer Inhalte lokal auf dem Sendergerät abspielte, wird durch die Auswahl eines Übertragungsgeräts die Wiedergabe auf diesem Gerät gestartet oder fortgesetzt. Während einer Übertragung kann der Nutzer jederzeit auf die Schaltfläche „Streamen“ klicken und die Übertragung Ihrer Anwendung auf das Cast-Gerät beenden. Der Nutzer muss die Möglichkeit haben, sich mit dem Übertragungsgerät zu verbinden bzw. die Verbindung zu trennen, während er Ihre App verwendet. Weitere Informationen hierzu finden Sie in der Checkliste für das Google Cast-Design.

Abhängigkeiten

Aktualisieren Sie die Datei „build.gradle“ der App, um die erforderlichen Bibliotheksabhängigkeiten anzugeben:

dependencies {
    implementation 'androidx.appcompat:appcompat:1.5.0'
    implementation 'androidx.mediarouter:mediarouter:1.3.1'
    implementation 'androidx.recyclerview:recyclerview:1.2.1'
    implementation 'com.google.android.gms:play-services-cast-framework:21.1.0'
    implementation 'com.android.volley:volley:1.2.1'
    implementation "androidx.core:core-ktx:1.8.0"
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}

Synchronisieren Sie das Projekt, um sicherzustellen, dass es ohne Fehler erstellt wird.

Initialisierung

Das Cast-Framework hat ein globales Singleton-Objekt, das CastContext, das alle Cast-Interaktionen koordiniert.

Du musst die OptionsProvider-Schnittstelle implementieren, um CastOptions anzugeben, das zum Initialisieren des CastContext-Singleton-Elements erforderlich ist. Die wichtigste Option ist die Empfänger-App-ID, mit der die Ergebnisse der Gerätesuche gefiltert und die Empfänger-App gestartet wird, wenn eine Streamingsitzung gestartet wird.

Wenn Sie Ihre eigene für Google Cast optimierte App entwickeln, müssen Sie sich als Cast-Entwickler registrieren und dann eine Anwendungs-ID für Ihre App abrufen. In diesem Codelab verwenden wir eine Beispiel-App-ID.

Fügen Sie dem com.google.sample.cast.refplayer-Paket des Projekts die folgende neue CastOptionsProvider.kt-Datei hinzu:

package com.google.sample.cast.refplayer

import android.content.Context
import com.google.android.gms.cast.framework.OptionsProvider
import com.google.android.gms.cast.framework.CastOptions
import com.google.android.gms.cast.framework.SessionProvider

class CastOptionsProvider : OptionsProvider {
    override fun getCastOptions(context: Context): CastOptions {
        return CastOptions.Builder()
                .setReceiverApplicationId(context.getString(R.string.app_id))
                .build()
    }

    override fun getAdditionalSessionProviders(context: Context): List<SessionProvider>? {
        return null
    }
}

Deklarieren Sie nun die OptionsProvider im Tag „application“ der App-Datei AndroidManifest.xml:

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

Initialisieren Sie CastContext in der VideoBrowserActivity-Methode „onCreate“ verzögert:

import com.google.android.gms.cast.framework.CastContext

private var mCastContext: CastContext? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.video_browser)
    setupActionBar()

    mCastContext = CastContext.getSharedInstance(this)
}

Fügen Sie der LocalPlayerActivity dieselbe Initialisierungslogik hinzu.

Cast-Symbol

Nachdem die CastContext initialisiert wurde, müssen wir die Schaltfläche „Streamen“ hinzufügen, damit der Nutzer ein Streaminggerät auswählen kann. Die Schaltfläche „Streamen“ wird von MediaRouteButton aus der MediaRouter-Supportbibliothek implementiert. Wie bei jedem Aktionssymbol, das Sie Ihrer Aktivität mithilfe eines ActionBar oder eines Toolbar hinzufügen können, müssen Sie zuerst den entsprechenden Menüpunkt zum Menü hinzufügen.

Bearbeiten Sie die Datei res/menu/browse.xml und fügen Sie den Menüpunkt MediaRouteActionProvider vor dem Menüpunkt „Einstellungen“ ein:

<item
    android:id="@+id/media_route_menu_item"
    android:title="@string/media_route_menu_title"
    app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
    app:showAsAction="always"/>

Überschreiben Sie die onCreateOptionsMenu()-Methode von VideoBrowserActivity, indem Sie CastButtonFactory verwenden, um die MediaRouteButton mit dem Cast-Framework zu verbinden:

import com.google.android.gms.cast.framework.CastButtonFactory

private var mediaRouteMenuItem: MenuItem? = null

override fun onCreateOptionsMenu(menu: Menu): Boolean {
     super.onCreateOptionsMenu(menu)
     menuInflater.inflate(R.menu.browse, menu)
     mediaRouteMenuItem = CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), menu,
                R.id.media_route_menu_item)
     return true
}

Überschreiben Sie onCreateOptionsMenu in LocalPlayerActivity auf ähnliche Weise.

Klicken Sie auf die Schaltfläche Die Schaltfläche „Ausführen“ in Android Studio, ein grünes Dreieck, das nach rechts zeigtAusführen, um die App auf Ihrem Mobilgerät auszuführen. In der Aktionsleiste der App sollte ein Cast-Symbol zu sehen sein. Wenn Sie darauf klicken, werden die Übertragungsgeräte in Ihrem lokalen Netzwerk aufgelistet. Die Geräteerkennung wird automatisch vom CastContext verwaltet. Wählen Sie Ihr Übertragungsgerät aus. Die Beispiel-Empfänger-App wird auf dem Übertragungsgerät geladen. Sie können zwischen den Browseraktivitäten und den Aktivitäten des lokalen Players wechseln. Der Status der Schaltfläche „Streamen“ wird dabei synchronisiert.

Die Medienwiedergabe wird noch nicht unterstützt. Videos können daher noch nicht auf dem Streaminggerät abgespielt werden. Klicken Sie auf die Schaltfläche „Streamen“, um die Verbindung zu trennen.

6. Videoinhalte streamen

Abbildung eines Android-Smartphones mit der App „Videos streamen“

Wir werden die Beispiel-App so erweitern, dass Videos auch per Fernzugriff auf einem Cast-Gerät wiedergegeben werden können. Dazu müssen wir auf die verschiedenen Ereignisse warten, die vom Cast-Framework generiert werden.

Medien streamen

Wenn Sie Medien auf einem Streaminggerät wiedergeben möchten, müssen Sie im Wesentlichen Folgendes tun:

  1. Erstelle ein MediaInfo-Objekt, das ein Medienelement modelliert.
  2. Stelle eine Verbindung zum Streaminggerät her und starte die Empfängeranwendung.
  3. Lade das MediaInfo-Objekt in deinen Empfänger und spiele die Inhalte ab.
  4. Behalten Sie den Medienstatus im Auge.
  5. Senden Sie Wiedergabebefehle an den Empfänger basierend auf Nutzerinteraktionen.

Schritt 2 haben wir bereits im vorherigen Abschnitt ausgeführt. Schritt 3 lässt sich mit dem Cast-Framework ganz einfach umsetzen. In Schritt 1 ordnen wir ein Objekt einem anderen zu. MediaInfo ist ein Objekt, das vom Cast-Framework verstanden wird, und MediaItem ist die Kapselung eines Medienelements in unserer App. Wir können MediaItem ganz einfach einem MediaInfo zuordnen.

In der Beispiel-App LocalPlayerActivity wird bereits anhand dieses Enumerationstyps zwischen lokaler und Remote-Wiedergabe unterschieden:

private var mLocation: PlaybackLocation? = null

enum class PlaybackLocation {
    LOCAL, REMOTE
}

enum class PlaybackState {
    PLAYING, PAUSED, BUFFERING, IDLE
}

In diesem Codelab ist es nicht wichtig, dass Sie genau verstehen, wie die gesamte Logik des Beispiel-Players funktioniert. Beachten Sie, dass der Mediaplayer Ihrer App modifiziert werden muss, damit er die beiden Wiedergabeorte auf ähnliche Weise erkennen kann.

Derzeit befindet sich der lokale Player immer im Status der lokalen Wiedergabe, da er noch nichts über die Streamingstatus weiß. Wir müssen die Benutzeroberfläche basierend auf Statusübergängen im Cast-Framework aktualisieren. Wenn wir beispielsweise mit dem Streamen beginnen, müssen wir die lokale Wiedergabe beenden und einige Steuerelemente deaktivieren. Wenn wir das Streaming in dieser Aktivität beenden, müssen wir zur lokalen Wiedergabe wechseln. Dazu müssen wir die verschiedenen vom Cast-Framework generierten Ereignisse überwachen.

Verwaltung von Übertragungssitzungen

Für das Cast-Framework umfasst eine Cast-Sitzung die Schritte zum Verbinden mit einem Gerät, zum Starten (oder Beitreten) einer Empfängeranwendung und zum Initialisieren eines Mediensteuerungskanals, falls erforderlich. Über den Mediensteuerungskanal sendet und empfängt das Cast-Framework Nachrichten vom Empfänger-Mediaplayer.

Die Übertragungssitzung wird automatisch gestartet, wenn der Nutzer über die Schaltfläche „Streamen“ ein Gerät auswählt, und automatisch beendet, wenn der Nutzer die Verbindung trennt. Auch die Wiederherstellung einer Verbindung zu einer Empfängersitzung aufgrund von Netzwerkproblemen erfolgt automatisch durch das Cast SDK.

Fügen wir der LocalPlayerActivity eine SessionManagerListener hinzu:

import com.google.android.gms.cast.framework.CastSession
import com.google.android.gms.cast.framework.SessionManagerListener
...

private var mSessionManagerListener: SessionManagerListener<CastSession>? = null
private var mCastSession: CastSession? = null
...

private fun setupCastListener() {
    mSessionManagerListener = object : SessionManagerListener<CastSession> {
        override fun onSessionEnded(session: CastSession, error: Int) {
            onApplicationDisconnected()
        }

        override fun onSessionResumed(session: CastSession, wasSuspended: Boolean) {
            onApplicationConnected(session)
        }

        override fun onSessionResumeFailed(session: CastSession, error: Int) {
            onApplicationDisconnected()
        }

        override fun onSessionStarted(session: CastSession, sessionId: String) {
            onApplicationConnected(session)
        }

        override fun onSessionStartFailed(session: CastSession, error: Int) {
            onApplicationDisconnected()
        }

        override fun onSessionStarting(session: CastSession) {}
        override fun onSessionEnding(session: CastSession) {}
        override fun onSessionResuming(session: CastSession, sessionId: String) {}
        override fun onSessionSuspended(session: CastSession, reason: Int) {}
        private fun onApplicationConnected(castSession: CastSession) {
            mCastSession = castSession
            if (null != mSelectedMedia) {
                if (mPlaybackState == PlaybackState.PLAYING) {
                    mVideoView!!.pause()
                    loadRemoteMedia(mSeekbar!!.progress, true)
                    return
                } else {
                    mPlaybackState = PlaybackState.IDLE
                    updatePlaybackLocation(PlaybackLocation.REMOTE)
                }
            }
            updatePlayButton(mPlaybackState)
            invalidateOptionsMenu()
        }

        private fun onApplicationDisconnected() {
            updatePlaybackLocation(PlaybackLocation.LOCAL)
            mPlaybackState = PlaybackState.IDLE
            mLocation = PlaybackLocation.LOCAL
            updatePlayButton(mPlaybackState)
            invalidateOptionsMenu()
       }
   }
}

Bei der Aktivität LocalPlayerActivity möchten wir wissen, wann eine Verbindung zum oder eine Trennung vom Streaminggerät hergestellt wird, damit wir zum lokalen Player wechseln können. Die Verbindung kann nicht nur durch die Instanz Ihrer Anwendung unterbrochen werden, die auf Ihrem Mobilgerät ausgeführt wird, sondern auch durch eine andere Instanz Ihrer (oder einer anderen) Anwendung, die auf einem anderen Mobilgerät ausgeführt wird.

Die derzeit aktive Sitzung kann als SessionManager.getCurrentSession() aufgerufen werden. Sitzungen werden automatisch erstellt und gelöscht, wenn Nutzer mit den Dialogfeldern für Google Cast interagieren.

Wir müssen unseren Sitzungs-Listener registrieren und einige Variablen initialisieren, die wir in der Aktivität verwenden werden. Ändern Sie die Methode LocalPlayerActivity onCreate in:

import com.google.android.gms.cast.framework.CastContext
...

private var mCastContext: CastContext? = null
...

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    mCastContext = CastContext.getSharedInstance(this)
    mCastSession = mCastContext!!.sessionManager.currentCastSession
    setupCastListener()
    ...
    loadViews()
    ...
    val bundle = intent.extras
    if (bundle != null) {
        ....
        if (shouldStartPlayback) {
              ....

        } else {
            if (mCastSession != null && mCastSession!!.isConnected()) {
                updatePlaybackLocation(PlaybackLocation.REMOTE)
            } else {
                updatePlaybackLocation(PlaybackLocation.LOCAL)
            }
            mPlaybackState = PlaybackState.IDLE
            updatePlayButton(mPlaybackState)
        }
    }
    ...
}

Medien werden geladen

Im Cast SDK bietet die RemoteMediaClient eine Reihe praktischer APIs zur Verwaltung der Remote-Medienwiedergabe auf dem Empfänger. Für eine CastSession, die die Medienwiedergabe unterstützt, wird vom SDK automatisch eine Instanz von RemoteMediaClient erstellt. Sie können darauf zugreifen, indem Sie die getRemoteMediaClient()-Methode auf der CastSession-Instanz aufrufen. Füge LocalPlayerActivity die folgenden Methoden hinzu, um das aktuell ausgewählte Video auf dem Empfänger zu laden:

import com.google.android.gms.cast.framework.media.RemoteMediaClient
import com.google.android.gms.cast.MediaInfo
import com.google.android.gms.cast.MediaLoadOptions
import com.google.android.gms.cast.MediaMetadata
import com.google.android.gms.common.images.WebImage
import com.google.android.gms.cast.MediaLoadRequestData

private fun loadRemoteMedia(position: Int, autoPlay: Boolean) {
    if (mCastSession == null) {
        return
    }
    val remoteMediaClient = mCastSession!!.remoteMediaClient ?: return
    remoteMediaClient.load( MediaLoadRequestData.Builder()
                .setMediaInfo(buildMediaInfo())
                .setAutoplay(autoPlay)
                .setCurrentTime(position.toLong()).build())
}

private fun buildMediaInfo(): MediaInfo? {
    val movieMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE)
    mSelectedMedia?.studio?.let { movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, it) }
    mSelectedMedia?.title?.let { movieMetadata.putString(MediaMetadata.KEY_TITLE, it) }
    movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia!!.getImage(0))))
    movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia!!.getImage(1))))
    return mSelectedMedia!!.url?.let {
        MediaInfo.Builder(it)
            .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
            .setContentType("videos/mp4")
            .setMetadata(movieMetadata)
            .setStreamDuration((mSelectedMedia!!.duration * 1000).toLong())
            .build()
    }
}

Aktualisiere jetzt verschiedene vorhandene Methoden, um die Cast-Sitzungslogik zur Unterstützung der Remote-Wiedergabe zu verwenden:

private fun play(position: Int) {
    startControllersTimer()
    when (mLocation) {
        PlaybackLocation.LOCAL -> {
            mVideoView!!.seekTo(position)
            mVideoView!!.start()
        }
        PlaybackLocation.REMOTE -> {
            mPlaybackState = PlaybackState.BUFFERING
            updatePlayButton(mPlaybackState)
            //seek to a new position within the current media item's new position 
            //which is in milliseconds from the beginning of the stream
            mCastSession!!.remoteMediaClient?.seek(position.toLong())
        }
        else -> {}
    }
    restartTrickplayTimer()
}
private fun togglePlayback() {
    ...
    PlaybackState.IDLE -> when (mLocation) {
        ...
        PlaybackLocation.REMOTE -> {
            if (mCastSession != null && mCastSession!!.isConnected) {
                loadRemoteMedia(mSeekbar!!.progress, true)
            }
        }
        else -> {}
    }
    ...
}
override fun onPause() {
    ...
    mCastContext!!.sessionManager.removeSessionManagerListener(
                mSessionManagerListener!!, CastSession::class.java)
}
override fun onResume() {
    Log.d(TAG, "onResume() was called")
    mCastContext!!.sessionManager.addSessionManagerListener(
            mSessionManagerListener!!, CastSession::class.java)
    if (mCastSession != null && mCastSession!!.isConnected) {
        updatePlaybackLocation(PlaybackLocation.REMOTE)
    } else {
        updatePlaybackLocation(PlaybackLocation.LOCAL)
    }
    super.onResume()
}

Ändern Sie für die Methode updatePlayButton den Wert der Variablen isConnected:

private fun updatePlayButton(state: PlaybackState?) {
    ...
    val isConnected = (mCastSession != null
                && (mCastSession!!.isConnected || mCastSession!!.isConnecting))
    ...
}

Klicken Sie jetzt auf die Schaltfläche Die Schaltfläche „Ausführen“ in Android Studio, ein grünes Dreieck, das nach rechts zeigtAusführen, um die App auf Ihrem Mobilgerät auszuführen. Stellen Sie eine Verbindung zu Ihrem Übertragungsgerät her und starten Sie die Wiedergabe eines Videos. Das Video sollte jetzt auf dem Receiver wiedergegeben werden.

7. Mini-Controller

Gemäß der Checkliste für das Cast-Design müssen alle Cast-Apps einen Mini-Controller haben, der angezeigt wird, wenn der Nutzer die aktuelle Inhaltsseite verlässt. Der Mini-Controller bietet sofortigen Zugriff und eine sichtbare Erinnerung an die aktuelle Übertragungssitzung.

Abbildung des unteren Teils eines Android-Smartphones mit dem Miniplayer in der App „Cast Videos“

Das Cast SDK bietet eine benutzerdefinierte Ansicht, MiniControllerFragment, die der App-Layoutdatei der Aktivitäten hinzugefügt werden kann, in denen der Mini-Controller angezeigt werden soll.

Fügen Sie die folgende Fragmentdefinition unten in res/layout/player_activity.xml und res/layout/video_browser.xml hinzu:

<fragment
    android:id="@+id/castMiniController"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:visibility="gone"
    class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment"/>

Klicken Sie auf die Schaltfläche Die Schaltfläche „Ausführen“ in Android Studio, ein grünes Dreieck, das nach rechts zeigtAusführen, um die App auszuführen und ein Video zu streamen. Wenn die Wiedergabe auf dem Receiver gestartet wird, sollte die Minifernbedienung unten bei jeder Aktivität angezeigt werden. Sie können die Wiedergabe über den Mini-Controller steuern. Wenn Sie zwischen der Suchaktivität und der Aktivität des lokalen Players wechseln, sollte der Mini-Controller-Status mit dem Medienwiedergabestatus des Empfängers synchron bleiben.

8. Benachrichtigungen und Sperrbildschirm

Gemäß der Google Cast-Design-Checkliste muss eine Sender-App Mediensteuerelemente in einer Benachrichtigung und auf dem Sperrbildschirm implementieren.

Abbildung eines Android-Smartphones mit Mediensteuerelementen im Benachrichtigungsbereich

Das Cast SDK bietet eine MediaNotificationService, mit der die Sender-App Mediensteuerelemente für die Benachrichtigung und den Sperrbildschirm erstellen kann. Der Dienst wird von Gradle automatisch in das Manifest Ihrer App eingefügt.

Die MediaNotificationService wird im Hintergrund ausgeführt, wenn der Sender streamt. Es wird eine Benachrichtigung mit einem Bild-Thumbnail und Metadaten zum aktuellen gestreamten Element, einer Wiedergabe-/Pause- und einer Stopp-Schaltfläche angezeigt.

Die Steuerelemente für Benachrichtigungen und den Sperrbildschirm können mit dem CastOptions bei der Initialisierung von CastContext aktiviert werden. Die Mediensteuerung für Benachrichtigungen und Sperrbildschirm sind standardmäßig aktiviert. Die Sperrbildschirmfunktion ist aktiviert, solange die Benachrichtigung aktiviert ist.

Bearbeiten Sie CastOptionsProvider und ändern Sie die getCastOptions-Implementierung so, dass sie mit diesem Code übereinstimmt:

import com.google.android.gms.cast.framework.media.CastMediaOptions
import com.google.android.gms.cast.framework.media.NotificationOptions

override fun getCastOptions(context: Context): CastOptions {
   val notificationOptions = NotificationOptions.Builder()
            .setTargetActivityClassName(VideoBrowserActivity::class.java.name)
            .build()
    val mediaOptions = CastMediaOptions.Builder()
            .setNotificationOptions(notificationOptions)
            .build()
   return CastOptions.Builder()
                .setReceiverApplicationId(context.getString(R.string.app_id))
                .setCastMediaOptions(mediaOptions)
                .build()
}

Klicken Sie auf die Schaltfläche Die Schaltfläche „Ausführen“ in Android Studio, ein grünes Dreieck, das nach rechts zeigtAusführen, um die App auf Ihrem Mobilgerät auszuführen. Streamen Sie ein Video und verlassen Sie die Beispiel-App. Es sollte eine Benachrichtigung für das Video geben, das gerade auf dem Empfänger wiedergegeben wird. Sperren Sie Ihr Mobilgerät und der Sperrbildschirm sollte jetzt Steuerelemente für die Medienwiedergabe auf dem Übertragungsgerät anzeigen.

Abbildung eines Android-Smartphones mit Mediensteuerung auf dem Sperrbildschirm

9. Einleitendes Overlay

Gemäß der Google Cast-Design-Checkliste muss eine Sender-App bestehenden Nutzern die Schaltfläche „Streamen“ präsentieren, um sie darüber zu informieren, dass die Sender-App jetzt das Streamen unterstützt. Außerdem sollte sie Nutzern, die Google Cast noch nicht kennen, helfen.

Abbildung, die das Einführungs-Overlay für Google Cast um die Schaltfläche „Streamen“ in der Android-App „Cast Videos“ zeigt

Das Cast SDK bietet eine benutzerdefinierte Ansicht (IntroductoryOverlay), mit der das Cast-Symbol hervorgehoben werden kann, wenn es Nutzern zum ersten Mal angezeigt wird. Fügen Sie VideoBrowserActivity den folgenden Code hinzu:

import com.google.android.gms.cast.framework.IntroductoryOverlay
import android.os.Looper

private var mIntroductoryOverlay: IntroductoryOverlay? = null

private fun showIntroductoryOverlay() {
    mIntroductoryOverlay?.remove()
    if (mediaRouteMenuItem?.isVisible == true) {
       Looper.myLooper().run {
           mIntroductoryOverlay = com.google.android.gms.cast.framework.IntroductoryOverlay.Builder(
                    this@VideoBrowserActivity, mediaRouteMenuItem!!)
                   .setTitleText("Introducing Cast")
                   .setSingleTime()
                   .setOnOverlayDismissedListener(
                           object : IntroductoryOverlay.OnOverlayDismissedListener {
                               override fun onOverlayDismissed() {
                                   mIntroductoryOverlay = null
                               }
                          })
                   .build()
          mIntroductoryOverlay!!.show()
        }
    }
}

Fügen Sie jetzt eine CastStateListener hinzu und rufen Sie die Methode showIntroductoryOverlay auf, wenn ein Streaminggerät verfügbar ist. Ändern Sie dazu die Methode onCreate und überschreiben Sie die Methoden onResume und onPause so, dass sie den folgenden Anforderungen entsprechen:

import com.google.android.gms.cast.framework.CastState
import com.google.android.gms.cast.framework.CastStateListener

private var mCastStateListener: CastStateListener? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.video_browser)
    setupActionBar()
    mCastStateListener = object : CastStateListener {
            override fun onCastStateChanged(newState: Int) {
                if (newState != CastState.NO_DEVICES_AVAILABLE) {
                    showIntroductoryOverlay()
                }
            }
        }
    mCastContext = CastContext.getSharedInstance(this)
}

override fun onResume() {
    super.onResume()
    mCastContext?.addCastStateListener(mCastStateListener!!)
}

override fun onPause() {
    super.onPause()
    mCastContext?.removeCastStateListener(mCastStateListener!!)
}

Löschen Sie die App-Daten oder entfernen Sie die App von Ihrem Gerät. Klicken Sie dann auf die Schaltfläche Die Schaltfläche „Ausführen“ in Android Studio, ein grünes Dreieck, das nach rechts zeigtAusführen, um die App auf Ihrem Mobilgerät auszuführen. Daraufhin sollte das Einführungs-Overlay angezeigt werden. Löschen Sie die App-Daten, wenn das Overlay nicht angezeigt wird.

10. Maximierter Controller

Gemäß der Checkliste für das Design von Google Cast muss eine Sender-App einen erweiterten Controller für die gestreamten Medien bereitstellen. Die erweiterte Steueroberfläche ist eine Vollbildversion der Ministeueroberfläche.

Illustration eines Videos, das auf einem Android-Smartphone abgespielt wird, mit dem darüber liegenden erweiterten Controller

Das Cast SDK bietet ein Widget für den erweiterten Controller namens ExpandedControllerActivity. Dies ist eine abstrakte Klasse, deren Klasse Sie ableiten müssen, um ein Cast-Symbol hinzuzufügen.

Erstellen Sie zuerst eine neue Menüressourcendatei namens expanded_controller.xml für den erweiterten Controller, um die Schaltfläche „Streamen“ bereitzustellen:

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
            android:id="@+id/media_route_menu_item"
            android:title="@string/media_route_menu_title"
            app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
            app:showAsAction="always"/>

</menu>

Erstellen Sie im Paket com.google.sample.cast.refplayer ein neues Paket expandedcontrols. Erstellen Sie als Nächstes im Paket com.google.sample.cast.refplayer.expandedcontrols eine neue Datei mit dem Namen ExpandedControlsActivity.kt.

package com.google.sample.cast.refplayer.expandedcontrols

import android.view.Menu
import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity
import com.google.sample.cast.refplayer.R
import com.google.android.gms.cast.framework.CastButtonFactory

class ExpandedControlsActivity : ExpandedControllerActivity() {
    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        super.onCreateOptionsMenu(menu)
        menuInflater.inflate(R.menu.expanded_controller, menu)
        CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_menu_item)
        return true
    }
}

Deklarieren Sie nun die ExpandedControlsActivity im AndroidManifest.xml innerhalb des application-Tags über der OPTIONS_PROVIDER_CLASS_NAME:

<application>
    ...
    <activity
        android:name="com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity"
        android:label="@string/app_name"
        android:launchMode="singleTask"
        android:theme="@style/Theme.CastVideosDark"
        android:screenOrientation="portrait"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
        </intent-filter>
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.google.sample.cast.refplayer.VideoBrowserActivity"/>
    </activity>
    ...
</application>

Bearbeiten Sie die CastOptionsProvider und ändern Sie NotificationOptions und CastMediaOptions, um die Zielaktivität auf die ExpandedControlsActivity festzulegen:

import com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity

override fun getCastOptions(context: Context): CastOptions {
    val notificationOptions = NotificationOptions.Builder()
            .setTargetActivityClassName(ExpandedControlsActivity::class.java.name)
            .build()
    val mediaOptions = CastMediaOptions.Builder()
            .setNotificationOptions(notificationOptions)
            .setExpandedControllerActivityClassName(ExpandedControlsActivity::class.java.name)
            .build()
    return CastOptions.Builder()
            .setReceiverApplicationId(context.getString(R.string.app_id))
            .setCastMediaOptions(mediaOptions)
            .build()
}

Aktualisiere die Methode LocalPlayerActivity loadRemoteMedia, damit die ExpandedControlsActivity angezeigt wird, wenn die Remote-Medien geladen werden:

import com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity

private fun loadRemoteMedia(position: Int, autoPlay: Boolean) {
    if (mCastSession == null) {
        return
    }
    val remoteMediaClient = mCastSession!!.remoteMediaClient ?: return
    remoteMediaClient.registerCallback(object : RemoteMediaClient.Callback() {
        override fun onStatusUpdated() {
            val intent = Intent(this@LocalPlayerActivity, ExpandedControlsActivity::class.java)
            startActivity(intent)
            remoteMediaClient.unregisterCallback(this)
        }
    })
    remoteMediaClient.load(MediaLoadRequestData.Builder()
                .setMediaInfo(buildMediaInfo())
                .setAutoplay(autoPlay)
                .setCurrentTime(position.toLong()).build())
}

Klicke auf die Schaltfläche Die Schaltfläche „Ausführen“ in Android Studio, ein grünes Dreieck, das nach rechts zeigtAusführen, um die App auf deinem Mobilgerät auszuführen und ein Video zu streamen. Der erweiterte Controller sollte angezeigt werden. Wenn du zur Videoliste zurückkehrst und auf den Mini-Controller klickst, wird der maximierte Controller wieder geladen. Wechseln Sie aus der App heraus, um die Benachrichtigung zu sehen. Klicken Sie auf das Benachrichtigungsbild, um den erweiterten Controller zu laden.

11. Unterstützung für Cast Connect hinzufügen

Mit der Cast Connect-Mediathek können vorhandene Senderanwendungen über das Cast-Protokoll mit Android TV-Anwendungen kommunizieren. Cast Connect baut auf der Cast-Infrastruktur auf, wobei deine Android TV-App als Receiver fungiert.

Abhängigkeiten

Hinweis: Zur Implementierung von Cast Connect muss play-services-cast-framework mindestens 19.0.0 sein.

LaunchOptions

Damit die Android TV-Anwendung, auch als Android-Empfänger bezeichnet, gestartet werden kann, müssen wir das Flag setAndroidReceiverCompatible im Objekt LaunchOptions auf „true“ setzen. Dieses LaunchOptions-Objekt legt fest, wie der Empfänger gestartet wird, und wird an das CastOptions übergeben, das von der CastOptionsProvider-Klasse zurückgegeben wird. Wenn du das oben genannte Flag auf false setzt, wird der Webempfänger für die definierte App-ID in der Cast Developer Console gestartet.

Fügen Sie in der Datei CastOptionsProvider.kt der Methode getCastOptions Folgendes hinzu:

import com.google.android.gms.cast.LaunchOptions
...
val launchOptions = LaunchOptions.Builder()
            .setAndroidReceiverCompatible(true)
            .build()
return new CastOptions.Builder()
        .setLaunchOptions(launchOptions)
        ...
        .build()

Anmeldedaten für den Start festlegen

Auf der Absenderseite können Sie CredentialsData angeben, um anzugeben, wer an der Sitzung teilnimmt. credentials ist ein String, der vom Nutzer definiert werden kann, solange er von deiner ATV-App verstanden wird. Die CredentialsData wird nur beim Starten oder Beitreten an deine Android TV-App übergeben. Wenn du sie während einer Verbindung noch einmal festlegst, wird sie nicht an deine Android TV App übergeben.

Damit Startanmeldedaten festgelegt werden können, muss CredentialsData definiert und an das LaunchOptions-Objekt übergeben werden. Fügen Sie der Methode getCastOptions in der Datei CastOptionsProvider.kt den folgenden Code hinzu:

import com.google.android.gms.cast.CredentialsData
...

val credentialsData = CredentialsData.Builder()
        .setCredentials("{\"userId\": \"abc\"}")
        .build()
val launchOptions = LaunchOptions.Builder()
       ...
       .setCredentialsData(credentialsData)
       .build()

Anmeldedaten für LoadRequest festlegen

Falls die Web Receiver App und die Android TV App credentials unterschiedlich verarbeiten, musst du möglicherweise für jeden ein separates credentials-Objekt definieren. Fügen Sie dazu in der Datei LocalPlayerActivity.kt unter der Funktion loadRemoteMedia den folgenden Code hinzu:

remoteMediaClient.load(MediaLoadRequestData.Builder()
       ...
       .setCredentials("user-credentials")
       .setAtvCredentials("atv-user-credentials")
       .build())

Abhängig von der Empfänger-App, an die Ihr Absender etwas überträgt, verarbeitet das SDK jetzt automatisch, welche Anmeldedaten für die aktuelle Sitzung verwendet werden.

Cast Connect testen

Android TV-APK auf Chromecast mit Google TV installieren

  1. Ermitteln Sie die IP-Adresse Ihres Android TV-Geräts. Normalerweise finden Sie sie unter Einstellungen > Netzwerk und Internet > (Name des Netzwerks, mit dem Ihr Gerät verbunden ist). Auf der rechten Seite werden die Details und die IP-Adresse Ihres Geräts im Netzwerk angezeigt.
  2. Verwenden Sie die IP-Adresse Ihres Geräts, um über das Terminal eine ADB-Verbindung herzustellen:
$ adb connect <device_ip_address>:5555
  1. Rufen Sie im Terminalfenster den übergeordneten Ordner für die Codelab-Beispiele auf, die Sie zu Beginn dieses Codelabs heruntergeladen haben. Beispiel:
$ cd Desktop/android_codelab_src
  1. Installieren Sie die APK-Datei in diesem Ordner auf Ihrem Android TV-Gerät:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. Auf Ihrem Android TV-Gerät sollte jetzt im Menü Meine Apps eine App mit dem Namen Videos streamen angezeigt werden.
  2. Kehren Sie zu Ihrem Android Studio-Projekt zurück und klicken Sie auf die Schaltfläche „Ausführen“, um die Sender-App auf Ihrem Mobilgerät zu installieren und auszuführen. Klicke oben rechts auf das Übertragungssymbol und wähle dein Android TV-Gerät aus den verfügbaren Optionen aus. Die Android TV App sollte jetzt auf Ihrem Android TV-Gerät gestartet werden. Wenn Sie ein Video abspielen, können Sie die Videowiedergabe mit der Android TV-Fernbedienung steuern.

12. Streaming-Widgets anpassen

Sie können Cast-Widgets anpassen, indem Sie die Farben, die Schaltflächen, den Text und die Darstellung der Miniaturansichten festlegen sowie die Schaltflächentypen auswählen, die angezeigt werden sollen.

res/values/styles_castvideo.xml aktualisieren

<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
    ...
    <item name="mediaRouteTheme">@style/CustomMediaRouterTheme</item>
    <item name="castIntroOverlayStyle">@style/CustomCastIntroOverlay</item>
    <item name="castMiniControllerStyle">@style/CustomCastMiniController</item>
    <item name="castExpandedControllerStyle">@style/CustomCastExpandedController</item>
    <item name="castExpandedControllerToolbarStyle">
        @style/ThemeOverlay.AppCompat.ActionBar
    </item>
    ...
</style>

Deklarieren Sie die folgenden benutzerdefinierten Designs:

<!-- Customize Cast Button -->
<style name="CustomMediaRouterTheme" parent="Theme.MediaRouter">
    <item name="mediaRouteButtonStyle">@style/CustomMediaRouteButtonStyle</item>
</style>
<style name="CustomMediaRouteButtonStyle" parent="Widget.MediaRouter.Light.MediaRouteButton">
    <item name="mediaRouteButtonTint">#EEFF41</item>
</style>

<!-- Customize Introductory Overlay -->
<style name="CustomCastIntroOverlay" parent="CastIntroOverlay">
    <item name="castButtonTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Button</item>
    <item name="castTitleTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Title</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Button" parent="android:style/TextAppearance">
    <item name="android:textColor">#FFFFFF</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Title" parent="android:style/TextAppearance.Large">
    <item name="android:textColor">#FFFFFF</item>
</style>

<!-- Customize Mini Controller -->
<style name="CustomCastMiniController" parent="CastMiniController">
    <item name="castShowImageThumbnail">true</item>
    <item name="castTitleTextAppearance">@style/TextAppearance.AppCompat.Subhead</item>
    <item name="castSubtitleTextAppearance">@style/TextAppearance.AppCompat.Caption</item>
    <item name="castBackground">@color/accent</item>
    <item name="castProgressBarColor">@color/orange</item>
</style>

<!-- Customize Expanded Controller -->
<style name="CustomCastExpandedController" parent="CastExpandedController">
    <item name="castButtonColor">#FFFFFF</item>
    <item name="castPlayButtonDrawable">@drawable/cast_ic_expanded_controller_play</item>
    <item name="castPauseButtonDrawable">@drawable/cast_ic_expanded_controller_pause</item>
    <item name="castStopButtonDrawable">@drawable/cast_ic_expanded_controller_stop</item>
</style>

13. Glückwunsch

Sie wissen jetzt, wie Sie eine Video-App mit den Cast SDK-Widgets auf Android-Geräten für das Streaming mit Google Cast aktivieren.

Weitere Informationen findest du im Entwicklerhandbuch für Android-Sender.