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 anpassen, dass sie Inhalte auf ein für Google Cast optimiertes Gerät streamen kann.

Was ist Google Cast?

Mit Google Cast können Nutzer Inhalte von Mobilgeräten 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 so erweitern, dass sie einen Fernseher oder ein Soundsystem steuern kann. Mit dem Cast SDK können Sie die erforderlichen UI-Komponenten anhand der Checkliste für das Google Cast-Design hinzufügen.

Die Design-Checkliste für Google Cast soll die Nutzung von 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 für Google Cast optimiertes Gerät streamen können.

Lerninhalte

  • Hinzufügen des Google Cast SDK zu einer Beispiel-Video-App
  • 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 Steuerelementen für den Sperrbildschirm
  • So fügst du einen erweiterten Controller hinzu.
  • So erstellst du ein einführendes Overlay.
  • Cast-Widgets anpassen
  • Cast Connect einbinden

Voraussetzungen

  • Das neueste Android SDK
  • Android Studio Version 3.2 oder höher
  • Ein Mobilgerät mit Android Jelly Bean ab Version 4.1 (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 Internetverbindung
  • Einen Fernseher oder Monitor mit HDMI-Eingang
  • Zum Testen der Cast Connect-Integration ist Chromecast mit Google TV erforderlich, für den Rest des Codelabs ist sie jedoch optional. Falls Sie keines haben, überspringen Sie den Schritt Cast Connect-Unterstützung hinzufügen gegen Ende dieser Anleitung.

Erfahrung

  • Sie müssen über Vorkenntnisse in der Kotlin- und Android-Entwicklung verfügen.
  • Außerdem benötigen Sie Vorkenntnisse in Bezug auf Fernsehen. :)

Wie möchten Sie diese Anleitung nutzen?

<ph type="x-smartling-placeholder"></ph> Nur bis zum Ende lesen Lies sie dir durch und absolviere die Übungen

Wie würdest du deine Erfahrung mit der Entwicklung von Android-Apps bewerten?

<ph type="x-smartling-placeholder"></ph> Neuling Leicht fortgeschritten Kompetent

Wie würden Sie Ihre Erfahrungen mit Fernsehen bewerten?

<ph type="x-smartling-placeholder"></ph> Neuling Leicht fortgeschritten Kompetent

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 Kompasspaars

Sehen wir uns zunächst 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 wiedergeben oder auf ein Google Cast-Gerät streamen.

Nachdem Sie den Code heruntergeladen haben, wird in der folgenden Anleitung beschrieben, wie Sie die fertige Beispiel-App in Android Studio öffnen und ausführen:

Wählen Sie auf dem Begrüßungsbildschirm Projekt importieren oder die Option File > 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 „Sync Project with Gradle“ (Projekt mit Gradle synchronisieren) Schaltfläche 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. Unter Einstellungen > Über das Telefon und tippen Sie siebenmal auf Build-Nummer. Kehre zum vorherigen Bildschirm zurück und gehe 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 die Stromversorgung 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 zeigtAusfü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.

Das Video wird auf Ihrem Google Cast-Gerät wiedergegeben.

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

Gehe zurück zur Liste der Videos.

Unten auf dem Bildschirm wird jetzt ein Mini-Controller angezeigt. Abbildung eines Android-Smartphones, auf dem die Funktion „Videos streamen“ ausgeführt wird App mit dem Mini-Controller unten auf dem Bildschirm

Drücke im Mini-Controller auf die Schaltfläche „Pause“, um das Video auf dem Receiver zu pausieren. Klicke im Mini-Controller auf die Wiedergabeschaltfläche, um die Wiedergabe des Videos fortzusetzen.

Klicken Sie auf die Schaltfläche für die Startseite des Mobilgeräts. Ziehen Sie die Benachrichtigungen herunter. Nun sollten Sie eine Benachrichtigung für das Streamen sehen.

Sperren Sie Ihr Smartphone. Wenn Sie es entsperren, sollte auf dem Sperrbildschirm eine Benachrichtigung angezeigt werden, über die Sie die Medienwiedergabe steuern oder das Streamen 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 Funktion „Videos streamen“ ausgeführt wird App

Wir müssen der heruntergeladenen Start-App Unterstützung für 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 Receiver-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 Download des Beispielcodes aus. Wählen Sie dazu auf der Willkommensseite Projekt importieren oder die Menüoption Datei > Neu > Projekt importieren... aus.
  2. Klicken Sie auf die Schaltfläche Android Studio „Sync Project with Gradle“ (Projekt mit Gradle synchronisieren) Schaltfläche Sync Project with Gradle Files (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 Anwendung auszuführen und sich mit der Benutzeroberfläche vertraut zu machen.

App-Design

Die App ruft eine Liste mit Videos von einem Remote-Webserver ab und stellt eine Liste zur Verfügung, die der Nutzer durchsuchen kann. Nutzer können ein Video auswählen, um die Details aufzurufen, oder das Video lokal auf einem Mobilgerät abspielen.

Die App besteht aus zwei Hauptaktivitäten: VideoBrowserActivity und LocalPlayerActivity. Um die Google Cast-Funktion zu integrieren, müssen die Aktivitäten entweder von der AppCompatActivity oder vom übergeordneten Element FragmentActivity übernommen 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-Supportbibliothek ist von der AppCompat-Supportbibliothek abhängig, die die erforderlichen Klassen bereitstellt.

VideoBrowserActivity

Diese Aktivität enthält ein Fragment (VideoBrowserFragment). Diese Liste wird durch ein ArrayAdapter (VideoListAdapter) gestützt. Die Liste der Videos und die zugehörigen Metadaten werden auf einem Remoteserver als JSON-Datei gehostet. Ein AsyncTaskLoader (VideoItemLoader) ruft diese JSON-Datei ab und verarbeitet sie, 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. MediaItem verfügt also über Dienstprogrammmethoden, mit denen es in ein Bundle-Objekt konvertiert werden kann und umgekehrt.

Wenn das Ladeprogramm die Liste MediaItems erstellt, übergibt es diese Liste an VideoListAdapter, die dann die Liste MediaItems im 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 ein 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 einem Mobilgerät abspielen.

Die Aktivität enthält ein VideoView, einige Mediensteuerelemente und einen Textbereich, in dem die Beschreibung des ausgewählten Videos angezeigt wird. Der Player verdeckt den oberen Teil des Bildschirms und bietet Platz für eine detaillierte Beschreibung des Videos darunter. Der Nutzer kann Videos abspielen/pausieren oder zur lokalen Wiedergabe von Videos spulen.

Abhängigkeiten

Da wir AppCompatActivity verwenden, benötigen wir die AppCompat-Supportbibliothek. Um die Liste der Videos zu verwalten und die Bilder für die Liste asynchron abzurufen, verwenden wir die Volley.

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 Das Cast-Symbol erscheint in der oberen rechten Ecke des Bildschirms.

Auf einer für Google Cast optimierten App wird das Cast-Symbol bei jeder Aktivität angezeigt. Wenn der Nutzer auf das Cast-Symbol klickt, wird eine Liste der Übertragungsgeräte angezeigt, die der Nutzer auswählen kann. Wenn der Nutzer Inhalte lokal auf dem Sendergerät wiedergegeben hat, wird die Wiedergabe auf diesem Übertragungsgerät gestartet oder fortgesetzt, wenn ein Übertragungsgerät ausgewählt wird. Der Nutzer kann während der Übertragung jederzeit auf das Cast-Symbol klicken und die Übertragung Ihrer App auf das Übertragungsgerä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 build.gradle-Datei der App, um die erforderlichen Bibliotheksabhängigkeiten einzuschließen:

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 die Projekt-Builds fehlerfrei sind.

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 ID der Empfänger-App. Sie wird verwendet, um die Ergebnisse der Übertragungsgeräteerkennung zu filtern und die Empfänger-App zu starten, wenn eine Übertragung gestartet wird.

Wenn Sie eine für Google Cast optimierte App entwickeln, müssen Sie sich als Cast-Entwickler registrieren und eine App-ID für Ihre App erhalten. In diesem 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
    }
}

Deklarieren Sie jetzt das OptionsProvider in „application“ Tag 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 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 LocalPlayerActivity dieselbe Initialisierungslogik hinzu.

Cast-Symbol

Nachdem CastContext initialisiert wurde, muss das Cast-Symbol hinzugefügt werden, 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 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 im Menü vor den Einstellungen das Element MediaRouteActionProvider 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"/>

Überschreibe die onCreateOptionsMenu()-Methode von VideoBrowserActivity, indem du CastButtonFactory verwendest, 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 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ähle dein Übertragungsgerät aus. Die Beispiel-Empfänger-App wird auf dem Übertragungsgerät geladen. Sie können zwischen der Suchaktivität und der Aktivität im lokalen Player wechseln. Der Status des Cast-Symbols wird synchronisiert.

Wir haben noch keine Unterstützung für die Medienwiedergabe, daher kannst du noch keine Videos auf dem Übertragungsgerät wiedergeben. Klicken Sie auf das Cast-Symbol, um die Verbindung zu trennen.

6. Streamen von Videoinhalten

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

Wir erweitern die Beispiel-App so, dass Videos auch per Fernzugriff auf Übertragungsgeräten 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 wiedergeben 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 Receiver-App.
  3. Laden Sie das MediaInfo-Objekt in den Receiver und spielen Sie den Inhalt ab.
  4. Beobachten Sie den Medienstatus.
  5. Wiedergabebefehle basierend auf Nutzerinteraktionen an den Empfänger senden

Schritt 2 im vorherigen Abschnitt wurde bereits ausgeführt. Schritt 3 lässt sich mit dem Cast-Framework ganz einfach umsetzen. Schritt 1 ist so, als würden Sie ein Objekt einem anderen zuordnen. MediaInfo versteht das Cast-Framework und MediaItem steht für die Kapselung eines Medienelements durch unsere App. können wir MediaItem ganz einfach MediaInfo zuordnen.

Die Beispiel-App LocalPlayerActivity unterscheidet bereits zwischen lokaler und Remote-Wiedergabe, indem sie diese Aufzählung verwendet:

private var mLocation: PlaybackLocation? = null

enum class PlaybackLocation {
    LOCAL, REMOTE
}

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

In diesem Codelab ist es nicht wichtig, zu verstehen, wie die gesamte Beispiellogik von Playern funktioniert. Beachten Sie, dass der Mediaplayer Ihrer App modifiziert werden muss, damit er die beiden Wiedergabeorte auf ähnliche Weise erkennen kann.

Derzeit ist der lokale Player immer im lokalen Wiedergabestatus, da er noch nichts über den 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. Gleichermaßen müssen wir zur lokalen Wiedergabe wechseln, wenn wir das Streamen beenden, während wir diese Aktivität ausführen. Dazu müssen wir auf die verschiedenen Ereignisse warten, die vom Cast-Framework generiert werden.

Streamingsitzung verwalten

Beim Cast-Framework umfasst eine Cast-Sitzung die Schritte: Verbinden mit einem Gerät, Starten oder Teilnehmen, Herstellen einer Verbindung zu 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.

Das Streamen wird automatisch gestartet, wenn der Nutzer ein Gerät über das Cast-Symbol 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 Sie dem 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()
       }
   }
}

Wir möchten bei den LocalPlayerActivity-Aktivitäten benachrichtigt werden, wenn eine Verbindung mit dem Übertragungsgerät hergestellt oder getrennt wird, damit wir zum oder vom 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:

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

Die RemoteMediaClient im Cast SDK bietet eine Reihe praktischer APIs für die Verwaltung der Remote-Medienwiedergabe auf dem Empfänger. Bei einem CastSession, das die Medienwiedergabe unterstützt, wird vom SDK automatisch eine RemoteMediaClient-Instanz 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 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 nun verschiedene vorhandene Methoden, um die Streaming-Sitzungslogik zu verwenden, um die Remote-Wiedergabe zu unterstützen:

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 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 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 für die aktuelle Übertragungssitzung.

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

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 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 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 beginnt, sollte unten bei jeder Aktivität der Mini-Controller angezeigt werden. Sie können die Remote-Wiedergabe mit dem 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 Design-Checkliste für Google Cast muss eine Absender-App Mediensteuerelemente über eine Benachrichtigung und den Sperrbildschirm implementieren.

Abbildung eines Android-Smartphones mit Mediensteuerelementen im Benachrichtigungsbereich

Das Cast SDK bietet ein MediaNotificationService, mit dem die Absender-App Mediensteuerelemente für Benachrichtigungen und Sperrbildschirm erstellen kann. Der Dienst wird automatisch mit Gradle in das Manifest Ihrer App eingefügt.

MediaNotificationService wird im Hintergrund ausgeführt, während der Absender Inhalte streamt, und zeigt eine Benachrichtigung mit einer Miniaturansicht des Bildes und Metadaten zum aktuellen Streamingelement sowie eine Schaltfläche für Wiedergabe/Pause und eine Stopp-Schaltfläche an.

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

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 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 vorhanden sein, das gerade auf dem Receiver 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 Mediensteuerelementen auf dem Sperrbildschirm

9. Einleitendes Overlay

Gemäß der Checkliste für das Google Cast-Design muss eine Absender-App bestehenden Nutzern das Cast-Symbol vorstellen, um sie darüber zu informieren, dass die Sender-App jetzt das Streamen unterstützt und auch Neulingen von Google Cast hilft.

Darstellung des einführenden Cast-Overlays um das Cast-Symbol in der Android-App für Videos streamen

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 nun ein CastStateListener hinzu und rufen Sie die Methode showIntroductoryOverlay auf, wenn ein Übertragungsgerät verfügbar ist. Ändern Sie dazu die Methode onCreate und überschreiben Sie die Methoden onResume und onPause entsprechend:

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ösche die App-Daten oder entferne die App von deinem 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ührende Overlay zu sehen sein. 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 Absender-App einen erweiterten Controller für die gestreamten Medien bereitstellen. Der erweiterte Controller ist eine Vollbildversion des Mini-Controllers.

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, über die der erweiterte Controller das Cast-Symbol bereitstellen kann:

<?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 jetzt das ExpandedControlsActivity im AndroidManifest.xml im application-Tag ü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, damit 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())
}

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

11. Cast Connect-Unterstützung hinzufügen

Mithilfe der Cast Connect-Bibliothek können bestehende Absender-Apps über das Cast-Protokoll mit Android TV-Apps 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

Zum Starten der Android TV App, die auch als Android-Receiver bezeichnet wird, müssen wir das setAndroidReceiverCompatible-Flag im LaunchOptions-Objekt auf „true“ setzen. Dieses LaunchOptions-Objekt legt fest, wie der Empfänger gestartet wird, und wird an das CastOptions übergeben, das von der Klasse CastOptionsProvider zurückgegeben wird. Wenn du das oben genannte Flag auf false setzt, wird der Web Receiver für die in der Cast Developer Console angegebene App-ID 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, sofern die ATV-App ihn lesen kann. Die CredentialsData wird nur während des Starts oder der Teilnahme an deiner Android TV App übergeben. Wenn Sie die Einstellung neu festlegen, während eine Verbindung besteht, wird sie nicht an Ihre Android TV App übergeben.

Zum Festlegen von Startanmeldedaten 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 wird getestet

Schritte zur Installation des Android TV APK auf Chromecast mit Google TV

  1. Ermitteln Sie die IP-Adresse Ihres Android TV-Geräts. Normalerweise befindet sich die Option unter Einstellungen > Netzwerk und Internet > (Netzwerkname, 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 des Geräts, um über ADB mit dem Terminal eine Verbindung zu ihm herzustellen:
$ adb connect <device_ip_address>:5555
  1. Gehen Sie im Terminalfenster zum Ordner der obersten Ebene für die Codelab-Beispiele, die Sie zu Beginn dieses Codelabs heruntergeladen haben. Beispiel:
$ cd Desktop/android_codelab_src
  1. Installiere die APK-Datei aus diesem Ordner auf deinem Android TV mit folgendem Befehl:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. Sie sollten jetzt auf Ihrem Android TV-Gerät im Menü Meine Apps eine App mit dem Namen Videos streamen finden.
  2. Kehren Sie zu Ihrem Android Studio-Projekt zurück und klicken Sie auf die Schaltfläche Run, um die App zu installieren und die Absender-App auf Ihrem Mobilgerät ausführen. Klicken Sie rechts oben auf das Cast-Symbol und wählen Sie aus den verfügbaren Optionen Ihr Android TV-Gerät aus. Die Android TV App sollte jetzt auf Ihrem Android TV-Gerät gestartet werden. Abspielen eines Videos sollte es Ihnen möglich sein, die Videowiedergabe mit Ihrer Android TV-Fernbedienung zu steuern.

12. Cast-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 Arten von Schaltflächen 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

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

Weitere Informationen finden Sie im Android Sender-Entwicklerleitfaden.