Chaînes sur l'écran d'accueil

L'écran d'accueil d'Android TV, ou simplement l'écran d'accueil, fournit une UI qui affiche des contenus recommandés sous la forme d'un tableau de chaînes et de programmes. Chaque ligne correspond à une chaîne. Une chaîne contient des fiches pour chaque programme qu'elle contient:

Écran d'accueil de la TV

Ce document explique comment ajouter des chaînes et des programmes à l'écran d'accueil, mettre à jour des contenus, gérer les actions des utilisateurs et leur offrir la meilleure expérience possible. Si vous souhaitez en savoir plus sur l'API, consultez atelier de programmation sur l'écran d'accueil et regardez la session Android TV I/O 2017.)

Remarque : Les canaux de recommandations ne sont disponibles que dans les pays suivants : Android 8.0 (niveau d'API 26) ou version ultérieure Vous devez les utiliser pour fournir recommandations pour les applications fonctionnant sous Android 8.0 (niveau d'API 26) ou version ultérieure. À fournir des recommandations pour les applications exécutées sur des versions antérieures d'Android, votre application vous devez utiliser ligne recommandations à la place.

UI de l'écran d'accueil

Les applications peuvent créer des chaînes, ajouter, supprimer et mettre à jour des programmes sur une chaîne, et contrôler l'ordre des programmes sur une chaîne. Par exemple, une application peut créer une catégorie intitulée "Nouveautés" et afficher des cartes pour les nouveaux programmes.

Les applications ne peuvent pas contrôler l'ordre d'affichage des chaînes sur l'écran d'accueil. Lorsque votre application crée une chaîne, celle-ci est ajoutée au bas de la liste des chaînes sur l'écran d'accueil. L'utilisateur peut réorganiser, masquer et afficher les chaînes.

La chaîne "Ma sélection"

La chaîne "Ma sélection" est la deuxième ligne de l'écran d'accueil, après la ligne des applications. Le système crée et gère cette chaîne. Votre application peut ajouter sur la chaîne "Ma sélection". Pour en savoir plus, consultez la section Ajouter des programmes à la chaîne "Ma sélection".

Versions de l'application

Les canaux créés par votre application suivent tous ce cycle de vie:

  1. L'utilisateur découvre une chaîne dans votre application et demande à l'ajouter à l'écran d'accueil.
  2. L'application crée la chaîne et l'ajoute à TvProvider (à ce stade, la chaîne n'est pas visible).
  3. L'application demande au système d'afficher la chaîne.
  4. Le système demande à l'utilisateur d'approuver la nouvelle chaîne.
  5. La nouvelle chaîne s'affiche sur la dernière ligne de l'écran d'accueil.

La chaîne par défaut

Votre appli peut proposer un nombre illimité de chaînes que l'utilisateur peut ajouter à son écran d'accueil. L'utilisateur doit généralement sélectionner et approuver chaque chaîne avant qu'elle n'apparaisse sur l'écran d'accueil. Chaque application a la possibilité de créer une chaîne par défaut. La chaîne par défaut est spéciale, car elle s'affiche automatiquement sur l'écran d'accueil. l'utilisateur n'a pas à le demander explicitement.

Prérequis

L'écran d'accueil d'Android TV utilise les API TvProvider d'Android pour gérer les chaînes et les programmes créés par votre application. Pour accéder aux données du fournisseur, ajoutez l'autorisation suivante au fichier manifeste de votre application:

<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />

La bibliothèque Support TvProvider facilite l'utilisation du fournisseur. Ajoutez-le aux dépendances dans votre fichier build.gradle:

Groovy

implementation 'androidx.tvprovider:tvprovider:1.0.0'

Kotlin

implementation("androidx.tvprovider:tvprovider:1.0.0")

Pour utiliser les chaînes et les programmes, assurez-vous d'inclure les fichiers de la bibliothèque Support suivants dans votre programme:

Kotlin

import android.support.media.tv.Channel
import android.support.media.tv.TvContractCompat
import android.support.media.tv.ChannelLogoUtils
import android.support.media.tv.PreviewProgram
import android.support.media.tv.WatchNextProgram

Java

import android.support.media.tv.Channel;
import android.support.media.tv.TvContractCompat;
import android.support.media.tv.ChannelLogoUtils;
import android.support.media.tv.PreviewProgram;
import android.support.media.tv.WatchNextProgram;

Chaînes

La première chaîne créée par votre application devient sa version par défaut. La chaîne par défaut s'affiche automatiquement sur l'écran d'accueil. Toutes les autres chaînes que vous créez doivent être sélectionnées et acceptées par l'utilisateur pour qu'elles apparaissent sur l'écran d'accueil.

Créer une chaîne

Votre application ne doit demander au système d'afficher les chaînes nouvellement ajoutées que lorsqu'elle s'exécute au premier plan. Cela empêche votre application d'afficher une boîte de dialogue demandant l'autorisation d'ajouter votre chaîne lorsque l'utilisateur exécute une autre application. Si vous essayez d'ajouter une chaîne exécutée en arrière-plan, la méthode onActivityResult() de l'activité renvoie le code d'état RESULT_CANCELED.

Pour créer une chaîne, procédez comme suit:

  1. Créez un outil de création de canaux et définissez ses attributs. Notez que le type de canal doit être TYPE_PREVIEW. Ajouter attributes selon les besoins.

    Kotlin

    val builder = Channel.Builder()
    // Every channel you create must have the type TYPE_PREVIEW
    builder.setType(TvContractCompat.Channels.TYPE_PREVIEW)
            .setDisplayName("Channel Name")
            .setAppLinkIntentUri(uri)
    

    Java

    Channel.Builder builder = new Channel.Builder();
    // Every channel you create must have the type TYPE_PREVIEW
    builder.setType(TvContractCompat.Channels.TYPE_PREVIEW)
            .setDisplayName("Channel Name")
            .setAppLinkIntentUri(uri);
    
  2. Insérez la chaîne dans le fournisseur:

    Kotlin

    var channelUri = context.contentResolver.insert(
            TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues())
    

    Java

    Uri channelUri = context.getContentResolver().insert(
            TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues());
    
  3. Vous devez enregistrer l'ID de la chaîne pour pouvoir y ajouter des programmes. plus tard. Extrayez l'ID du canal à partir de l'URI renvoyé:

    Kotlin

    var channelId = ContentUris.parseId(channelUri)
    

    Java

    long channelId = ContentUris.parseId(channelUri);
    
  4. Vous devez ajouter un logo pour votre chaîne. Utilisez un Uri ou un Bitmap. Le logo doit mesurer 80 dp x 80 dp et être opaque. Il s'affiche sous une masque circulaire:

    Masque de l&#39;icône de l&#39;écran d&#39;accueil TV

    Kotlin

    // Choose one or the other
    storeChannelLogo(context: Context, channelId: Long, logoUri: Uri) // also works if logoUri is a URL
    storeChannelLogo(context: Context, channelId: Long, logo: Bitmap)
    

    Java

    // Choose one or the other
    storeChannelLogo(Context context, long channelId, Uri logoUri); // also works if logoUri is a URL
    storeChannelLogo(Context context, long channelId, Bitmap logo);
    
  5. "Create the default channel" (Créer la version par défaut) (facultatif): lorsque votre application crée sa première vous pouvez en faire chaîne par défaut pour qu'elle s'affiche sur la page d'accueil sans intervention de l'utilisateur. Toutes les autres chaînes que vous créez ne sont pas visibles tant que l'utilisateur n'a pas les sélectionne.

    Kotlin

    TvContractCompat.requestChannelBrowsable(context, channelId)
    

    Java

    TvContractCompat.requestChannelBrowsable(context, channelId);
    

  6. Affichez votre chaîne par défaut avant l'ouverture de votre application. Vous pouvez pour que ce comportement se produise en ajoutant un BroadcastReceiver qui écoute l'événement android.media.tv.action.INITIALIZE_PROGRAMS, qui s'affiche sur l'écran d'accueil envoie après l'installation de l'application:
    <receiver
      android:name=".RunOnInstallReceiver"
      android:exported="true">
        <intent-filter>
          <action android:name="android.media.tv.action.INITIALIZE_PROGRAMS" />
          <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>
    
    Si vous téléchargez votre application indépendamment pendant le développement, vous pouvez tester cette étape en déclencher l'intent via adb, où your.package.name/.YourReceiverName correspond à la valeur BroadcastReceiver:

    adb shell am broadcast -a android.media.tv.action.INITIALIZE_PROGRAMS -n \
        your.package.name/.YourReceiverName
    

    Dans de rares cas, votre application peut recevoir la diffusion en même temps que l'utilisateur lance votre application. Assurez-vous que votre code ne tente pas d'ajouter la chaîne par défaut plusieurs fois.

Mettre à jour une chaîne

Le processus de mise à jour et de création d'une chaîne est très semblable.

Utilisez un autre Channel.Builder pour définir les attributs à modifier.

Utilisez ContentResolver pour mettre à jour le canal. Utilisez l'ID de chaîne que vous avez enregistré lors de son ajout initial:

Kotlin

context.contentResolver.update(
        TvContractCompat.buildChannelUri(channelId),
        builder.build().toContentValues(),
        null,
        null
)

Java

context.getContentResolver().update(TvContractCompat.buildChannelUri(channelId),
    builder.build().toContentValues(), null, null);

Pour modifier le logo d'une chaîne, utilisez storeChannelLogo().

Supprimer une chaîne

Kotlin

context.contentResolver.delete(TvContractCompat.buildChannelUri(channelId), null, null)

Java

context.getContentResolver().delete(TvContractCompat.buildChannelUri(channelId), null, null);

Programmes

Ajouter des programmes à une chaîne d'application

Créez un PreviewProgram.Builder et définissez ses attributs:

Kotlin

val builder = PreviewProgram.Builder()
builder.setChannelId(channelId)
        .setType(TvContractCompat.PreviewPrograms.TYPE_CLIP)
        .setTitle("Title")
        .setDescription("Program description")
        .setPosterArtUri(uri)
        .setIntentUri(uri)
        .setInternalProviderId(appProgramId)

Java

PreviewProgram.Builder builder = new PreviewProgram.Builder();
builder.setChannelId(channelId)
        .setType(TvContractCompat.PreviewPrograms.TYPE_CLIP)
        .setTitle("Title")
        .setDescription("Program description")
        .setPosterArtUri(uri)
        .setIntentUri(uri)
        .setInternalProviderId(appProgramId);

Ajoutez d'autres attributs selon le type de programme. (Pour afficher les attributs disponibles pour chaque type de programme, consultez les tableaux ci-dessous.)

Insérez le programme dans le fournisseur:

Kotlin

var programUri = context.contentResolver.insert(TvContractCompat.PreviewPrograms.CONTENT_URI,
        builder.build().toContentValues())

Java

Uri programUri = context.getContentResolver().insert(TvContractCompat.PreviewPrograms.CONTENT_URI,
      builder.build().toContentValues());

Récupérez l'ID du programme pour référence ultérieure:

Kotlin

val programId = ContentUris.parseId(programUri)

Java

long programId = ContentUris.parseId(programUri);

Ajouter des programmes à la chaîne "Ma sélection"

Pour insérer des programmes dans la chaîne "Ma sélection", consultez l'article Ajouter des programmes à la chaîne Watch Next. Canal suivant.

Mettre à jour un programme

Vous pouvez modifier les informations d'un programme. Vous pouvez, par exemple, mettre à jour le prix de location d'un film ou afficher une barre de progression indiquant la durée de visionnage d'un programme par l'utilisateur.

Utilisez un PreviewProgram.Builder pour définir les attributs à modifier. Ensuite, appelez getContentResolver().update pour mettre à jour le programme. Indiquez l'ID de programme que vous avez enregistré lors de l'ajout initial du programme:

Kotlin

context.contentResolver.update(
        TvContractCompat.buildPreviewProgramUri(programId),
                builder.build().toContentValues(), null, null
)

Java

context.getContentResolver().update(TvContractCompat.buildPreviewProgramUri(programId),
    builder.build().toContentValues(), null, null);

Supprimer un programme

Kotlin

context.contentResolver
        .delete(TvContractCompat.buildPreviewProgramUri(programId), null, null)

Java

context.getContentResolver().delete(TvContractCompat.buildPreviewProgramUri(programId), null, null);

Gérer les actions des utilisateurs

Votre application peut aider les utilisateurs à découvrir du contenu en fournissant une UI permettant d'afficher et d'ajouter des chaînes. Votre application doit également gérer les interactions avec vos chaînes une fois qu'elles apparaissent sur l'écran d'accueil.

Découvrir et ajouter des chaînes

Votre application peut fournir un élément d'interface utilisateur qui permet à l'utilisateur de sélectionner et d'ajouter ses chaînes (par exemple, un bouton qui demande à ajouter la chaîne).

Une fois que l'utilisateur a demandé une chaîne spécifique, exécutez ce code pour obtenir l'autorisation de l'ajouter à l'interface utilisateur de l'écran d'accueil:

Kotlin

val intent = Intent(TvContractCompat.ACTION_REQUEST_CHANNEL_BROWSABLE)
intent.putExtra(TvContractCompat.EXTRA_CHANNEL_ID, channelId)
try {
  activity.startActivityForResult(intent, 0)
} catch (e: ActivityNotFoundException) {
  // handle error
}

Java

Intent intent = new Intent(TvContractCompat.ACTION_REQUEST_CHANNEL_BROWSABLE);
intent.putExtra(TvContractCompat.EXTRA_CHANNEL_ID, channelId);
try {
   activity.startActivityForResult(intent, 0);
} catch (ActivityNotFoundException e) {
  // handle error
}

Le système affiche une boîte de dialogue demandant à l'utilisateur d'approuver la chaîne. Gérez le résultat de la requête dans la méthode onActivityResult de votre activité (Activity.RESULT_CANCELED ou Activity.RESULT_OK).

Événements sur l'écran d'accueil d'Android TV

Lorsque l'utilisateur interagit avec les programmes ou les chaînes publiés par l'application, l'écran d'accueil envoie des intents à l'application:

  • L'écran d'accueil envoie à l'application l'élément Uri stocké dans l'attribut APP_LINK_INTENT_URI d'une chaîne lorsque l'utilisateur sélectionne le logo de la chaîne. L'application doit simplement lancer son interface utilisateur principale ou une vue liée à la chaîne sélectionnée.
  • L'écran d'accueil envoie à l'application le Uri stocké dans l'attribut INTENT_URI d'un programme lorsque l'utilisateur sélectionne un programme. L'application doit lire le contenu sélectionné.
  • L'utilisateur peut indiquer qu'il n'est plus intéressé par un programme et qu'il souhaite le supprimer de l'interface utilisateur de l'écran d'accueil. Le système supprime le programme de l'interface utilisateur et envoie à l'application propriétaire un intent (android.media.tv.ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED ou android.media.tv.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED) avec l'ID du programme. L'application doit supprimer le programme du fournisseur et NE doit PAS le réinsérer.

Veillez à créer des filtres d'intent pour tous les Uris que l'écran d'accueil envoie pour les interactions utilisateur. Par exemple:

<receiver
   android:name=".WatchNextProgramRemoved"
   android:enabled="true"
   android:exported="true">
   <intent-filter>
       <action android:name="android.media.tv.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED" />
   </intent-filter>
</receiver>

Bonnes pratiques

  • De nombreuses applications TV nécessitent la connexion des utilisateurs. Dans ce cas, le BroadcastReceiver qui écoute android.media.tv.action.INITIALIZE_PROGRAMS devrait suggérer le contenu du canal pour les utilisateurs non authentifiés.Par exemple, votre application peut initialement afficher les meilleurs contenus ou ceux actuellement populaires. Une fois l'utilisateur connecté, peuvent afficher des contenus personnalisés. C'est une excellente occasion pour les applications de vendre la gamme supérieure avant qu'ils ne se connectent.
  • Lorsque votre application n'est pas au premier plan et que vous devez mettre à jour une version ou un programme, utilisez le JobScheduler pour planifier le travail (voir: JobScheduler et JobService).
  • Le système peut révoquer les autorisations du fournisseur de votre appli en cas de dysfonctionnement (par exemple, en envoyant continuellement des données au fournisseur). Assurez-vous que encapsuler le code qui accède au fournisseur avec des clauses try-catch pour gérer des exceptions de sécurité.
  • Avant de mettre à jour vos programmes et vos chaînes, demandez au fournisseur les données que vous devez mettre à jour et rapprocher les données. Par exemple, il n'est pas nécessaire de mettre à jour un programme que l'utilisateur souhaite supprimer de l'interface utilisateur. Utilisez une tâche d'arrière-plan qui insère/met à jour vos données dans le fournisseur après avoir interrogé des données, puis demandez l'approbation de vos chaînes. Vous pouvez exécuter ce job l'application démarre et chaque fois que l'application doit mettre à jour ses données.

    Kotlin

    context.contentResolver
      .query(
          TvContractCompat.buildChannelUri(channelId),
              null, null, null, null).use({
                  cursor-> if (cursor != null and cursor.moveToNext()) {
                               val channel = Channel.fromCursor(cursor)
                               if (channel.isBrowsable()) {
                                   //update channel's programs
                               }
                           }
              })
    

    Java

    try (Cursor cursor = context.getContentResolver()
          .query(
              TvContractCompat.buildChannelUri(channelId),
              null,
              null,
              null,
              null)) {
                  if (cursor != null && cursor.moveToNext()) {
                      Channel channel = Channel.fromCursor(cursor);
                      if (channel.isBrowsable()) {
                          //update channel's programs
                      }
                  }
              }
    
  • Utilisez des URI uniques pour toutes les images (logos, icônes et images de contenu). Veillez à utiliser un autre URI lorsque vous mettez à jour une image. Toutes les images sont mises en cache. Si vous ne modifiez pas l'URI lorsque vous changez l'image, l'ancienne image continuera d'apparaître.

  • N'oubliez pas que les clauses WHERE ne sont pas autorisées et que les appels vers les fournisseurs contenant ces clauses génèrent une exception de sécurité.

Attributs

Cette section décrit séparément les attributs de chaîne et de programme.

Attributs du canal

Vous devez spécifier les attributs suivants pour chaque chaîne:

Attribut Notes
MACH définie sur TYPE_PREVIEW.
NOM_DISPLAY défini sur le nom de la chaîne.
APP_LINK_INTENT_URI Lorsque l'utilisateur sélectionne le logo de la chaîne, le système envoie une intention pour lancer une activité qui présente du contenu pertinent pour la chaîne. Définissez cet attribut sur l'URI utilisé dans le filtre d'intent de cette activité.

En outre, un canal comporte six champs réservés à une utilisation interne des applications. Ces champs peuvent être utilisés pour stocker des clés ou d'autres valeurs qui peuvent aider l'application à mapper le canal avec sa structure de données interne:

  • INTERNAL_PROVIDER_ID
  • INTERNAL_PROVIDER_DATA
  • INTERNAL_PROVIDER_FLAG1
  • INTERNAL_PROVIDER_FLAG2
  • INTERNAL_PROVIDER_FLAG3
  • INTERNAL_PROVIDER_FLAG4

Attributs du programme

Consultez les pages individuelles pour connaître les attributs de chaque type de programme:

Exemple de code

Pour savoir comment créer des applications qui interagissent avec l'écran d'accueil, et pour ajouter des chaînes et des programmes à l'écran d'accueil d'Android TV, consultez l'atelier de programmation sur cet écran.