SDK Engage per i consigli sui video

Questa guida contiene istruzioni per gli sviluppatori per integrare i contenuti video consigliati utilizzando l'SDK Engage, per popolare le esperienze di consigli sulle piattaforme Google, come TV, dispositivi mobili e tablet.

Il consiglio sfrutta il cluster di consigli per mostrare film e programmi TV di più app in un unico raggruppamento dell'interfaccia utente. Ogni partner sviluppatore può trasmettere un massimo di 25 entità in ogni cluster di consigli e possono esserci un massimo di 7 cluster di consigli per richiesta.

Preparazione

Prima di iniziare, completa i seguenti passaggi. 1. Verifica che la tua app abbia come target il livello API 19 o versioni successive per questa integrazione.

  1. Aggiungi la libreria com.google.android.engage alla tua app.

    Esistono SDK separati da utilizzare nell'integrazione: uno per le app mobile e uno per le app TV.

    Per dispositivi mobili

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

    per TV

    
      dependencies {
        implementation 'com.google.android.engage:engage-tv:1.0.5
      }
    
  2. Imposta l'ambiente di servizio Engage su produzione nel file AndroidManifest.xml.

    Per APK mobile

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

    Per tv apk

    
    <meta-data
        android:name="com.google.android.engage.service.ENV"
        android:value="PRODUCTION">
    </meta-data>
    
  3. Esegui la pubblicazione su un servizio in primo piano.

  4. Pubblica i dati dei consigli al massimo una volta al giorno, attivati da uno dei seguenti eventi:

    1. Il primo accesso dell'utente della giornata. (o)
    2. Quando l'utente inizia a interagire con l'applicazione.

Integrazione

AppEngagePublishClient pubblica il cluster di consigli. Utilizza il metodo publishRecommendationClusters per pubblicare un oggetto consigli.

Utilizza isServiceAvailable()2 per verificare se il servizio è disponibile per l'integrazione.

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.
  }
}

Cluster di consigli e una richiesta di pubblicazione

I cluster sono raggruppamenti logici delle entità. I seguenti esempi di codice spiegano come creare i cluster in base alle tue preferenze e come creare una richiesta di pubblicazione per tutti i cluster.

// 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()

Creare un profilo dell'account

Per consentire un'esperienza personalizzata su Google TV, fornisci le informazioni dell'account e del profilo. Utilizza AccountProfile per fornire:

  1. ID account: un identificatore univoco che rappresenta l'account dell'utente all'interno della tua applicazione. Può trattarsi dell'ID account effettivo o di una versione offuscata in modo appropriato.
  2. ID profilo (facoltativo): se la tua applicazione supporta più profili all'interno di un singolo account, fornisci un identificatore univoco per il profilo utente specifico.
  3. Locale(facoltativo): se vuoi, puoi specificare la lingua preferita dell'utente. Questo campo è utile se invii MediaActionFeedEntity nel RecommendationRequest.
// 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();

Quando il servizio riceve la richiesta, all'interno di una transazione si verificano le seguenti azioni:

  • I dati RecommendationsCluster esistenti del partner sviluppatore vengono rimossi.
  • I dati della richiesta vengono analizzati e archiviati nel RecommendationsCluster aggiornato. In caso di errore, l'intera richiesta viene rifiutata e lo stato esistente viene mantenuto.

Sincronizzazione cross-device

Il flag SyncAcrossDevices controlla se i dati del cluster di consigli di un utente vengono condivisi con Google TV e sono disponibili su tutti i suoi dispositivi, come TV, smartphone, tablet. Affinché il suggerimento funzioni, deve essere impostato su true.

L'applicazione multimediale deve fornire un'impostazione chiara per attivare o disattivare la sincronizzazione cross-device. Spiega i vantaggi per l'utente e memorizza la preferenza dell'utente una sola volta e applicala di conseguenza nella richiesta publishRecommendations. Per sfruttare al meglio la funzionalità cross-device, verifica che l'app ottenga il consenso dell'utente e attivi SyncAcrossDevices per true.

Eliminare i dati degli annunci video discovery

Per eliminare manualmente i dati di un utente dal server Google TV prima del periodo di conservazione standard di 60 giorni, utilizza il metodo client.deleteClusters(). Al ricevimento della richiesta, il servizio elimina tutti i dati esistenti di scoperta dei video per il profilo dell'account o per l'intero account.

L'enumerazione DeleteReason definisce il motivo dell'eliminazione dei dati. Il seguente codice rimuove i consigli al momento della disconnessione.

// 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()
)

Crea entità

L'SDK ha definito entità diverse per rappresentare ogni tipo di elemento. Per il cluster di consigli sono supportate le seguenti entità:

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

Descrizione

Fornisci una breve descrizione per ogni entità. Questa descrizione verrà visualizzata quando gli utenti passano il mouse sopra l'entità, fornendo loro ulteriori dettagli.

URI di riproduzione specifici della piattaforma

Crea URI di riproduzione per ogni piattaforma supportata: Android TV, Android o iOS. In questo modo, il sistema può selezionare l'URI appropriato per la riproduzione video sulla rispettiva piattaforma.

Nel raro caso in cui gli URI di riproduzione siano identici per tutte le piattaforme, ripeti la procedura per ogni piattaforma.

// 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()

Immagini poster

Le immagini del poster richiedono un URI e le dimensioni in pixel (altezza e larghezza). Prendi di mira diversi fattori di forma fornendo più immagini della locandina, ma verifica che tutte le immagini mantengano proporzioni 16:9 e un'altezza minima di 200 pixel per la corretta visualizzazione dell'entità "Consigliati", in particolare all'interno di Entertainment Space di Google. Le immagini con un'altezza inferiore a 200 pixel potrebbero non essere mostrate.

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)

Motivo del consiglio

(Facoltativo) Fornisci un motivo per il suggerimento che può essere utilizzato da Google TV per spiegare all'utente perché suggerire un film o un programma TV specifico.

//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()

Visualizzare la finestra temporale

Se un'entità deve essere disponibile solo per un periodo di tempo limitato, imposta un tempo di scadenza personalizzato. Senza un orario di scadenza esplicito, le entità scadranno automaticamente e verranno cancellate dopo 60 giorni. Imposta quindi una data di scadenza solo quando le entità devono scadere prima. Specifica più finestre di disponibilità.

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

Se hai integrato il catalogo multimediale o il feed di azioni multimediali con Google TV, non devi creare entità separate per film o programmi TV e puoi invece creare un'entità MediaActionFeed che includa il campo obbligatorio DataFeedElementId. Questo ID deve essere univoco e corrispondere all'ID nel feed Azione multimediale, in quanto consente di identificare i contenuti del feed inseriti ed eseguire ricerche di contenuti multimediali.

val id = "dataFeedEleemntId"

MovieEntity

Ecco un esempio di creazione di un MovieEntity con tutti i campi obbligatori:


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()

Puoi fornire dati aggiuntivi come generi, classificazioni dei contenuti, data di uscita, motivo del consiglio e finestre temporali di disponibilità, che potrebbero essere utilizzati da Google TV per visualizzazioni avanzate o scopi di filtraggio.

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

Ecco un esempio di creazione di un TvShowEntity con tutti i campi obbligatori:

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

Se vuoi, fornisci dati aggiuntivi come generi, classificazioni dei contenuti, motivo del consiglio, prezzo dell'offerta, numero di stagioni o finestra temporale di disponibilità, che potrebbero essere utilizzati da Google TV per una visualizzazione o un filtraggio avanzati.

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

Ecco un esempio di creazione di un MediaActionFeedEntity con tutti i campi obbligatori:


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

(Facoltativo) Fornisci dati aggiuntivi come descrizione, motivo del consiglio e finestra temporale di visualizzazione, che potrebbero essere utilizzati da Google TV per visualizzazioni avanzate o scopi di filtraggio.

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

Rappresenta un canale TV in diretta. Ecco un esempio di creazione di un LiveTvChannelEntity con tutti i campi obbligatori:

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()

(Facoltativo) Fornisci dati aggiuntivi, come le classificazioni dei contenuti o il motivo del consiglio.

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

Rappresenta una scheda di programma TV in diretta in onda o in programmazione su un canale TV in diretta. Ecco un esempio di creazione di un LiveTvProgramEntity con tutti i campi obbligatori:

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()

(Facoltativo) Fornisci dati aggiuntivi come classificazioni dei contenuti, generi o motivo del consiglio.

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()

Implementando questi passaggi, gli sviluppatori possono integrare correttamente i consigli sui contenuti video in Google TV, aumentando la scoperta e il coinvolgimento degli utenti e fornendo un'esperienza di visualizzazione coerente e personalizzata su tutti i loro dispositivi.