Engage SDK für Videoempfehlungen

In dieser Anleitung erfahren Entwickler, wie sie ihre empfohlenen Videoinhalte mithilfe des Engage SDK integrieren, um Empfehlungen auf Google-Plattformen wie Fernsehern, Smartphones und Tablets zu präsentieren.

Bei Empfehlungen wird der Empfehlungscluster verwendet, um Filme und Serien aus mehreren Apps in einer Benutzeroberflächengruppe anzuzeigen. Jeder Entwicklerpartner kann in jedem Empfehlungscluster maximal 25 Entitäten übertragen. Pro Anfrage sind maximal 7 Empfehlungscluster möglich.

Vorbereitung

Führen Sie zuerst die folgenden Schritte aus. 1. Prüfen Sie, ob Ihre App für diese Integration auf API‑Level 19 oder höher ausgerichtet ist.

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

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

    Für Mobilgeräte

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

    für TV

    
      dependencies {
        implementation 'com.google.android.engage:engage-tv:1.0.5
      }
    
  2. Legen Sie die Engage-Dienstumgebung in der Datei AndroidManifest.xml auf „production“ fest.

    Für mobile APK

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

    Für TV-APK

    
    <meta-data
        android:name="com.google.android.engage.service.ENV"
        android:value="PRODUCTION">
    </meta-data>
    
  3. Veröffentlichung in einem Vordergrunddienst ausführen

  4. Veröffentlichen Sie Empfehlungsdaten höchstens einmal täglich. Die Veröffentlichung kann durch eine der folgenden Aktionen ausgelöst werden:

    1. Die erste Anmeldung des Nutzers an diesem Tag. (oder)
    2. Wenn der Nutzer mit der Anwendung interagiert.

Integration

AppEngagePublishClient veröffentlicht das Empfehlungscluster. Verwenden Sie die Methode publishRecommendationClusters, um ein Empfehlungsobjekt zu veröffentlichen.

Prüfen Sie mit isServiceAvailable()2, ob der Dienst für die Integration verfügbar ist.

val client = AppEngagePublishClient(context)

client.isServiceAvailable().addOnCompleteListener { task ->
  if (task.isSuccessful) {
  // Handle IPC call success
    if(task.result) {
      // Service is available on the device, proceed with content publish
      // calls.
      client.publishRecommendationClusters(recommendationRequest)
    } else {
      // Service is not available
    }
  } else {
    // The IPC call itself fails, proceed with error handling logic here,
    // such as retry.
  }
}

Empfehlungscluster und Veröffentlichungsanfrage

Cluster sind logische Gruppierungen der Entitäten. Die folgenden Codebeispiele veranschaulichen, wie Sie die Cluster nach Ihren Wünschen erstellen und eine Veröffentlichungsanfrage für alle Cluster erstellen.

// cluster for popular movies
val recommendationCluster1 = RecommendationCluster
  .Builder()
  .addEntity(movie1)
  .addEntity(movie2)
  .addEntity(movie3)
  .addEntity(movie4)
  .addEntity(tvShow)
  // This cluster is meant to be used as an individual provider row
  .setRecommendationClusterType(TYPE_PROVIDER_ROW)
  .setTitle("Popular Movies")
  .build()

// cluster for live TV programs
val recommendationCluster2 = RecommendationCluster
  .Builder()
  .addEntity(liveTvProgramEntity1)
  .addEntity(liveTvProgramEntity2)
  .addEntity(liveTvProgramEntity3)
  .addEntity(liveTvProgramEntity4)
  .addEntity(liveTvProgramEntity5)
 // This cluster is meant to be used as an individual provider row
  .setRecommendationClusterType(TYPE_PROVIDER_ROW)
  .setTitle("Popular Live TV Programs")
  .build()

// creating a publishing request
val recommendationRequest = PublishRecommendationClustersRequest
  .Builder()
  .setSyncAcrossDevices(true)
  .setAccountProfile(accountProfile)
  .addRecommendationCluster(recommendationCluster1)
  .addRecommendationCluster(recommendationCluster2)
  .build()

Kontoprofil erstellen

Damit Google TV personalisiert werden kann, müssen Konto- und Profilinformationen angegeben werden. Verwenden Sie AccountProfile, um Folgendes anzugeben:

  1. Konto-ID: Eine eindeutige Kennung, die das Konto des Nutzers in Ihrer Anwendung darstellt. Das kann die tatsächliche Konto-ID oder eine entsprechend verschleierte Version sein.
  2. Profil-ID (optional): Wenn Ihre Anwendung mehrere Profile in einem einzelnen Konto unterstützt, geben Sie eine eindeutige Kennung für das jeweilige Nutzerprofil an.
  3. Locale(optional): Optional können Sie die bevorzugte Sprache des Nutzers angeben. Dieses Feld ist nützlich, wenn Sie MediaActionFeedEntity im RecommendationRequest senden.
// If app only supports account
val accountProfile = AccountProfile.Builder()
  .setAccountId("account_id")
  .build();

// If app supports both account and profile
val accountProfile = AccountProfile.Builder()
  .setAccountId("account_id")
  .setProfileId("profile_id")
  .build();

// set Locale
val accountProfile = AccountProfile.Builder()
  .setAccountId("account_id")
  .setProfileId("profile_id")
  .setLocale("en-US")
  .build();

Wenn der Dienst die Anfrage empfängt, werden die folgenden Aktionen in einer Transaktion ausgeführt:

  • Vorhandene RecommendationsCluster-Daten des Entwicklerpartners werden entfernt.
  • Die Daten aus der Anfrage werden geparst und im aktualisierten RecommendationsCluster gespeichert. Bei einem Fehler wird die gesamte Anfrage abgelehnt und der vorhandene Status beibehalten.

Geräteübergreifende Synchronisierung

Mit dem Flag SyncAcrossDevices wird gesteuert, ob die Daten des Empfehlungsclusters eines Nutzers für Google TV freigegeben und auf seinen Geräten wie Fernseher, Smartphone und Tablet verfügbar sind. Damit die Empfehlung funktioniert, muss sie auf „true“ gesetzt sein.

Die Media-App muss eine eindeutige Einstellung zum Aktivieren oder Deaktivieren der geräteübergreifenden Synchronisierung bieten. Erläutern Sie dem Nutzer die Vorteile und speichern Sie die Einstellung des Nutzers einmal, um sie entsprechend im publishRecommendations-Request anzuwenden. Damit Sie die geräteübergreifende Funktion optimal nutzen können, müssen Sie dafür sorgen, dass die App die Einwilligung des Nutzers einholt und SyncAcrossDevices für true aktiviert.

Daten zur Videoermittlung löschen

Wenn Sie die Daten eines Nutzers vor dem standardmäßigen Aufbewahrungszeitraum von 60 Tagen manuell vom Google TV-Server löschen möchten, verwenden Sie die Methode client.deleteClusters(). Nach Eingang der Anfrage löscht der Dienst alle vorhandenen Daten zur Videoermittlung für das Kontoprofil oder für das gesamte Konto.

Die Enumeration DeleteReason definiert den Grund für das Löschen von Daten. Mit dem folgenden Code werden Empfehlungen beim Abmelden entfernt.

// If the user logs out from your media app, you must make the following call
// to remove recommendations data from the current google TV device,
// otherwise, the recommendations data persists on the current
// google TV device until 60 days later.
client.deleteClusters(
  new DeleteClustersRequest.Builder()
    .setAccountProfile(AccountProfile())
    .setReason(DeleteReason.DELETE_REASON_USER_LOG_OUT)
    .build()
)

// If the user revokes the consent to share data with Google TV,
// you must make the following call to remove recommendations data from
// all current google TV devices. Otherwise, the recommendations data persists
// until 60 days later.
client.deleteClusters(
  new DeleteClustersRequest.Builder()
    .setAccountProfile(AccountProfile())
    .setReason(DeleteReason.DELETE_REASON_LOSS_OF_CONSENT)
    .build()
)

Entitäten erstellen

Im SDK sind verschiedene Entitäten definiert, um die einzelnen Elementtypen darzustellen. Die folgenden Einheiten werden für den Empfehlungscluster unterstützt:

  1. MediaActionFeedEntity
  2. MovieEntity
  3. TvShowEntity
  4. LiveTvChannelEntity
  5. LiveTvProgramEntity

Beschreibung

Geben Sie für jede Einheit eine kurze Beschreibung an. Diese Beschreibung wird angezeigt, wenn Nutzer den Mauszeiger auf die Einheit bewegen, und enthält zusätzliche Details.

Plattformspezifische Wiedergabe-URIs

Erstelle Wiedergabe-URIs für jede unterstützte Plattform: Android TV, Android oder iOS. So kann das System den entsprechenden URI für die Videowiedergabe auf der jeweiligen Plattform auswählen.

In dem seltenen Fall, dass die Wiedergabe-URIs für alle Plattformen identisch sind, wiederholen Sie den Vorgang für jede Plattform.

// Required. Set this when you want recommended 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()

// Optional. Set this when you want recommended entities to show up on
// Google TV Android app
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 recommended 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)

// Provide appropriate rating for the system.
val contentRating = new RatingSystem
  .Builder()
  .setAgencyName("MPAA")
  .setRating("PG-13")
  .build()

Posterbilder

Für Posterbilder sind eine URI und Pixelabmessungen (Höhe und Breite) erforderlich. Wenn Sie mehrere Posterbilder bereitstellen, können Sie verschiedene Formfaktoren ansprechen. Achten Sie jedoch darauf, dass alle Bilder ein Seitenverhältnis von 16:9 und eine Mindesthöhe von 200 Pixeln haben, damit die Empfehlungen richtig angezeigt werden, 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)

Grund für Empfehlung

Optional können Sie einen Empfehlungsgrund angeben, der von Google TV verwendet werden kann, um Gründe dafür zu nennen, warum einem Nutzer ein bestimmter Film oder eine bestimmte Serie vorgeschlagen wird.

//Allows us to construct reason: "Because it is top 10 on your Channel"
val topOnPartner = RecommendationReasonTopOnPartner
  .Builder()
  .setNum(10) //any valid integer value
  .build()

//Allows us to construct reason: "Because it is popular on your Channel"
val popularOnPartner = RecommendationReasonPopularOnPartner
  .Builder()
  .build()

//Allows us to construct reason: "New to your channel, or Just added"
val newOnPartner = RecommendationReasonNewOnPartner
  .Builder()
  .build()

//Allows us to construct reason: "Because you watched Star Wars"
val watchedSimilarTitles = RecommendationReasonWatchedSimilarTitles
  .addSimilarWatchedTitleName("Movie or TV Show Title")
  .addSimilarWatchedTitleName("Movie or TV Show Title")
  .Builder()
  .build()

//Allows us to construct reason: "Recommended for you by ChannelName"
val recommendedForUser = RecommendationReasonRecommendedForUser
  .Builder()
  .build()

val watchAgain = RecommendationReasonWatchAgain
  .Builder()
  .build()

val fromUserWatchList = RecommendationReasonFromUserWatchlist
  .Builder()
  .build()

val userLikedOnPartner = RecommendationReasonUserLikedOnPartner
  .Builder()
  .setTitleName("Movie or TV Show Title")
  .build()

val generic = RecommendationReasonGeneric.Builder().build()

Zeitfenster für die Anzeige

Wenn eine Einheit nur für begrenzte Zeit verfügbar sein soll, legen Sie eine benutzerdefinierte Ablaufzeit fest. Ohne eine explizite Ablaufzeit laufen Entitäten nach 60 Tagen automatisch ab und werden gelöscht. Legen Sie also nur dann eine Ablaufzeit fest, wenn die Entitäten früher ablaufen müssen. Geben Sie mehrere solcher Verfügbarkeitszeiträume an.

val window1 = DisplayTimeWindow
  .Builder()
  .setStartTimeStampMillis(now()+ 1.days.toMillis())
  .setEndTimeStampMillis(now()+ 30.days.toMillis())

val window2 = DisplayTimeWindow
  .Builder()
  .setEndTimeStampMillis(now()+ 30.days.toMillis())

val availabilityTimeWindows: List<DisplayTimeWindow> = listof(window1,window2)

DataFeedElementId

Wenn Sie Ihren Medienkatalog oder Media Action-Feed in Google TV integriert haben, müssen Sie keine separaten Einheiten für Filme oder Serien erstellen. Stattdessen können Sie eine MediaActionFeed-Einheit erstellen, die das erforderliche Feld „DataFeedElementId“ enthält. Diese ID muss eindeutig sein und mit der ID im Media Action Feed übereinstimmen, da sie zur Identifizierung von aufgenommenen Feedinhalten und zur Suche nach Medieninhalten verwendet wird.

val id = "dataFeedEleemntId"

MovieEntity

Hier ein Beispiel für das Erstellen eines MovieEntity mit allen erforderlichen Feldern:


val movieEntity = MovieEntity.Builder()
  .setName("Movie name")
  .setDescription("A sentence describing movie.")
  .addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
  .addPosterImages(images)
  // Suppose the duration is 2 hours, it is 72000000 in milliseconds
  .setDurationMills(72000000)
  .build()

Sie können zusätzliche Daten wie Genres, Altersfreigaben, Veröffentlichungsdatum, Empfehlungsgrund und Verfügbarkeitszeiträume angeben, die von Google TV für eine verbesserte Darstellung oder Filterung verwendet werden können.

val genres = Arrays.asList("Action", "Science fiction");
val rating1 = RatingSystem.Builder().setAgencyName("MPAA").setRating("pg-13").build();
val contentRatings = Arrays.asList(rating1);
//Suppose release date is 11-02-2025
val releaseDate  = 1739233800000L
val movieEntity = MovieEntity.Builder()
  ...
  .addGenres(genres)
  .setReleaseDateEpochMillis(releaseDate)
  .addContentRatings(contentRatings)
  .setRecommendationReason(topOnPartner or watchedSimilarTitles)
  .addAllAvailabilityTimeWindows(availabilityTimeWindows)
  .build()

TvShowEntity

Hier ein Beispiel für das Erstellen eines TvShowEntity mit allen erforderlichen Feldern:

val tvShowEntity = TvShowEntity.Builder()
  .setName("Show title")
  .setDescription("A sentence describing TV Show.")
  .addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
  .addPosterImages(images)
  .build();

Optional können Sie zusätzliche Daten wie Genres, Altersfreigaben, Empfehlungsgrund, Angebotspreis, Anzahl der Staffeln oder Verfügbarkeitszeitraum angeben, die von Google TV für eine verbesserte Darstellung oder Filterzwecke verwendet werden können.

val genres = Arrays.asList("Action", "Science fiction");
val rating1 = RatingSystem.Builder()
  .setAgencyName("MPAA")
  .setRating("pg-13")
  .build();
val price = Price.Builder()
  .setCurrentPrice("$14.99")
  .setStrikethroughPrice("$16.99")
  .build();
val contentRatings = Arrays.asList(rating1);
val seasonCount = 5;
val tvShowEntity = TvShowEntity.Builder()
  ...
  .addGenres(genres)
  .addContentRatings(contentRatings)
  .setRecommendationReason(topOnPartner or watchedSimilarTitles)
  .addAllAvailabilityTimeWindows(availabilityTimeWindows)
  .setSeasonCount(seasonCount)
  .setPrice(price)
  .build()

MediaActionFeedEntity

Hier ist ein Beispiel für das Erstellen eines MediaActionFeedEntity mit allen erforderlichen Feldern:


val mediaActionFeedEntity = MediaActionFeedEntity.Builder()
  .setDataFeedElementId(id)
  .build()

Optional können Sie zusätzliche Daten wie Beschreibung, Empfehlungsgrund und Anzeigezeitfenster angeben, die von Google TV für erweiterte Anzeigen oder Filterzwecke verwendet werden können.

val mediaActionFeedEntity = MediaActionFeedEntity.Builder()
  .setName("Movie name or TV Show name")
  .setDescription("A sentence describing an entity")
  .setRecommendationReason(topOnPartner or watchedSimilarTitles)
  .addPosterImages(images)
  .build()

LiveTvChannelEntity

Das ist ein Live-TV-Kanal. Hier ein Beispiel für das Erstellen eines LiveTvChannelEntity mit allen erforderlichen Feldern:

val liveTvChannelEntity = LiveTvChannelEntity.Builder()
  .setName("Channel Name")
  // ID of the live TV channel
  .setEntityId("https://www.example.com/channel/12345")
  .setDescription("A sentence describing this live TV channel.")
  // channel playback uri must contain at least PlatformType.TYPE_ANDROID_TV
  .addPlatformSpecificPlaybackUri(channelPlaybackUris)
  .addLogoImage(logoImage)
  .build()

Optional können Sie zusätzliche Daten wie Altersfreigaben oder den Grund für die Empfehlung angeben.

val rating1 = RatingSystem.Builder()
  .setAgencyName("MPAA")
  .setRating("pg-13")
  .build()
val contentRatings = Arrays.asList(rating1)

val liveTvChannelEntity = LiveTvChannelEntity.Builder()
  ...
  .addContentRatings(contentRatings)
  .setRecommendationReason(topOnPartner)
  .build()

LiveTvProgramEntity

Dies ist eine Karte für eine Live-TV-Sendung, die auf einem Live-TV-Kanal ausgestrahlt wird oder ausgestrahlt werden soll. Hier ein Beispiel für das Erstellen eines LiveTvProgramEntity mit allen erforderlichen Feldern:

val liveTvProgramEntity = LiveTvProgramEntity.Builder()
  // First set the channel information
  .setChannelName("Channel Name")
  .setChanelId("https://www.example.com/channel/12345")
  // channel playback uri must contain at least PlatformType.TYPE_ANDROID_TV
  .addPlatformSpecificPlaybackUri(channelPlaybackUris)
  .setChannelLogoImage(channelLogoImage)
  // Then set the program or card specific information.
  .setName("Program Name")
  .setEntityId("https://www.example.com/schedule/123")
  .setDescription("Program Desccription")
  .addAvailabilityTimeWindow(
      DisplayTimeWindow.Builder()
        .setStartTimestampMillis(1756713600000L)// 2025-09-01T07:30:00+0000
        .setEndTimestampMillis(1756715400000L))// 2025-09-01T08:00:00+0000
  .addPosterImage(programImage)
  .build()

Optional können Sie zusätzliche Daten wie Altersfreigaben, Genres oder den Grund für die Empfehlung angeben.

val rating1 = RatingSystem.Builder()
  .setAgencyName("MPAA")
  .setRating("pg-13")
  .build()
val contentRatings = Arrays.asList(rating1)
val genres = Arrays.asList("Action", "Science fiction")

val liveTvProgramEntity = LiveTvProgramEntity.Builder()
  ...
  .addContentRatings(contentRatings)
  .addGenres(genres)
  .setRecommendationReason(topOnPartner)
  .build()

Wenn Entwickler diese Schritte ausführen, können sie Videoinhaltsempfehlungen erfolgreich in Google TV einbinden. So können Nutzer Inhalte leichter finden und die Interaktion wird gesteigert. Außerdem wird Nutzern auf allen ihren Geräten eine einheitliche und personalisierte Wiedergabe geboten.