Android-App für Google Cast aktivieren

Mit Sammlungen den Überblick behalten Sie können Inhalte basierend auf Ihren Einstellungen speichern und kategorisieren.

1. Übersicht

Logo: Google Cast

In diesem Codelab erfahren Sie, wie Sie eine vorhandene Android-Video-App so ändern, dass Inhalte auf ein Google Cast-fähiges Gerät gestreamt werden.

Was ist Google Cast?

Mit Google Cast können Nutzer Inhalte von einem Mobilgerät auf einen Fernseher streamen. Nutzer können ihr Mobilgerät dann 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 Checkliste für das Google Cast-Design hinzufügen.

Die Checkliste für das Google Cast-Design soll dafür sorgen, dass Cast auf allen unterstützten Plattformen einfach und vorhersehbar funktioniert.

Ziele

Wenn du dieses Codelab abgeschlossen hast, kannst du mit einer Android-Video-App Videos auf ein für Google Cast optimiertes Gerät streamen.

Lerninhalte

  • So fügen Sie das Google Cast SDK einer Beispielvideo-App hinzu
  • So fügen Sie das Cast-Symbol zum Auswählen eines Google Cast-Geräts hinzu
  • Eine Verbindung zu einem Übertragungsgerät herstellen und einen Medienempfänger starten
  • Ein Video streamen
  • So fügen Sie Ihrer App einen Cast Mini-Controller hinzu
  • Hier erfährst du, wie du Medienbenachrichtigungen und die Sperrbildschirm-Unterstützung unterstützt.
  • So fügen Sie einen erweiterten Controller hinzu.
  • Einführungs-Overlay bereitstellen
  • Cast-Widgets anpassen
  • Integration in Cast Connect

Voraussetzungen

  • Das neueste Android SDK.
  • Android Studio 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 Ihrem Entwicklungscomputer
  • Ein Google Cast-Gerät wie Chromecast oder Android TV, das mit Internetzugang konfiguriert ist.
  • Ein 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 dies optional. Wenn Sie keine haben, können Sie den Schritt Support für Cast Connect hinzufügen am Ende dieser Anleitung überspringen.

Plattform

  • Dafür benötigen Sie Erfahrung mit Kotlin und Android-Entwicklung.
  • Außerdem benötigst du Vorkenntnisse zum Fernsehen.

Wie verwenden Sie diese Anleitung?

Nur durchlesen Lies dir die Übungen durch

Wie würden Sie Ihre Erfahrungen im Erstellen von Android-Apps bewerten?

Anfänger Fortgeschritten Profi

Wie würdest du deine Erfahrung mit dem 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 von zwei Kompassen

Sehen wir uns zuerst an, wie die ausgefüllte 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, können Sie die folgende Beispiel-App in Android Studio öffnen und ausführen:

Wählen Sie auf dem Willkommensbildschirm die Option Import Project (Projekt importieren) oder die Menüoption File > New > Import Project... aus.

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

Klicken Sie auf File >Android Studio-Schaltfläche & Projekt mit Gradle synchronisieren Sync Project with Gradle Files.

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

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

Klicken Sie in der Video-App auf das Cast-Symbol und wählen Sie Ihr 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 abgespielt.

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

Zurück zur Videoliste.

Unten auf dem Bildschirm ist jetzt ein Minicontroller zu sehen. Abbildung eines Android-Smartphones, auf dem die App „Videos streamen“ läuft. Der Minicontroller wird unten auf dem Bildschirm angezeigt.

Klicke auf die Pause-Taste im Mini-Controller, um das Video auf dem Empfänger zu pausieren. Klicke auf die Wiedergabeschaltfläche im Mini-Controller, um die Wiedergabe des Videos fortzusetzen.

Klicken Sie auf die Schaltfläche für die Startseite des Mobilgeräts. Benachrichtigungen werden geöffnet. Sie sollten jetzt eine Benachrichtigung für die Übertragung sehen.

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

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

Häufig gestellte Fragen

4. Startprojekt vorbereiten

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

Wir müssen die heruntergeladene Start-App für Google Cast unterstützen. Im Folgenden finden Sie einige Begriffe von Google Cast, die wir in diesem Codelab verwenden werden:

  • eine Absender-App auf einem Mobilgerät oder Laptop ausgeführt wird,
  • 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 Beispielcode aus. Wählen Sie dazu auf dem Willkommensbildschirm Import Project (Projekt importieren) oder die Menüoption File > New > Import Project... (Datei importieren & neu; Projekt importieren...) aus.
  2. Klicken Sie auf die Schaltfläche Android Studio-Schaltfläche & Projekt mit Gradle synchronisieren Synchronisierungsprojekt mit Gradle-Dateien.
  3. Klicken Sie auf die Schaltfläche Android Studio-Schaltfläche „Ausführen“, ein grünes Dreieck, das nach rechts zeigtAusführen, um die App auszuführen und die Benutzeroberfläche kennenzulernen.

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 sich die Details anzusehen, oder das Video lokal auf dem Mobilgerät abspielen.

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

VideoBrowserActivity

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

Ein MediaItem-Objekt modelliert ein Video und die zugehörigen Metadaten, wie 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. In MediaItem gibt es daher Dienstprogrammen, mit denen es in ein Bundle konvertiert werden kann und umgekehrt.

Wenn der Lader die Liste MediaItems erstellt, übergibt sie diese Liste an VideoListAdapter, wodurch die Liste MediaItems in VideoBrowserFragment angezeigt wird. Dem Nutzer wird eine Liste mit 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.

Lokale Spieleraktivität

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

In der Aktivität werden ein VideoView, einige Mediensteuerelemente und ein Textbereich für die Beschreibung des ausgewählten Videos gehostet. Der Player verdeckt den oberen Teil des Bildschirms. So bleibt Platz für die detaillierte Beschreibung des Videos darunter. Der Nutzer kann die Videos abspielen/pausieren oder zur lokalen Wiedergabe zurückkehren.

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 Bibliothek Vollständigy.

Häufig gestellte Fragen

5. Cast-Symbol hinzufügen

Illustration des oberen Bereichs eines Android-Smartphones, auf dem die Cast Video App ausgeführt wird. Das Cast-Symbol wird oben rechts auf dem Bildschirm angezeigt.

Für Google Cast optimierte Apps zeigen bei jeder Aktivität das Cast-Symbol an. Wenn Nutzer auf das Cast-Symbol klicken, wird eine Liste der Übertragungsgeräte angezeigt, die der Nutzer auswählen kann. Wenn der Nutzer Inhalte lokal auf dem Gerät des Absenders abgespielt hat, wird durch Auswahl eines Übertragungsgeräts die Wiedergabe auf diesem Übertragungsgerät gestartet oder fortgesetzt. Der Nutzer kann jederzeit während einer Streamingsitzung auf das Cast-Symbol klicken und die Übertragung Ihrer App an das Cast-Gerät beenden. Der Nutzer muss während einer beliebigen Aktivität Ihrer App in der Lage sein, eine Verbindung zum Cast-Gerät herzustellen bzw. zu trennen, wie in der Google Cast-Design-Checkliste beschrieben.

Abhängigkeiten

Aktualisieren Sie die Datei build.gradle der App, sodass sie die erforderlichen Bibliotheksabhängigkeiten enthält:

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 bestätigen, dass es fehlerfrei erstellt wird.

Initialisierung

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

Sie müssen die Schnittstelle OptionsProvider implementieren, um den CastOptions bereitzustellen, der zur Initialisierung des CastContext-Singleton benötigt wird. Die wichtigste Option ist die Empfänger-App-ID, mit der die Ergebnisse der Cast-Geräteerkennung gefiltert und die Empfängeranwendung gestartet werden, wenn eine Cast-Sitzung gestartet wird.

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

Deklarieren Sie jetzt OptionsProvider im Tag &application der App-Datei AndroidManifest.xml:

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

Initialisieren Sie CastContext mit 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 die gleiche Initialisierungslogik hinzu.

Cast-Symbol

Nachdem die 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 über ActionBar oder Toolbar zu Ihren Aktivitäten 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 Elementen die Einstellungen 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"/>

Überschreiben Sie die Methode onCreateOptionsMenu() von VideoBrowserActivity mit CastButtonFactory, um das 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 Android Studio-Schaltfläche „Ausführen“, ein grünes Dreieck, das nach rechts zeigtAusführen, um die App auf Ihrem Mobilgerät auszuführen. In der Aktionsleiste der App sollten Sie ein Cast-Symbol sehen. Wenn Sie darauf klicken, werden die Cast-Geräte in Ihrem lokalen Netzwerk aufgelistet. Die Geräteerkennung wird automatisch von CastContext verwaltet. Wählen Sie Ihr Übertragungsgerät aus. Die Beispiel-Empfänger-App wird dann auf dem Übertragungsgerät geladen. Sie können zwischen der Browser- und der lokalen Playeraktivität wechseln. Der Cast-Status wird dabei synchronisiert.

Die Medienwiedergabe ist noch nicht verfügbar, sodass Sie noch keine Videos auf dem Übertragungsgerät abspielen können. Klicke auf das Cast-Symbol, um die Verbindung zu trennen.

6. Streamen von Videoinhalten

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

Wir erweitern die Beispiel-App, damit du auch Videos per Remotezugriff auf einem Übertragungsgerät abspielen kannst. Dazu müssen wir die verschiedenen Ereignisse im Cast-Framework beobachten.

Medien streamen

Wenn Sie Medien auf einem Übertragungsgerät abspielen möchten, müssen Sie Folgendes tun:

  1. Erstellen Sie ein MediaInfo-Objekt, das ein Mediaplan modelliert.
  2. Stellen Sie eine Verbindung zum Cast-Gerät her und starten Sie die Empfängeranwendung.
  3. Laden Sie das Objekt MediaInfo in Ihren Receiver und spielen Sie den Inhalt ab.
  4. Verfolgen Sie den Medienstatus.
  5. Sende basierend auf Nutzerinteraktionen Wiedergabebefehle an den Empfänger.

Wir haben Schritt 2 bereits im vorherigen Abschnitt ausgeführt. Schritt 3 ist mit dem Cast-Framework ganz einfach. Schritt 1 ist die Zuordnung eines Objekts zum anderen; MediaInfo ist etwas, das vom Cast-Framework verstanden wird, und MediaItem ist die Kapselung unserer App für ein Mediaelement. Wir können ein MediaItem einfach einem MediaInfo zuordnen.

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

private var mLocation: PlaybackLocation? = null

enum class PlaybackLocation {
    LOCAL, REMOTE
}

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

In diesem Codelab ist es nicht wichtig, dass du genau verstehst, wie die gesamte Beispiellogik funktioniert. Es ist wichtig zu verstehen, dass der Mediaplayer deiner App so angepasst werden muss, dass die beiden Wiedergabeorte ähnlich erkannt werden.

Im Moment ist der lokale Player immer im lokalen Wiedergabestatus, da er noch nichts über den Streaming-Status weiß. Wir müssen die Benutzeroberfläche basierend auf Statusübergängen aktualisieren, die im Cast-Framework erfolgen. Wenn wir beispielsweise mit dem Streamen beginnen, müssen wir die lokale Wiedergabe beenden und einige Steuerelemente deaktivieren. Wenn wir das Streaming beenden, während wir uns in dieser Aktivität befinden, müssen wir zur lokalen Wiedergabe übergehen. Dazu müssen wir die verschiedenen Ereignisse im Cast-Framework beobachten.

Cast-Sitzungsverwaltung

Beim Cast-Framework werden bei einer Cast-Sitzung die folgenden Schritte durchgeführt: Verbinden mit einem Gerät, Starten (oder Teilnehmen) des Geräts, Verbinden mit einer Empfängeranwendung und Initialisieren eines Mediensteuerungskanals (falls zutreffend). Über den Mediensteuerungskanal wird festgelegt, wie das Cast-Framework Nachrichten vom Mediaplayer des Empfängers sendet und empfängt.

Die Streamingsitzung wird automatisch gestartet, wenn der Nutzer ein Gerät über die Cast-Schaltfläche auswählt, und automatisch beendet, wenn der Nutzer die Verbindung trennt. Die Verbindung mit einer Empfängersitzung aufgrund von Netzwerkproblemen wird ebenfalls automatisch vom Cast SDK verarbeitet.

Fügen Sie dem 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()
       }
   }
}

Bei Aktivitäten in LocalPlayerActivity sind wir interessiert, wenn wir eine Verbindung zum Cast-Gerät herstellen oder trennen, damit wir zum lokalen Player wechseln können. Beachten Sie, dass die Verbindung nicht nur durch die Instanz Ihrer Anwendung unterbrochen werden kann, die auf Ihrem Mobilgerät ausgeführt wird, sondern auch durch eine andere Instanz Ihrer (oder eine andere) Anwendung, die auf einem anderen Mobilgerät ausgeführt wird.

Die aktuell aktive Sitzung kann als SessionManager.getCurrentSession() aufgerufen werden. Sitzungen werden automatisch erstellt und gelöscht, wenn Nutzer mit dem Cast-Dialogfeld 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 so:

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

private var mCastContext: CastContext? = null
...

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

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

Medien werden geladen

Im Cast SDK bietet die RemoteMediaClient eine Reihe von praktischen APIs für die Verwaltung der Remote-Medienwiedergabe auf dem Empfänger. Für eine CastSession, die die Medienwiedergabe unterstützt, wird vom SDK automatisch eine Instanz von RemoteMediaClient erstellt. Der Zugriff erfolgt über die Methode getRemoteMediaClient() in der Instanz CastSession. Füge die folgenden Methoden zu LocalPlayerActivity 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()
    }
}

Aktualisieren Sie nun verschiedene vorhandene Methoden, um die Remote-Wiedergabe mit der Logik der Cast-Sitzung 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 jetzt auf die Schaltfläche Android Studio-Schaltfläche „Ausführen“, ein grünes Dreieck, das nach rechts zeigtAusführen, um die App auf Ihrem Mobilgerät auszuführen. Stelle eine Verbindung zu deinem Übertragungsgerät her und starte die Wiedergabe eines Videos. Sie sollten das Video auf dem Empfänger sehen.

7. Mini-Controller

Für die Checkliste für das Cast-Design muss in allen Cast-Apps ein Mini-Controller verfügbar sein, 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 Streamingsitzung.

Illustration eines unteren Teils eines Android-Smartphones, auf dem der Miniplayer in der App „Videos streamen“ zu sehen ist

Das Cast SDK bietet eine benutzerdefinierte Ansicht, MiniControllerFragment, die in die App-Layoutdatei der Aktivitäten aufgenommen werden kann, in denen der Minicontroller angezeigt werden soll.

Fügen Sie unten in 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 Android Studio-Schaltfläche „Ausführen“, 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 am unteren Rand jeder Aktivität ein Minicontroller angezeigt werden. Sie können die Wiedergabe über den Mini-Controller steuern. Wenn Sie zwischen der Browseraktivität und der lokalen Playeraktivität wechseln, sollte der Status des Minicontrollers mit dem Medienwiedergabestatus des Empfängers übereinstimmen.

8. Benachrichtigung und Sperrbildschirm

Für die Checkliste für das Google Cast-Design muss eine Absender-App Mediensteuerelemente über eine Benachrichtigung und den Sperrbildschirm implementieren.

Abbildung eines Android-Smartphones mit Mediensteuerelementen im Benachrichtigungsbereich

Das Cast SDK bietet einen MediaNotificationService, mit dem die Absender-App Mediensteuerelemente für die Benachrichtigung und den Sperrbildschirm erstellen kann. Der Dienst wird von Gradle automatisch in das Manifest Ihrer App zusammengeführt.

MediaNotificationService wird beim Streamen im Hintergrund ausgeführt. Außerdem werden eine Benachrichtigung mit einer Bild-Miniaturansicht und Metadaten zum aktuellen Übertragungselement, einer Wiedergabe-/Pause-Schaltfläche und einer Stopp-Schaltfläche angezeigt.

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

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

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 Android Studio-Schaltfläche „Ausführen“, 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 angezeigt werden, das gerade auf dem Empfänger wiedergegeben wird. Sperren Sie Ihr Mobilgerät und auf dem Sperrbildschirm sollten jetzt Steuerelemente für die Medienwiedergabe auf dem Übertragungsgerät angezeigt werden.

Abbildung eines Android-Smartphones mit Mediensteuerelementen auf dem Sperrbildschirm

9. Einführungs-Overlay

In der Checkliste zum Google Cast-Design muss eine Absender-App das Cast-Symbol bei bestehenden Nutzern einführen, um sie darauf hinzuweisen, dass die Absender-App jetzt das Streamen unterstützt und auch Nutzer unterstützt, die neu bei Google Cast sind.

Abbildung mit dem Cast-Overlay, das in der Android-App „Cast-Videos“ auf das Cast-Symbol verweist

Das Cast SDK bietet eine benutzerdefinierte Ansicht, IntroductoryOverlay, mit der Sie das Cast-Symbol hervorheben können, wenn es Nutzern zum ersten Mal angezeigt wird. Fügen Sie VideoBrowserActivity den folgenden Code hinzu:

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

private var mIntroductoryOverlay: IntroductoryOverlay? = null

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

Fügen Sie jetzt 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 so:

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

private var mCastStateListener: CastStateListener? = null

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

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

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

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

10. Maximierter Controller

In der Checkliste für das Google Cast-Design muss eine Absender-App einen maximierten Controller für die gestreamten Medien bereitstellen. Der maximierte Controller ist eine Vollbildversion des Mini-Controllers.

Illustration eines Videos, das auf einem Android-Smartphone abgespielt wird, auf dem der Controller maximiert ist

Das Cast SDK enthält ein Widget für den erweiterten Controller mit dem Namen ExpandedControllerActivity. Dies ist eine abstrakte Klasse, die Sie benötigen, um eine Unterklasse hinzuzufügen.

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 jetzt ExpandedControlsActivity in 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 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 beim Laden des Remote-Medien angezeigt wird:

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 Android Studio-Schaltfläche „Ausführen“, ein grünes Dreieck, das nach rechts zeigtAusführen, um die App auf Ihrem Mobilgerät auszuführen und ein Video zu streamen. Sie sollten den erweiterten Controller sehen. Wenn Sie zur Liste der Videos zurückkehren, wird der maximierte Controller wieder geladen. Verlassen Sie 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

Über die Cast Connect-Bibliothek können bestehende Absenderanwendungen mit Android TV-Apps über das Cast-Protokoll kommunizieren. Cast Connect baut auf der Cast-Infrastruktur auf und die Android TV App fungiert als Empfänger.

Abhängigkeiten

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

Startoptionen

Zum Starten der Android TV-App, die auch als Android Receiver bezeichnet wird, muss das Flag setAndroidReceiverCompatible im Objekt LaunchOptions auf „true“ gesetzt werden. Dieses LaunchOptions-Objekt gibt an, wie der Empfänger gestartet wird, und wird an die CastOptions übergeben, die von der Klasse CastOptionsProvider zurückgegeben wird. Wenn Sie das oben genannte Flag auf false setzen, wird der Webempfänger für die definierte App-ID in der Cast Developer Console gestartet.

Fügen Sie in der Datei CastOptionsProvider.kt Folgendes zur Methode getCastOptions 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 Absenderseite können Sie CredentialsData angeben, um anzugeben, wer an der Sitzung teilnimmt. credentials ist ein String, der vom Nutzer definiert werden kann, solange Ihre ATV-App sie verstehen kann. CredentialsData wird nur während der Einführung oder beim Beitritt an deine Android TV App übergeben. Wenn du sie später noch einmal verbindest, wird sie nicht an deine Android TV App weitergegeben.

Zum Festlegen von Anmeldedaten muss CredentialsData definiert und an das Objekt LaunchOptions ü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

Wenn deine Web Receiver App und deine Android TV App credentials unterschiedlich verarbeiten, musst du für jeden eine eigene credentials definieren. Fügen Sie dazu in der Datei LocalPlayerActivity.kt unter der Funktion loadRemoteMedia den folgenden Code ein:

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

Je nachdem, an welche Empfänger-App Ihr Absender streamt, verarbeitet das SDK automatisch, welche Anmeldedaten für die aktuelle Sitzung verwendet werden sollen.

Cast Connect wird getestet

Android TV-APK auf Chromecast mit Google TV installieren

  1. Suchen Sie die IP-Adresse Ihres Android TV-Geräts. Sie finden sie in der Regel unter Einstellungen > Netzwerk > Internetname des Geräts. Auf der rechten Seite werden die Details und die IP-Adresse Ihres Geräts im Netzwerk angezeigt.
  2. Verwenden Sie die IP-Adresse für Ihr Gerät, um über ADB eine Verbindung über das Terminal herzustellen:
$ adb connect <device_ip_address>:5555
  1. Gehen Sie im Terminalfenster zum Ordner auf oberster Ebene für die Codelab-Beispiele, die Sie zu Beginn dieses Codelabs heruntergeladen haben. Beispiel:
$ cd Desktop/android_codelab_src
  1. Installieren Sie die APK-Datei in diesem Ordner auf Ihrem Android TV-Gerät:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. Sie sollten jetzt auf Ihrem Android TV-Gerät im Menü Meine Apps den Namen Videos streamen sehen.
  2. Kehren Sie zu Ihrem Android Studio-Projekt zurück und klicken Sie auf die Schaltfläche „Ausführen“, um die Absender-App auf Ihrem Mobilgerät zu installieren. 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. Wenn Sie ein Video abspielen, sollten Sie die Wiedergabe über die Android TV-Fernbedienung steuern können.

12. Cast-Widgets anpassen

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

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 Entwicklerleitfaden Android Sender.