Für Google Cast optimierte Android-App

1. Überblick

Google Cast-Logo

In diesem Codelab erfahren Sie, wie Sie eine vorhandene Android-Video-App ändern können, um Inhalte auf ein für Google Cast optimiertes Gerät zu streamen.

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 gemäß der Google Cast-Design-Checkliste hinzufügen.

Die Checkliste für das Design von Google Cast enthält eine einfache und vorhersehbare Checkliste für alle unterstützten Plattformen.

Ziele

Wenn Sie dieses Codelab abgeschlossen haben, verfügen Sie über eine Android-Video-App, mit der Sie Videos auf ein für Google Cast optimiertes Gerät streamen können.

Lerninhalte

  • Google Cast SDK einer Beispielvideo-App hinzufügen
  • Hinzufügen des Cast-Symbols zur Auswahl eines Google Cast-Geräts
  • Hier erfahren Sie, wie Sie eine Verbindung zu einem Übertragungsgerät herstellen und einen Medienempfänger starten.
  • So streamen Sie ein Video.
  • Cast Mini-Controller zur App hinzufügen
  • Unterstützung von Medienbenachrichtigungen und Steuerelementen für den Sperrbildschirm
  • So fügst du einen erweiterten Controller hinzu.
  • So stellst du ein einführendes Overlay bereit.
  • Streaming-Widgets anpassen
  • Einbindung in Cast Connect

Voraussetzungen

  • Das neueste Android SDK
  • Android Studio ab Version 3.2
  • Ein Mobilgerät mit Android 4.1 (Jelly Bean) und höher (API-Level 16)
  • Ein USB-Datenkabel zum Verbinden Ihres Mobilgeräts mit dem Entwicklungscomputer.
  • Ein Google Cast-Gerät wie Chromecast oder Android TV mit Internetzugang
  • Fernseher oder Monitor mit HDMI-Eingang
  • Zum Testen der Cast Connect-Integration ist ein Chromecast mit Google TV erforderlich, für den Rest des Codelabs jedoch optional. Wenn Sie keinen haben, können Sie den Schritt Unterstützung für Cast Connect hinzufügen am Ende dieser Anleitung überspringen.

Plattform

  • Vorkenntnisse in Kotlin und Android sind erforderlich.
  • Außerdem benötigst du Vorkenntnisse im Fernsehen.

Wie werden Sie dieses Tutorial verwenden?

Nur lesen Lesen und die Übungen abschließen

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

Neuling Fortgeschritten Profi

Wie würdest du deine Erfahrung mit Fernsehen bewerten?

Neuling Fortgeschritten Profi

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 Kompasspaares

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, wird im Folgenden beschrieben, wie Sie die fertige Beispiel-App in Android Studio öffnen und ausführen:

Wählen Sie auf der Willkommensseite Projekt importieren oder in den Menüoptionen 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 Datei > Android Studio-Schaltfläche „Sync Project with Gradle“ (Projekt mit Gradle synchronisieren) Projekt mit Gradle-Dateien synchronisieren.

Aktiviere USB-Debugging auf deinem Android-Gerät. Unter Android 4.2 und höher ist der Bildschirm mit den Entwickleroptionen standardmäßig ausgeblendet. Wenn Sie es sichtbar machen 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 es zu aktivieren.

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

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 auf Ihrem Google Cast-Gerät beginnt.

Der maximierte Controller wird angezeigt. Mit der Schaltfläche für Wiedergabe/Pause können Sie die Wiedergabe steuern.

Zurück zur Videoliste.

Unten auf dem Display ist jetzt ein Mini-Controller zu sehen. Darstellung eines Android-Smartphones, auf dem die App „Videos streamen“ mit dem Mini-Controller unten auf dem Bildschirm angezeigt wird

Klicke auf die Pause-Taste auf dem Mini-Controller, um das Video auf dem Empfänger anzuhalten. Klicke auf die Wiedergabetaste auf dem Mini-Controller, um die Wiedergabe des Videos fortzusetzen.

Klicken Sie auf die Startbildschirmtaste des Mobilgeräts. Ziehen Sie die Benachrichtigungen herunter. Sie sollten jetzt eine Benachrichtigung für die Übertragung sehen.

Wenn Sie Ihr Smartphone sperren, sollten Sie auf dem Sperrbildschirm eine Benachrichtigung sehen, über die 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, auf dem die App „Videos streamen“ ausgeführt wird

Wir müssen der heruntergeladenen Start-App Unterstützung für Google Cast hinzufügen. Hier sind einige Google Cast-Terminologie, die wir in diesem Codelab verwenden werden:

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

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

  1. Wählen Sie das Verzeichnis Ordnersymbolapp-start aus dem heruntergeladenen Beispielcode aus. Wählen Sie dazu auf der Willkommensseite Projekt importieren oder in der Menüoption Datei > Neu > Projekt importieren... aus.
  2. Klicken Sie auf die Schaltfläche Android Studio-Schaltfläche „Sync Project with Gradle“ (Projekt mit Gradle synchronisieren) Sync Project with Gradle Files.
  3. Klicken Sie auf die Schaltfläche Schaltfläche „Ausführen“ in Android Studio, ein grünes Dreieck, das nach rechts zeigtRun (Ausfü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 dem Nutzer eine Liste zur Verfügung. Nutzer können ein Video auswählen, um die Details zu sehen, oder das Video lokal auf dem Mobilgerät abspielen.

Die App besteht aus zwei Hauptaktivitäten: VideoBrowserActivity und LocalPlayerActivity. Damit die Google Cast-Funktion integriert werden kann, müssen die Aktivitäten entweder vom AppCompatActivity oder vom übergeordneten Element FragmentActivity übernommen werden. Diese Einschränkung besteht, da wir die MediaRouteButton aus der MediaRouter-Supportbibliothek als MediaRouteActionProvider hinzufügen müssten, und dies funktioniert nur, wenn die Aktivität von den oben genannten Klassen übernimmt. Die MediaRouter-Supportbibliothek hängt von der AppCompat-Supportbibliothek ab, die die erforderlichen Klassen bereitstellt.

VideoBrowserActivity

Diese Aktivität enthält ein Fragment (VideoBrowserFragment). Diese Liste wird von einem ArrayAdapter (VideoListAdapter) gestützt. Die Liste der Videos und deren zugehörige Metadaten wird auf einem Remote-Server als JSON-Datei gehostet. Ein AsyncTaskLoader (VideoItemLoader) ruft diesen JSON-Code ab und verarbeitet ihn, 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 zugehörige Text-Tracks (für Untertitel), falls vorhanden. Das MediaItem-Objekt wird zwischen Aktivitäten übergeben. Daher verfügt MediaItem über Hilfsmethoden, mit denen es in ein Bundle konvertiert wird und umgekehrt.

Wenn das Ladeprogramm die Liste von MediaItems erstellt, übergibt es diese an den VideoListAdapter, der dann die MediaItems-Liste in der VideoBrowserFragment präsentiert. 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 die 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.

Bei der Aktivität werden ein VideoView, einige Mediensteuerelemente und ein Textbereich für die Beschreibung des ausgewählten Videos gehostet. Der Player deckt den oberen Teil des Bildschirms ab und lässt Platz für die detaillierte Beschreibung des Videos darunter. Der Nutzer kann Videos abspielen/anhalten oder die lokale Wiedergabe suchen.

Abhängigkeiten

Da wir AppCompatActivity verwenden, benötigen wir die AppCompat-Supportbibliothek. Zum Verwalten der Videoliste und zum asynchronen Abrufen der Bilder für die Liste verwenden wir die Volley-Bibliothek.

Häufig gestellte Fragen

5. Cast-Symbol hinzufügen

Darstellung des oberen Teils eines Android-Smartphones mit ausgeführter Video-App; das Cast-Symbol oben rechts auf dem Bildschirm

In einer für Google Cast optimierten App wird das Cast-Symbol bei allen Aktivitäten angezeigt. Wenn der Nutzer auf das Cast-Symbol klickt, wird eine Liste mit Übertragungsgeräten angezeigt. Wenn der Nutzer Inhalte lokal auf dem Sendergerät wiedergegeben hat, wird durch die Auswahl eines Übertragungsgeräts die Wiedergabe auf diesem Übertragungsgerät gestartet oder fortgesetzt. Der Nutzer kann jederzeit während einer Sitzung auf das Cast-Symbol klicken und das Streaming Ihrer App auf das Übertragungsgerät beenden. Der Nutzer muss sich wie in der Checkliste für das Design von Google Cast beschrieben mit dem Übertragungsgerät verbinden können, während er Ihre App verwendet.

Abhängigkeiten

Fügen Sie der Datei build.gradle die erforderlichen Bibliotheksabhängigkeiten hinzu:

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 zu prüfen, ob das Projekt fehlerfrei erstellt wird.

Initialisierung

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

Sie müssen die Schnittstelle OptionsProvider implementieren und CastOptions bereitstellen, das zum Initialisieren des Singleton-Elements CastContext erforderlich ist. Die wichtigste Option ist die ID der Empfänger-App. Sie wird verwendet, um die Ergebnisse der Streaming-Gerätesuche zu filtern und die Empfänger-App beim Start einer Streaming-Sitzung zu starten.

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 anfordern. Für dieses Codelab verwenden wir eine Beispiel-App-ID.

Fügen Sie dem Paket com.google.sample.cast.refplayer 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
    }
}

Geben Sie nun OptionsProvider im Tag „application“ der Datei AndroidManifest.xml der App an:

<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 verzögert in der onCreate-Methode VideoBrowserActivity:

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 dem LocalPlayerActivity dieselbe Initialisierungslogik hinzu.

Cast-Symbol

Nachdem CastContext initialisiert wurde, müssen wir das Cast-Symbol hinzufügen, damit der Nutzer ein Übertragungsgerät auswählen kann. Das Cast-Symbol wird vom MediaRouteButton aus der MediaRouter-Supportbibliothek implementiert. Wie bei jedem Aktionssymbol, das Sie mit einem ActionBar oder einem Toolbar Ihren Aktivitäten hinzufügen können, müssen Sie zuerst den entsprechenden Menüpunkt zu Ihrem Menü hinzufügen.

Bearbeiten Sie die Datei res/menu/browse.xml und fügen Sie im Menü das Element MediaRouteActionProvider vor dem Einstellungselement hinzu:

<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 Methode onCreateOptionsMenu() von VideoBrowserActivity, indem Sie CastButtonFactory verwenden, um 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 auf ähnliche Weise in LocalPlayerActivity.

Klicken Sie auf die Schaltfläche 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 eine Cast-Schaltfläche 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ähle dein Übertragungsgerät aus. Die Beispiel-Empfänger-App wird dann auf das Übertragungsgerät geladen. Du kannst zwischen den Suchaktivitäten und der Aktivität des lokalen Players wechseln und der Status des Cast-Symbols wird synchronisiert.

Wir haben keine Unterstützung für die Medienwiedergabe hergestellt, sodass Sie noch keine Videos auf dem Übertragungsgerät abspielen können. Klicke auf das Cast-Symbol, um die Verbindung zu trennen.

6. Videoinhalte streamen

Abbildung eines Android-Smartphones, auf dem die App „Videos streamen“ ausgeführt wird

Wir werden die Beispiel-App erweitern, damit Videos auch aus der Ferne auf einem Übertragungsgerät abgespielt werden können. Dazu müssen wir auf die verschiedenen Ereignisse warten, die vom Cast-Framework generiert werden.

Medien werden gestreamt

Wenn Sie Medien auf einem Übertragungsgerät abspielen möchten, gehen Sie so vor:

  1. Erstellen Sie ein MediaInfo-Objekt, das ein Medienelement modelliert.
  2. Stellen Sie eine Verbindung zum Übertragungsgerät her und starten Sie die Empfänger-App.
  3. Laden Sie das MediaInfo-Objekt in den Empfänger und geben Sie den Inhalt wieder.
  4. Verfolgen Sie den Medienstatus.
  5. Sendet Wiedergabebefehle auf der Grundlage von Nutzerinteraktionen an den Empfänger.

Wir haben Schritt 2 bereits im vorherigen Abschnitt ausgeführt. Schritt 3 lässt sich ganz einfach mit dem Cast-Framework durchführen. In Schritt 1 wird ein Objekt einem anderen zugeordnet. MediaInfo ist etwas, das das Cast-Framework versteht, und MediaItem ist die Kapselung eines Medienelements in unserer App. Ein MediaItem kann ganz einfach einem MediaInfo zugeordnet werden.

Die Beispiel-App LocalPlayerActivity unterscheidet bereits mithilfe der folgenden Aufzählung zwischen lokaler und Remote-Wiedergabe:

private var mLocation: PlaybackLocation? = null

enum class PlaybackLocation {
    LOCAL, REMOTE
}

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

Es ist nicht wichtig, dass du in diesem Codelab genau verstehst, wie die gesamte Beispiel-Playerlogik funktioniert. Es ist wichtig zu verstehen, dass der Mediaplayer Ihrer App modifiziert werden muss, um die beiden Wiedergabeorte auf ähnliche Weise erkennen zu können.

Momentan befindet sich der lokale Player immer im lokalen Wiedergabestatus, da er noch nichts über die Übertragungsstatus hat. Wir müssen die Benutzeroberfläche basierend auf Statusübergängen aktualisieren, die im Cast-Framework stattfinden. Wenn Sie beispielsweise mit dem Streamen beginnen, müssen wir die lokale Wiedergabe beenden und einige Steuerelemente deaktivieren. Das Gleiche gilt, wenn wir das Streamen beenden, während wir diese Aktivität ausführen, müssen wir zur lokalen Wiedergabe wechseln. Dazu müssen wir auf die verschiedenen Ereignisse warten, die vom Cast-Framework generiert werden.

Streamingsitzung verwalten

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

Die Übertragung wird automatisch gestartet, wenn der Nutzer ein Gerät über das Cast-Symbol auswählt, und automatisch beendet, wenn der Nutzer die Verbindung trennt. Das erneute Herstellen einer Verbindung zu einer Empfängersitzung aufgrund von Netzwerkproblemen wird ebenfalls automatisch vom Cast SDK übernommen.

Fügen wir der LocalPlayerActivity ein 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()
       }
   }
}

Wir möchten in den Aktivitäten des Typs "LocalPlayerActivity" informiert werden, wenn eine Verbindung zum Übertragungsgerät hergestellt oder getrennt wird, damit wir zum lokalen Player wechseln können. Beachten Sie, dass die Verbindung nicht nur durch die Instanz Ihrer Anwendung, die auf Ihrem Mobilgerät ausgeführt wird, unterbrochen werden kann, sondern auch durch eine andere Instanz Ihrer (oder eine andere) Anwendung, die auf einem anderen Mobilgerät ausgeführt wird.

Auf die derzeit aktive Sitzung kann als SessionManager.getCurrentSession() zugegriffen werden. Sitzungen werden als Reaktion auf Nutzerinteraktionen mit den Cast-Dialogfeldern automatisch erstellt und entfernt.

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 das RemoteMediaClient eine Reihe praktischer APIs für die Remote-Medienwiedergabe auf dem Empfänger. Bei einem CastSession, das die Medienwiedergabe unterstützt, wird vom SDK automatisch eine Instanz von RemoteMediaClient erstellt. Sie können darauf zugreifen, indem Sie die Methode getRemoteMediaClient() auf der Instanz CastSession aufrufen. Füge LocalPlayerActivity die folgenden Methoden hinzu, um das aktuell ausgewählte Video auf den 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()
    }
}

Aktualisieren Sie nun 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 nun auf die Schaltfläche 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 auf dem Receiver wiedergegeben werden.

7. Mini-Controller

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

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

Das Cast SDK bietet eine benutzerdefinierte Ansicht MiniControllerFragment, die Sie der App-Layoutdatei der Aktivitäten hinzufügen können, in denen Sie den Mini-Controller zeigen möchten.

Fügen Sie am Ende von res/layout/player_activity.xml und res/layout/video_browser.xml die folgende Fragmentdefinition 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 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 beginnt, sollte der Mini-Controller unten bei jeder Aktivität angezeigt werden. Die Remote-Wiedergabe kannst du mit dem Mini-Controller steuern. Wenn Sie zwischen den Suchaktivitäten und dem lokalen Player wechseln, sollte der Status des Mini-Controllers mit dem Status der Medienwiedergabe auf dem Empfänger synchron bleiben.

8. Benachrichtigung und Sperrbildschirm

Gemäß der Checkliste für das Design von Google Cast muss eine Sender-App die Mediensteuerung über eine Benachrichtigung und den Sperrbildschirm implementieren.

Abbildung eines Android-Smartphones mit Mediensteuerelementen im Benachrichtigungsbereich

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

MediaNotificationService wird im Hintergrund ausgeführt, wenn der Absender eine Übertragung startet. Sie zeigt eine Benachrichtigung mit einer Miniaturansicht des Bildes, Metadaten zum aktuellen Streaming-Element, einer Schaltfläche für Wiedergabe/Pause und einer Schaltfläche zum Beenden an.

Die Steuerelemente für Benachrichtigungen und Sperrbildschirm können mit CastOptions beim Initialisieren von CastContext aktiviert werden. Die Mediensteuerung für Benachrichtigungen und Sperrbildschirm ist standardmäßig aktiviert. Die Sperrbildschirm-Funktion ist aktiviert, solange die Benachrichtigungsfunktion aktiviert ist.

Bearbeiten Sie die CastOptionsProvider und ändern Sie die getCastOptions-Implementierung entsprechend diesem Code:

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 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. Sie sollten eine Benachrichtigung für das Video sehen, das gerade auf dem Empfänger wiedergegeben wird. Wenn Sie Ihr Mobilgerät sperren, sollten auf dem Sperrbildschirm jetzt Steuerelemente für die Medienwiedergabe auf dem Übertragungsgerät angezeigt werden.

Abbildung eines Android-Smartphones mit Mediensteuerelementen auf dem Sperrbildschirm

9. Einleitendes Overlay

Gemäß der Checkliste für das Design von Google Cast muss eine Sender-App für bestehende Nutzer das Cast-Symbol einführen, um sie darauf hinzuweisen, dass die Sender-App jetzt Streaming unterstützt und Nutzern hilft, die neu bei Google Cast sind.

Abbildung mit dem einführenden Cast-Overlay um das Cast-Symbol in der Android-App &quot;Videos streamen&quot;

Das Cast SDK bietet eine benutzerdefinierte Ansicht (IntroductoryOverlay), in 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üge nun ein CastStateListener hinzu und rufe die showIntroductoryOverlay-Methode auf, wenn ein Übertragungsgerät verfügbar ist. Ändere dazu die onCreate-Methode und überschreibe die onResume- und onPause-Methoden, sodass sie Folgendem 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 anschließend auf die Schaltfläche 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. Das einführende Overlay sollte erscheinen. Wenn das Overlay nicht angezeigt wird, werden die App-Daten gelöscht.

10. Maximierter Controller

Gemäß der Design-Checkliste für Google Cast muss eine Sender-App eine erweiterte Steuerung für die gestreamten Medien bereitstellen. Der maximierte Controller ist eine Vollbildversion des Mini-Controllers.

Darstellung eines Videos, das auf einem Android-Smartphone mit dem erweiterten Controller abgespielt wird

Das Cast SDK enthält ein Widget für den erweiterten Controller mit dem Namen ExpandedControllerActivity. Dies ist eine abstrakte Klasse, deren abgeleitete Klasse ist, um ein Cast-Symbol hinzufügen zu können.

Erstellen Sie zuerst eine neue Menüressourcendatei namens expanded_controller.xml für den maximierten Controller, um das Cast-Symbol 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 ein neues Paket expandedcontrols im Paket com.google.sample.cast.refplayer. Erstellen Sie als Nächstes eine neue Datei mit dem Namen ExpandedControlsActivity.kt im Paket com.google.sample.cast.refplayer.expandedcontrols.

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 ExpandedControlsActivity im AndroidManifest.xml innerhalb des application-Tags über 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 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()
}

Aktualisieren Sie die Methode LocalPlayerActivity loadRemoteMedia, um ExpandedControlsActivity anzuzeigen, 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())
}

Klicken Sie auf die Schaltfläche 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 und ein Video zu streamen. Der maximierte Controller sollte angezeigt werden. Gehe zurück zur Videoliste. Wenn du auf den Mini-Controller klickst, wird der maximierte Controller wieder geladen. Verlasse die App, um die Benachrichtigung zu sehen. Klicken Sie auf das Benachrichtigungsbild, um den maximierten Controller zu laden.

11. Cast Connect-Unterstützung hinzufügen

Mithilfe der Cast Connect-Bibliothek können vorhandene Sender-Apps über das Cast-Protokoll mit Android TV-Apps kommunizieren. Cast Connect basiert auf der Cast-Infrastruktur, wobei Ihre Android TV App als Empfänger fungiert.

Abhängigkeiten

Hinweis: Für die Implementierung von Cast Connect muss play-services-cast-framework mindestens 19.0.0 sein.

LaunchOptions

Um die Android TV App zu starten, die auch als Android-Empfänger bezeichnet wird, muss das setAndroidReceiverCompatible-Flag im LaunchOptions-Objekt auf „true“ gesetzt werden. Dieses LaunchOptions-Objekt bestimmt, 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 angegebene App-ID in der Cast-Entwicklerkonsole 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()

Start-Anmeldedaten festlegen

Auf der Absenderseite können Sie CredentialsData angeben, um anzugeben, wer der Sitzung beitritt. „credentials“ ist ein String, der vom Nutzer definiert werden kann, solange die ATV-App ihn verstehen kann. Die CredentialsData wird nur beim Start oder der Zeit des Beitritts an deine Android TV-App weitergegeben. Wenn du sie wieder festlegst, während eine Verbindung besteht, wird sie nicht an deine Android TV App übergeben.

Zum Festlegen von Start-Anmeldedaten 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 credentials in deiner Web-Receiver-App und deiner Android TV-App unterschiedlich verarbeitet werden, musst du möglicherweise für beide separate credentials definieren. Fügen Sie daher in die Datei LocalPlayerActivity.kt unter der Funktion loadRemoteMedia den folgenden Code ein:

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

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

Cast Connect wird getestet

Schritte zur Installation des Android TV-APKs auf Chromecast mit Google TV

  1. Ermitteln Sie die IP-Adresse Ihres Android TV-Geräts. Sie ist normalerweise unter Einstellungen > Netzwerk und Internet > (Netzwerkname, mit dem Ihr Gerät verbunden ist) zu finden. Auf der rechten Seite werden die Details und die IP-Adresse Ihres Geräts im Netzwerk angezeigt.
  2. Verwende die IP-Adresse deines Geräts, um über das Terminal über ADB eine Verbindung zu ihm herzustellen:
$ adb connect <device_ip_address>:5555
  1. Gehen Sie im Terminalfenster zum Ordner der obersten Ebene mit den Codelab-Beispielen, die Sie zu Beginn dieses Codelabs heruntergeladen haben. Beispiel:
$ cd Desktop/android_codelab_src
  1. Installieren Sie die in diesem Ordner enthaltene APK-Datei auf Ihrem Android TV-Gerät .Führen Sie dazu den folgenden Befehl aus:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. Sie sollten nun eine App mit dem Namen Videos streamen im Menü Meine Apps auf Ihrem Android TV-Gerät sehen.
  2. Kehren Sie zu Ihrem Android Studio-Projekt zurück und klicken Sie auf die Schaltfläche Run (Ausführen), um die Sender-App auf Ihrem physischen Mobilgerät zu installieren und auszuführen. Klicke oben rechts auf das Cast-Symbol und wähle dein Android TV-Gerät aus den verfügbaren Optionen aus. Die Android TV-App sollte nun auf Ihrem Android TV-Gerät gestartet werden. Bei der Wiedergabe eines Videos sollte die Steuerung über die Fernbedienung Ihres Android TV-Geräts möglich sein.

12. Streaming-Widgets anpassen

Sie können Streaming-Widgets anpassen, indem Sie die Farben, den Stil der Schaltflächen, den Text und die Darstellung der Miniaturansichten festlegen und 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>

Geben Sie die folgenden benutzerdefinierten Designs an:

<!-- 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

Jetzt wissen Sie, wie Sie mithilfe der Cast SDK-Widgets unter Android eine Video-App für Google Cast aktivieren.

Weitere Informationen finden Sie im Entwicklerleitfaden für Android-Sender.