In diesem Leitfaden wird beschrieben, wie Sie die Funktion „Weiter ansehen“ mithilfe des Engage SDK in Ihre Android TV-App einbinden.
Vorarbeit
Führen Sie die Schritte im Abschnitt Vorbereitung des Startleitfadens aus.
Integration
Entitäten erstellen
Im SDK sind verschiedene Entitäten definiert, die die einzelnen Artikeltypen darstellen. Der Fortsetzungscluster unterstützt die folgenden Entitäten:
Geben Sie die plattformspezifischen URIs und Posterbilder für diese Entitäten an.
Erstellen Sie außerdem Wiedergabe-URIs für jede Plattform, z. B. Android TV, Android oder iOS, falls Sie dies noch nicht getan haben. Wenn ein Nutzer also auf einer Plattform weitersieht, verwendet die App einen gezielten Wiedergabe-URI, um den Videoinhalt abzuspielen.
// Required. Set this when you want continue watching entities to show up on
// Google TV
val playbackUriTv = PlatformSpecificUri.Builder()
.setPlatformType(PlatformType.TYPE_ANDROID_TV)
.setActionUri(Uri.parse("https://www.example.com/entity_uri_for_tv"))
.build()
// Required. Set this when you want continue watching entities to show up on
// Google TV Android app, Entertainment Space, Playstore Widget
val playbackUriAndroid = PlatformSpecificUri.Builder()
.setPlatformType(PlatformType.TYPE_ANDROID_MOBILE)
.setActionUri(Uri.parse("https://www.example.com/entity_uri_for_android"))
.build()
// Optional. Set this when you want continue watching entities to show up on
// Google TV iOS app
val playbackUriIos = PlatformSpecificUri.Builder()
.setPlatformType(PlatformType.TYPE_IOS)
.setActionUri(Uri.parse("https://www.example.com/entity_uri_for_ios"))
.build()
val platformSpecificPlaybackUris =
Arrays.asList(playbackUriTv, playbackUriAndroid, playbackUriIos)
Für Posterbilder sind ein URI und Pixelabmessungen (Höhe und Breite) erforderlich. Wenn du verschiedene Formfaktoren ansprechen möchtest, kannst du mehrere Posterbilder bereitstellen. Achte aber darauf, dass alle Bilder ein Seitenverhältnis von 16:9 und eine Mindesthöhe von 200 Pixeln haben, damit die Entität „Weiter ansehen“ korrekt angezeigt wird, insbesondere im Entertainment Space von Google. Bilder mit einer Höhe von weniger als 200 Pixeln werden möglicherweise nicht angezeigt.
val images = Arrays.asList(
Image.Builder()
.setImageUri(Uri.parse("http://www.example.com/entity_image1.png"))
.setImageHeightInPixel(300)
.setImageWidthInPixel(169)
.build(),
Image.Builder()
.setImageUri(Uri.parse("http://www.example.com/entity_image2.png"))
.setImageHeightInPixel(640)
.setImageWidthInPixel(360)
.build()
// Consider adding other images for different form factors
)
MovieEntity
In diesem Beispiel wird gezeigt, wie Sie einen MovieEntity mit allen erforderlichen Feldern erstellen:
val movieEntity = MovieEntity.Builder()
.setWatchNextType(WatchNextType.TYPE_CONTINUE)
.setName("Movie name")
.addPlatformSpecificPlaybackUris(platformSpecificPlaybackUris)
.addPosterImages(images)
// Timestamp in millis for sample last engagement time 12/1/2023 00:00:00
.setLastEngagementTimeMillis(1701388800000)
// Suppose the duration is 2 hours, it is 72000000 in milliseconds
.setDurationMillis(72000000)
// Suppose last playback offset is 1 hour, 36000000 in milliseconds
.setLastPlayBackPositionTimeMillis(36000000)
.setCallToActionText("Resume")
.addTag("Action")
.build()
Wenn du Details wie Genres und Altersfreigaben angibst, kann Google TV deine Inhalte dynamischer präsentieren und den richtigen Zuschauern zeigen.
val genres = Arrays.asList("Action", "Science fiction")
val rating1 = RatingSystem.Builder().setAgencyName("MPAA").setRating("PG-13").build()
val contentRatings = Arrays.asList(rating1)
val movieEntity = MovieEntity.Builder()
...
.addGenres(genres)
.addContentRatings(contentRatings)
.build()
Entitäten bleiben automatisch 60 Tage lang verfügbar, sofern Sie keine kürzere Ablaufzeit angeben. Legen Sie nur dann einen benutzerdefinierten Ablauf fest, wenn die Entität vor diesem Standardzeitraum entfernt werden muss.
// Set the expiration time to be now plus 30 days in milliseconds
val expirationTime = DisplayTimeWindow.Builder()
.setEndTimestampMillis(now().toMillis()+2592000000).build()
val movieEntity = MovieEntity.Builder()
...
.addAvailabilityTimeWindow(expirationTime)
.build()
TvEpisodeEntity
In diesem Beispiel wird gezeigt, wie Sie einen TvEpisodeEntity mit allen erforderlichen Feldern erstellen:
val tvEpisodeEntity = TvEpisodeEntity.Builder()
.setWatchNextType(WatchNextType.TYPE_CONTINUE)
.setName("Episode name")
.addPlatformSpecificPlaybackUris(platformSpecificPlaybackUris)
.addPosterImages(images)
// Timestamp in millis for sample last engagement time 12/1/2023 00:00:00
.setLastEngagementTimeMillis(1701388800000)
.setDurationMillis(72000000) // 2 hours in milliseconds
// 45 minutes and 15 seconds in milliseconds is 2715000
.setLastPlayBackPositionTimeMillis(2715000)
.setEpisodeNumber("2")
.setSeasonNumber("1")
.setShowTitle("Title of the show")
.setCallToActionText("Resume")
.addTag("Comedy")
.build()
Der String für die Folgennummer (z. B. "2") und der String für die Staffelnummer (z. B. "1") werden in das richtige Format erweitert, bevor sie auf der Karte „Weiter ansehen“ angezeigt werden. Beachte, dass es sich um einen numerischen String handeln muss. Gib nicht „e2“, „Folge 2“, „s1“ oder „Staffel 1“ ein.
Wenn eine bestimmte Serie nur eine Staffel hat, lege die Staffelnummer auf „1“ fest.
Wenn du die Wahrscheinlichkeit erhöhen möchtest, dass Zuschauer deine Inhalte auf Google TV finden, solltest du zusätzliche Daten wie Genres, Altersfreigaben und Verfügbarkeitszeiträume angeben. Diese Details können die Darstellung und die Filteroptionen verbessern.
val genres = Arrays.asList("Action", "Science fiction")
val rating1 = RatingSystem.Builder().setAgencyName("MPAA").setRating("PG-13").build()
val contentRatings = Arrays.asList(rating1)
val tvEpisodeEntity = TvEpisodeEntity.Builder()
...
.addGenres(genres)
.addContentRatings(contentRatings)
.setSeasonTitle("Season Title")
.setShowTitle("Show Title")
.build()
VideoClipEntity
Hier ist ein Beispiel für das Erstellen eines VideoClipEntity mit allen erforderlichen Feldern.
VideoClipEntity steht für einen von Nutzern erstellten Clip, z. B. ein YouTube-Video.
val videoClipEntity = VideoClipEntity.Builder()
.setPlayBackUri(Uri.parse("https://www.example.com/uri_for_current_platform"))
.setWatchNextType(WatchNextType.TYPE_CONTINUE)
.setName("Video clip name")
.addPlatformSpecificPlaybackUris(platformSpecificPlaybackUris)
.addPosterImages(images)
// Timestamp in millis for sample last engagement time 12/1/2023 00:00:00
.setLastEngagementTimeMillis(1701388800000)
.setDurationMillis(600000) //10 minutes in milliseconds
.setLastPlayBackPositionTimeMillis(300000) //5 minutes in milliseconds
.setCallToActionText("Resume")
.addTag("Vlog")
.build()
Optional können Sie den Ersteller, das Erstellerbild, die Erstellungszeit in Millisekunden oder das Verfügbarkeitszeitfenster festlegen .
LiveStreamingVideoEntity
Hier ist ein Beispiel für das Erstellen eines LiveStreamingVideoEntity mit allen erforderlichen Feldern.
val liveStreamingVideoEntity = LiveStreamingVideoEntity.Builder()
.setPlayBackUri(Uri.parse("https://www.example.com/uri_for_current_platform"))
.setWatchNextType(WatchNextType.TYPE_CONTINUE)
.setName("Live streaming name")
.addPlatformSpecificPlaybackUris(platformSpecificPlaybackUris)
.addPosterImages(images)
// Timestamp in millis for sample last engagement time 12/1/2023 00:00:00
.setLastEngagementTimeMillis(1701388800000)
.setLastPlayBackPositionTimeMillis(36000000) //1 hour in milliseconds
.addContentRating(contentRating)
.setCallToActionText("Resume")
.addTag("Live")
.build()
Optional können Sie die Startzeit, den Sender, das Sender-Symbol oder das Verfügbarkeitszeitfenster für die Livestreaming-Entität festlegen.
Ausführliche Informationen zu Attributen und Anforderungen finden Sie in der API-Referenz.
Daten zum Fortsetzungscluster angeben
AppEngagePublishClient ist für die Veröffentlichung des Fortsetzungsclusters verantwortlich.
Mit der Methode publishContinuationCluster veröffentlichen Sie ein ContinuationCluster-Objekt.
Initialisieren Sie den Client und prüfen Sie die Dienstverfügbarkeit, wie im Startleitfaden beschrieben.
client.publishContinuationCluster(
PublishContinuationClusterRequest
.Builder()
.setContinuationCluster(
ContinuationCluster.Builder()
.setAccountProfile(accountProfile)
.addEntity(movieEntity1)
.addEntity(movieEntity2)
.addEntity(tvEpisodeEntity1)
.addEntity(tvEpisodeEntity2)
.setSyncAcrossDevices(true)
.build()
)
.build()
)
Wenn der Dienst die Anfrage empfängt, werden die folgenden Aktionen innerhalb einer Transaktion ausgeführt:
- Vorhandene
ContinuationCluster-Daten des Entwicklerpartners werden entfernt. - Die Daten aus der Anfrage werden geparst und im aktualisierten
ContinuationClustergespeichert.
Bei einem Fehler wird die gesamte Anfrage abgelehnt und der vorhandene Status beibehalten.
Die Veröffentlichungs-APIs sind Upsert-APIs, die den vorhandenen Inhalt ersetzen. Wenn Sie eine bestimmte Entität im Fortsetzungscluster aktualisieren müssen, müssen Sie alle Entitäten noch einmal veröffentlichen.
Daten zu Fortsetzungsclustern sollten nur für Konten von Erwachsenen bereitgestellt werden. Veröffentlichen Sie nur, wenn das Kontoprofil einem Erwachsenen gehört.
Geräteübergreifende Synchronisierung
setSyncAcrossDevices steuert, ob die ContinuationCluster-Daten eines Nutzers auf Geräten wie Fernsehern, Smartphones, Tablets usw. synchronisiert werden. Die geräteübergreifende Synchronisierung ist standardmäßig deaktiviert.
Werte:
true: Daten zu Fortsetzungsclustern werden auf allen Geräten des Nutzers geteilt, um eine nahtlose Wiedergabe zu ermöglichen. Wir empfehlen diese Option dringend, um die beste geräteübergreifende Nutzung zu ermöglichen.false: Fortsetzungsclusterdaten sind auf das aktuelle Gerät beschränkt.
Außerdem musst du eine AccountProfile mit einer Konto-ID angeben, damit die Inhalte zwischen Geräten synchronisiert werden können. Weitere Informationen finden Sie unter Kontoprofil erstellen.
Einwilligung einholen
Die Medien-App muss eine klare Einstellung zum Aktivieren oder Deaktivieren der geräteübergreifenden Synchronisierung bieten. Erläutere dem Nutzer die Vorteile, speichere seine Einstellung einmal und wende sie in publishContinuationCluster entsprechend an.
// Example to allow cross device syncing.
client.publishContinuationCluster(
PublishContinuationClusterRequest
.Builder()
.setContinuationCluster(
ContinuationCluster.Builder()
.setAccountProfile(accountProfile)
.setSyncAcrossDevices(true)
.build()
)
.build()
)
Damit Sie die geräteübergreifende Funktion optimal nutzen können, müssen Sie die Nutzereinwilligung einholen und SyncAcrossDevices auf true festlegen. So können Inhalte nahtlos auf allen Geräten synchronisiert werden, was zu einer besseren Nutzererfahrung und mehr Interaktionen führt. Ein Partner, der diese Funktion implementiert hat, verzeichnete beispielsweise einen Anstieg der Klicks auf „Weiter ansehen“ um 40 %, da seine Inhalte auf mehreren Geräten angezeigt wurden.
Engage-Daten löschen
Wenn du die Daten eines Nutzers vor Ablauf der standardmäßigen Aufbewahrungsdauer von 60 Tagen manuell vom Google TV-Server löschen möchtest, verwende die Methode deleteClusters. Nach Erhalt der Anfrage löscht der Dienst alle vorhandenen Engage-Daten für das Kontoprofil oder für das gesamte Konto.
Das Enum DeleteReason definiert den Grund für das Löschen von Daten.
Mit dem folgenden Code werden die Daten zum Fortsetzen der Wiedergabe beim Abmelden entfernt.
// If the user logs out from your media app, you must make the following call
// to remove continue watching data from the current google TV device,
// otherwise, the continue watching data will persist on the current
// google TV device until 60 days later.
client.deleteClusters(
DeleteClustersRequest.Builder()
.setAccountProfile(accountProfile)
.setDeleteReason(DeleteReason.DELETE_REASON_USER_LOG_OUT)
.setSyncAcrossDevices(true)
.build()
)
Test
Verwende die Bestätigungs-App, um zu prüfen, ob die Integration des Engage SDK ordnungsgemäß funktioniert.
Nachdem Sie die Publish API aufgerufen haben, prüfen Sie in der Bestätigungs-App, ob Ihre Daten korrekt veröffentlicht werden. Ihr Fortsetzungscluster sollte als separate Zeile in der Benutzeroberfläche der App angezeigt werden.
- Testen Sie die folgenden Aktionen in Ihrer App:
- Melden Sie sich an.
- Wechseln Sie zwischen den Profilen(falls zutreffend).
- Starte ein Video und pausiere es dann oder kehre zur Startseite zurück.
- Schließe die App während der Videowiedergabe.
- Entferne ein Element aus der Zeile „Weiter ansehen“ (falls unterstützt).
- Prüfe nach jeder Aktion, ob deine App die
publishContinuationClustersAPI aufgerufen hat und ob die Daten in der Bestätigungs-App korrekt angezeigt werden. In der Verifizierungs-App wird für korrekt implementierte Entitäten ein grünes Häkchen mit der Meldung „Alles in Ordnung“ angezeigt.
Abbildung 1. Verification App Success Die Überprüfungs-App kennzeichnet alle problematischen Entitäten.
Abbildung 2. Fehler bei der Bestätigungs-App Wenn du Fehler bei Entitäten beheben möchtest, wähle die Entität in der Verifizierungs-App mit der TV-Fernbedienung aus und klicke darauf. Die spezifischen Probleme werden angezeigt und rot hervorgehoben (siehe Beispiel unten).
Abbildung 3. Details zum Fehler bei der Bestätigungs-App