Chaînes sur l'écran d'accueil

L'écran d'accueil d'Android TV, ou simplement l'écran d'accueil, fournit une interface utilisateur qui affiche le contenu recommandé 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 tous les programmes qu'elle propose:

Écran d'accueil de la TV

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

Remarque:Les canaux de recommandations ne sont disponibles que sur Android 8.0 (niveau d'API 26) ou version ultérieure. Vous devez les utiliser pour fournir des recommandations pour les applications exécutées sur Android 8.0 (niveau d'API 26) ou version ultérieure. Afin de fournir des recommandations pour les applications exécutées sur des versions antérieures d'Android, votre application doit plutôt utiliser la ligne de recommandations.

UI de l'écran d'accueil

Les applications permettent de créer des chaînes, d'ajouter, de supprimer et de mettre à jour les programmes d'une chaîne, et de contrôler l'ordre des programmes sur une chaîne. Par exemple, une application peut créer une chaîne intitulée "Nouveautés" et afficher des fiches sur les nouveaux programmes disponibles.

Les applications ne peuvent pas contrôler l'ordre dans lequel les chaînes s'affichent sur l'écran d'accueil. Lorsque votre application crée une chaîne, l'écran d'accueil l'ajoute au bas de la liste des chaînes. 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 qui s'affiche sur 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 des programmes à la chaîne "Ma sélection". Pour en savoir plus, consultez Ajouter des programmes à la chaîne "Ma sélection".

Canaux d'application

Tous les canaux créés par votre application suivent 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.

Canal 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 pour qu'elle apparaisse sur l'écran d'accueil. Chaque application a la possibilité de créer une chaîne par défaut. La version par défaut est spéciale, car elle apparaît automatiquement sur l'écran d'accueil. L'utilisateur n'a pas besoin de la demander explicitement.

Conditions préalables

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 des chaînes et des programmes, veillez à inclure les importations de bibliothèques Support suivantes 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

Le premier canal créé par votre application devient le canal 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 doit demander au système d'afficher les chaînes nouvellement ajoutées uniquement 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 alors que l'application est 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. Ajoutez d'autres attributs si nécessaire.

    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 le canal 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 y ajouter des programmes ultérieurement. Extrayez l'ID du canal 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. L'icône du logo doit être de 80 × 80 dp et opaque. Il s'affiche sous un masque circulaire:

    Masque d&#39;icône de l&#39;écran d&#39;accueil du téléviseur

    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. Créer la version par défaut (facultatif): lorsque votre application crée sa première version, vous pouvez en faire la version par défaut afin qu'elle apparaisse immédiatement sur l'écran d'accueil sans aucune action de l'utilisateur. Les autres canaux que vous créez ne sont pas visibles tant que l'utilisateur ne les sélectionne pas explicitement.

    Kotlin

    TvContractCompat.requestChannelBrowsable(context, channelId)
    

    Java

    TvContractCompat.requestChannelBrowsable(context, channelId);
    

  6. Affichez votre canal par défaut avant l'ouverture de votre application. Pour que ce comportement se produise, vous pouvez ajouter un BroadcastReceiver qui écoute l'action android.media.tv.action.INITIALIZE_PROGRAMS, que 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>
    
    Lorsque vous téléchargez votre application de manière indépendante pendant le développement, vous pouvez tester cette étape en déclenchant l'intent via adb, où your.package.name/.YourReceiverName correspond au BroadcastReceiver de votre application:

    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 au même moment que l'utilisateur la lance. Assurez-vous que votre code n'essaie pas d'ajouter le canal par défaut plusieurs fois.

Mettre à jour une chaîne

La procédure à suivre pour mettre à jour des chaînes est très similaire à leur création.

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

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

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 une 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 en fonction du type de programme. Pour connaître 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 vous y référer ultérieurement:

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 à la chaîne "Ma sélection", consultez Ajouter des programmes à la chaîne "Ma sélection".

Mettre à jour un programme

Vous pouvez modifier les informations d'un programme. Par exemple, vous pouvez mettre à jour le prix de location d'un film ou 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 que vous devez modifier, puis appelez getContentResolver().update pour mettre à jour le programme. Indiquez l'ID du programme que vous avez enregistré lors de son ajout initial:

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 des contenus en fournissant une UI pour afficher et ajouter des canaux. 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 canaux (par exemple, un bouton demandant à ajouter le canal).

Une fois que l'utilisateur a demandé un canal spécifique, exécutez ce code pour obtenir l'autorisation de l'utilisateur 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 de l'écran d'accueil Android TV

Lorsque l'utilisateur interagit avec les programmes/canaux publiés par l'application, l'écran d'accueil envoie des intents à l'application:

  • L'écran d'accueil envoie à l'application le 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'appli devrait 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 un intent à l'application propriétaire du programme (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 PAS le réinsérer.

Veillez à créer des filtres d'intent pour tous les Uris envoyés par l'écran d'accueil 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 que les utilisateurs se connectent. Dans ce cas, le BroadcastReceiver qui écoute android.media.tv.action.INITIALIZE_PROGRAMS doit suggérer du contenu de chaîne pour les utilisateurs non authentifiés.Par exemple, votre application peut d'abord afficher le meilleur contenu ou le contenu actuellement populaire. Une fois connecté, l'utilisateur peut afficher du contenu personnalisé. C'est une excellente occasion pour les applications de vendre la gamme supérieure aux utilisateurs avant qu'ils se connectent.
  • Lorsque votre application n'est pas au premier plan et que vous devez mettre à jour un canal ou un programme, utilisez JobScheduler pour planifier le travail (consultez JobScheduler et JobService).
  • Le système peut révoquer les autorisations du fournisseur de votre application en cas de dysfonctionnement de celle-ci (par exemple, si elle envoie continuellement du spam au fournisseur avec des données). Veillez à encapsuler le code qui accède au fournisseur avec des clauses try-catch pour gérer les exceptions de sécurité.
  • Avant de mettre à jour les programmes et les chaînes, demandez au fournisseur les données dont vous avez besoin pour 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é les données existantes, puis demandé l'approbation de vos canaux. Vous pouvez exécuter cette tâche au démarrage de l'application 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, images de contenu). Veillez à utiliser un autre URI lorsque vous modifiez 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 de s'afficher.

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

Attributs

Cette section décrit séparément les attributs des chaînes et des programmes.

Attributs de la chaîne

Vous devez spécifier les attributs suivants pour chaque canal:

Attribut Notes
TYPE défini sur TYPE_PREVIEW.
NOM DE L'AFFICHAGE défini sur le nom du critère.
INTENT_URI APP_LINK 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 pour cette activité.

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

  • ID DU FOURNISSEUR INTERNE
  • DONNÉES_FOURNISSEURS INTERNES
  • INTERNAL_PROVIDER_FLAG1
  • INTERNAL_PROVIDER_FLAG2
  • INTERNAL_PROVIDER_FLAG3
  • INTERNAL_PROVIDER_FLAG4

Attributs du programme

Consultez les pages individuelles des attributs de chaque type de programme:

Exemple de code

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