Anleitung zur Integration des Engage SDK für Fernseher

Bei „Weiter ansehen“ wird der Fortsetzungscluster verwendet, um nicht fertig angesehene Videos und die nächsten Folgen derselben TV-Staffel aus mehreren Apps in einer UI-Gruppierung anzuzeigen. Du kannst ihre Entitäten in diesem Fortsetzungscluster präsentieren. In diesem Leitfaden erfährst du, wie du mit dem Engage SDK das Nutzer-Engagement durch die Funktion „Weiter ansehen“ verbessern kannst.

Schritt 1: Vorarbeiten

Führen Sie zuerst die folgenden Schritte aus:

Ihre App muss für diese Integration auf API-Level 19 oder höher ausgerichtet sein.

  1. Fügen Sie Ihrer App die com.google.android.engage-Bibliothek hinzu:

    Für die Integration gibt es separate SDKs: eines für mobile Apps und eines für TV-Apps.

    Mobilgerät

    
      dependencies {
        implementation 'com.google.android.engage:engage-core:1.5.5
      }
    

    TV

    
      dependencies {
        implementation 'com.google.android.engage:engage-tv:1.0.2
      }
    
  2. Legen Sie in der Datei AndroidManifest.xml die Umgebung des Engage-Dienstes auf „Produktion“ fest.

    Mobilgerät

    
    <meta-data
          android:name="com.google.android.engage.service.ENV"
          android:value="PRODUCTION">
    </meta-data>
    

    TV

    
    <meta-data
        android:name="com.google.android.engage.service.ENV"
        android:value="PRODUCTION">
    </meta-data>
    
  3. Berechtigung für WRITE_EPG_DATA für TV-APK hinzufügen

      <uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
    
  4. Sorgen Sie für eine zuverlässige Veröffentlichung von Inhalten, indem Sie für die Planung einen Hintergrunddienst wie androidx.work verwenden.

  5. Damit die Wiedergabe reibungslos funktioniert, sollten Sie Daten zur Wiedergabe fortsetzen veröffentlichen, wenn eines der folgenden Ereignisse eintritt:

    1. Erste Anmeldung: Wenn sich ein Nutzer zum ersten Mal anmeldet, werden seine Daten veröffentlicht, damit sein Wiedergabeverlauf sofort verfügbar ist.
    2. Profilerstellung oder -wechsel (Apps mit mehreren Profilen): Wenn Ihre App mehrere Profile unterstützt, veröffentlichen Sie Daten, wenn ein Nutzer ein Profil erstellt oder wechselt. So wird für jeden Nutzer eine personalisierte Nutzung ermöglicht.
    3. Unterbrechung der Videowiedergabe: Damit Nutzer dort weitermachen können, wo sie aufgehört haben, veröffentlichen Sie Daten, wenn ein Video pausiert oder angehalten wird oder die App während der Wiedergabe geschlossen wird.
    4. Aktualisierungen des Bereichs „Weiter ansehen“ (falls unterstützt): Wenn ein Nutzer ein Element aus dem Bereich „Weiter ansehen“ entfernt, müssen Sie diese Änderung durch das Veröffentlichen aktualisierter Daten widerspiegeln. So bleibt das Info-Anzeigefeld relevant und personalisiert.
    5. Videowiedergabe bis zum Ende:
      1. Entferne bei Filmen den angesehenen Film aus dem Bereich „Weiter ansehen“. Wenn der Film Teil einer Reihe ist, füge den nächsten Film hinzu, um die Aufmerksamkeit der Nutzer aufrechtzuerhalten.
      2. Entferne bei Folgen die abgeschlossene Folge und füge gegebenenfalls die nächste Folge der Serie hinzu, um die Zuschauer zum Weiterschauen zu animieren.

Integration

AccountProfile

Wenn du die Funktion „Weiter ansehen“ auf Google TV personalisieren möchtest, gib Konto- und Profilinformationen an. Verwenden Sie das AccountProfile, um Folgendes anzugeben:

  1. Konto-ID: Eine eindeutige Kennung, die das Konto des Nutzers in Ihrer Anwendung darstellt. Dies kann die tatsächliche Konto-ID oder eine entsprechend verschleierte Version sein.

  2. Profil-ID (optional): Wenn Ihre Anwendung mehrere Profile innerhalb eines einzelnen Kontos unterstützt, geben Sie eine eindeutige Kennung für das jeweilige Nutzerprofil an (wiederum echt oder verschleiert).

// If your app only supports account
val accountProfile = AccountProfile.Builder()
      .setAccountId("your_users_account_id")
      .build()
// If your app supports both account and profile
val accountProfile = AccountProfile.Builder()
      .setAccountId("your_users_account_id")
      .setProfileId("your_users_profile_id")
.build()

Entitäten erstellen

Im SDK sind verschiedene Entitäten für jeden Artikeltyp definiert. Fortsetzungscluster unterstützen die folgenden Entitäten:

  1. MovieEntity
  2. TvEpisodeEntity
  3. LiveStreamingVideoEntity
  4. VideoClipEntity

Gib die platformspezifischen URIs und Posterbilder für diese Entitäten an.

Erstelle außerdem Wiedergabe-URIs für jede Plattform, z. B. für Android TV, Android oder iOS, falls noch nicht geschehen. Wenn ein Nutzer sich also auf jeder Plattform die Wiedergabe fortsetzt, verwendet die App einen zielgerichteten Wiedergabe-URI, um die Videoinhalte 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. Du kannst verschiedene Formfaktoren anvisieren, indem du mehrere Posterbilder bereitstellst. 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.


Image image1 = new Image.Builder()
            .setImageUri(Uri.parse("http://www.example.com/entity_image1.png");)
            .setImageHeightInPixel(300)
            .setImageWidthInPixel(169)
            .build()
Image image2 = new Image.Builder()
            .setImageUri(Uri.parse("http://www.example.com/entity_image2.png");)
            .setImageHeightInPixel(640)
            .setImageWidthInPixel(360)
            .build()
// And other images for different form factors.
val images = Arrays.asList(image1, image2)
MovieEntity

In diesem Beispiel wird gezeigt, wie Sie ein MovieEntity mit allen erforderlichen Feldern erstellen:

val movieEntity = MovieEntity.Builder()
   .setWatchNextType(WatchNextType.TYPE_CONTINUE)
   .setName("Movie name")
   .addPlatformSpecificPlaybackUri(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
   .setDurationMills(72000000)
   // Suppose last playback offset is 1 hour, 36000000 in milliseconds
   .setLastPlayBackPositionTimeMillis(36000000)
   .build()

Wenn du Details wie Genres und Altersfreigaben angibst, kann Google TV deine Inhalte dynamischer präsentieren und sie den richtigen Zuschauern präsentieren.

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, es sei denn, Sie geben eine kürzere Gültigkeitsdauer an. Legen Sie nur dann ein benutzerdefiniertes Ablaufdatum fest, wenn das Entitätselement vor diesem Standardzeitraum entfernt werden soll.

// Set the expiration time to be now plus 30 days in milliseconds
val expirationTime = new DisplayTimeWindow.Builder()
             .setEndTimestampMillis(now().toMillis()+2592000000).build()
val movieEntity = MovieEntity.Builder()
    ...
    .addAvailabilityTimeWindow(expirationTime)
    .build()
TvEpisodeEntity

In diesem Beispiel wird gezeigt, wie Sie ein TvEpisodeEntity mit allen erforderlichen Feldern erstellen:

val tvEpisodeEntity = TvEpisodeEntity.Builder()
    .setWatchNextType(WatchNextType.TYPE_CONTINUE)
    .setName("Episode name")
    .addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
    .addPosterImages(images)
    // Timestamp in millis for sample last engagement time 12/1/2023 00:00:00
    .setLastEngagementTimeMillis(1701388800000)
    .setDurationMills(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")
    .build();

Der String für die Folgennummer (z. B. "2") und der String für die Staffelnummer (z. B. "1") werden in die richtige Form umgewandelt, bevor sie auf der Karte „Weiter ansehen“ angezeigt werden. Die Nummer muss ein numerischer String sein. Gib also keine Werte wie „e2“, „Folge 2“, „s1“ oder „Staffel 1“ ein.

Wenn eine bestimmte TV-Serie nur eine Staffel hat, setze die Staffelnummer auf 1.

Damit Zuschauer deine Inhalte auf Google TV leichter finden, solltest du zusätzliche Daten wie Genres, Altersfreigaben und Verfügbarkeitszeiträume angeben. Diese Details können die Darstellung und 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")
    .addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
    .addPosterImages(images)
    // Timestamp in millis for sample last engagement time 12/1/2023 00:00:00
    .setLastEngagementTimeMillis(1701388800000)
    .setDurationMills(600000) //10 minutes in milliseconds
    .setLastPlayBackPositionTimeMillis(300000) //5 minutes in milliseconds
    .addContentRating(contentRating)
    .build();

Optional kannst du den Ersteller, das Bild des Erstellers, die Erstellungszeit in Millisekunden oder das Zeitfenster für die Verfügbarkeit festlegen .

LiveStreamingVideoEntity

Hier ist ein Beispiel für die Erstellung einer 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")
    .addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
    .addPosterImages(images)
    // Timestamp in millis for sample last engagement time 12/1/2023 00:00:00
    .setLastEngagementTimeMillis(1701388800000)
    .setDurationMills(72000000) //2 hours in milliseconds
    .setLastPlayBackPositionTimeMillis(36000000) //1 hour in milliseconds
    .addContentRating(contentRating)
    .build();

Optional kannst du die Startzeit, den Sender, das Sendersymbol oder den Verfügbarkeitszeitraum für die Livestreaming-Entität festlegen.

Ausführliche Informationen zu Attributen und Anforderungen finden Sie in der API-Referenz.

Daten für Fortsetzungscluster angeben

AppEngagePublishClient ist für die Veröffentlichung des Fortsetzungsclusters verantwortlich. Mit der Methode publishContinuationCluster() wird ein ContinuationCluster-Objekt veröffentlicht.

Prüfe zuerst mit isServiceAvailable(), ob der Dienst für die Integration verfügbar ist.

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 erhält, werden innerhalb einer Transaktion die folgenden Aktionen ausgeführt:

  • Vorhandene ContinuationCluster-Daten des Entwicklerpartners werden entfernt.
  • Die Daten aus der Anfrage werden analysiert und in der aktualisierten ContinuationCluster gespeichert.

Bei einem Fehler wird die gesamte Anfrage abgelehnt und der aktuelle Status bleibt erhalten.

Die Publish APIs sind Upsert-APIs, die die vorhandenen Inhalte ersetzen. Wenn Sie eine bestimmte Entität im ContinuationCluster aktualisieren möchten, müssen Sie alle Entitäten noch einmal veröffentlichen.

ContinuationCluster-Daten sollten nur für Konten von Erwachsenen bereitgestellt werden. Nur veröffentlichen, wenn das Kontoprofil einem Erwachsenen gehört.

Geräteübergreifende Synchronisierung

Flag „SyncAcrossDevices“

Mit diesem Flag wird festgelegt, ob die ContinuationCluster-Daten eines Nutzers auf seinen Geräten (Fernseher, Smartphone, Tablet usw.) synchronisiert werden. Standardmäßig ist „false“ festgelegt, was bedeutet, dass die geräteübergreifende Synchronisierung standardmäßig deaktiviert ist.

Werte:

  • „true“: ContinuationCluster-Daten werden für eine nahtlose Wiedergabe auf allen Geräten des Nutzers freigegeben. Wir empfehlen diese Option, um die Geräteübergreifende Nutzung zu optimieren.
  • false: ContinuationCluster-Daten sind auf das aktuelle Gerät beschränkt.

Die Medienanwendung muss eine eindeutige Einstellung zur Aktivierung/Deaktivierung der geräteübergreifenden Synchronisierung bieten. Erläutern Sie die Vorteile für den Nutzer, speichern Sie die Einstellung des Nutzers einmal und wenden Sie sie entsprechend in publishContinuationCluster 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, muss Ihre App die Nutzereinwilligung einholen und „SyncAcrossDevices“ muss auf „true“ gesetzt sein. So können Inhalte nahtlos zwischen Geräten synchronisiert werden, was zu einer besseren Nutzererfahrung und mehr Interaktionen führt. Ein Partner, der diese Funktion implementiert hat, verzeichnete beispielsweise eine Steigerung der Klicks auf „Weiter ansehen“ um 40 %, da seine Inhalte auf mehreren Geräten angezeigt wurden.

Daten zu Videoaufrufen löschen

Wenn du die Daten eines Nutzers vor Ablauf der standardmäßigen Aufbewahrungsfrist von 60 Tagen manuell vom Google TV-Server löschen möchtest, verwende die Methode „client.deleteClusters()“. Nach Erhalt der Anfrage werden alle vorhandenen Daten zur Videosuche für das Kontoprofil oder für das gesamte Konto gelöscht.

Die DeleteReason-Enumeration definiert den Grund für das Löschen von Daten. Mit dem folgenden Code werden 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(
  new DeleteClustersRequest.Builder()
        .setAccountProfile(AccountProfile())
        .setReason(DeleteReason.DELETE_REASON_USER_LOG_OUT)
        .setSyncAcrossDevices(true)
        .build()
)

Testen

Mit der Überprüfungs-App kannst du prüfen, ob die Integration des Engage SDK ordnungsgemäß funktioniert. Diese Android-Anwendung bietet Tools, mit denen Sie Ihre Daten prüfen und bestätigen können, dass Broadcast-Intents ordnungsgemäß verarbeitet werden.

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 in der Benutzeroberfläche der App als separate Zeile angezeigt werden.

  • Achten Sie darauf, dass das Flag „Engage Service“ in der Android-Manifestdatei Ihrer App NICHT auf „Production“ festgelegt ist.
  • Installieren und öffnen Sie die Engage Verify App.
  • Wenn isServiceAvailable false ist, klicken Sie auf die Schaltfläche „Aktivieren/Deaktivieren“, um die Funktion zu aktivieren.
  • Geben Sie den Paketnamen Ihrer App ein, um veröffentlichte Daten automatisch aufzurufen, sobald Sie mit der Veröffentlichung beginnen.
  • Testen Sie diese Aktionen in Ihrer App:
    • Melden Sie sich an.
    • Wechseln Sie gegebenenfalls zwischen Profilen.
    • Starte oder pausiere ein Video oder kehre zur Startseite zurück.
    • Schließen Sie die App während der Videowiedergabe.
    • Entferne ein Element aus der Zeile „Weiter ansehen“ (falls unterstützt).
  • Prüfen Sie nach jeder Aktion, ob Ihre App die publishContinuationClusters API aufgerufen hat und ob die Daten in der Bestätigungs-App korrekt angezeigt werden.
  • Die Bestätigungs-App zeigt für korrekt implementierte Entitäten ein grünes Häkchen an.

    Screenshot: Bestätigung der App war erfolgreich
    Abbildung 1. Überprüfung App-Erfolg
  • Die App zur Überprüfung meldet alle problematischen Entitäten.

    Screenshot des Fehlers bei der Bestätigungs-App
    Abbildung 2. Fehler bei der Bestätigungs-App
  • Wenn Sie Probleme mit Entitäten beheben möchten, wählen Sie die Entität in der Bestätigungs-App mit der Fernbedienung Ihres Fernsehers aus und klicken Sie darauf. Die spezifischen Probleme werden angezeigt und rot hervorgehoben (siehe Beispiel unten).

    Fehlerdetails zur Überprüfungs-App
    Abbildung 3: Details zum Fehler bei der Überprüfung der App