Chaînes sur l'écran d'accueil

L'écran d'accueil Android TV 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 disponible sur cette chaîne :

Écran d'accueil Android TV
Écran d'accueil Android TV

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

Interface utilisateur de l'écran d'accueil

Les applications peuvent créer des chaînes, ajouter, supprimer et mettre à jour les programmes d'une chaîne, et contrôler l'ordre des programmes dans une chaîne. Par exemple, une application peut créer une chaîne appelée "Nouveautés" et afficher des fiches pour les programmes récemment disponibles.

Les applications ne peuvent pas contrôler l'ordre dans lequel les chaînes apparaissent sur l'écran d'accueil. Lorsque votre application crée une chaîne, l'écran d'accueil l'ajoute en bas de la liste des chaînes. L'utilisateur peut réorganiser, masquer et afficher les chaînes.

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

Chaînes d'applications

Les chaînes créées par votre application suivent toutes 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 apparaît dans la dernière ligne de l'écran d'accueil.

Chaîne par défaut

Votre application peut proposer un nombre illimité de chaînes que l'utilisateur peut ajouter à son écran d'accueil. Une chaîne doit généralement être sélectionnée et approuvée par l'utilisateur pour s'afficher 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 sans intervention explicite de l'utilisateur.

Prérequis

L'écran d'accueil 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 de support TvProvider facilite l'utilisation du fournisseur. Ajoutez-la 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èque de 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

La première chaîne créée par votre application devient sa chaîne 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 avant de pouvoir s'afficher 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 pendant que l'utilisateur exécute une autre application. Si vous essayez d'ajouter une chaîne 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 générateur de chaînes et définissez ses attributs. Notez que le type de chaîne 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 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 ultérieurement. Extrayez l'ID de la chaîne de l'URI renvoyée :

    Kotlin

    var channelId = ContentUris.parseId(channelUri)
    

    Java

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

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

    Kotlin

    TvContractCompat.requestChannelBrowsable(context, channelId)
    

    Java

    TvContractCompat.requestChannelBrowsable(context, channelId);
    
  6. Faites en sorte que votre chaîne par défaut s'affiche avant l'ouverture de votre application. Pour ce faire, ajoutez 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 chargez votre application de manière latérale pendant le développement, vous pouvez tester cette étape en déclenchant l'intent via adb, où your.package.name/.YourReceiverName est le 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 en même temps que l'utilisateur la démarre. Assurez-vous que votre code n'essaie pas d'ajouter la chaîne par défaut plus d'une fois.

Mettre à jour une chaîne

La mise à jour des chaînes est très semblable à leur création.

Utilisez un autre 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 l'ajout initial de la chaîne :

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 mettre à jour 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

Les programmes sont les fiches de contenu individuelles affichées dans une chaîne. Vous pouvez publier des programmes à la fois sur les chaînes personnalisées de votre application et sur la chaîne "Ma sélection" gérée par le système.

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 en fonction du 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 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 modifier le prix de location d'un film ou mettre à jour 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, puis appelez getContentResolver().update pour mettre à jour le programme. Spécifiez l'ID du 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 de l'utilisateur

Votre application peut aider les utilisateurs à découvrir du contenu en fournissant une interface utilisateur pour afficher et 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 d'ajouter la chaîne).

Une fois que l'utilisateur a demandé une chaîne spécifique, exécutez ce code pour obtenir son autorisation afin 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 et les chaînes publiés par l'application, l'écran d'accueil envoie des intents à l'application :

  • L'écran d'accueil envoie l'Uri stockée dans l'attribut APP_LINK_INTENT_URI d'une chaîne à l'application lorsque l'utilisateur sélectionne le logo de la chaîne. L'application doit simplement lancer son interface utilisateur principale ou une vue associée à la chaîne sélectionnée.
  • L'écran d'accueil envoie l'Uri stockée dans l'attribut INTENT_URI d'un programme à l'application 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 du programme 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 de l'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>

Informations complémentaires

  • 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 initialement afficher le meilleur contenu ou le contenu actuellement populaire. Une fois que l'utilisateur s'est connecté, elle peut afficher du contenu personnalisé. C'est une excellente occasion pour les applications de vendre des produits aux utilisateurs avant qu'ils ne se connectent.
  • Lorsque votre application n'est pas au premier plan et que vous devez mettre à jour une chaîne ou un programme, utilisez JobScheduler pour planifier le travail (voir JobScheduler et JobService).
  • Le système peut révoquer les autorisations de fournisseur de votre application si elle se comporte mal (par exemple, en spammant continuellement le fournisseur avec des données). Assurez-vous d'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 des programmes et des chaînes, interrogez le fournisseur pour obtenir les données à mettre à jour et réconciliez-les. 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 en arrière-plan qui insère ou met à jour vos données dans le fournisseur après avoir interrogé les données existantes, puis demandé l'approbation de vos chaînes. Vous pouvez exécuter cette tâche au démarrage de l'application et chaque fois qu'elle 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 &amp;&amp; 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 URI différent lorsque vous mettez à jour une image. Toutes les images sont mises en cache. Si vous ne modifiez pas l'URI lorsque vous modifiez l'image, l'ancienne image continuera à 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 les attributs de la chaîne et du programme séparément.

Attributs de la chaîne

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

Attribut Remarques
TYPE défini sur TYPE_PREVIEW.
DISPLAY_NAME 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 un intent pour démarrer 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 également six champs réservés à l'utilisation interne de l'application. Ces champs peuvent être utilisés pour stocker des clés ou d'autres valeurs qui peuvent aider l'application à mapper la chaîne à 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 en savoir plus sur la création d'applications qui interagissent avec l'écran d'accueil et ajoutent des chaînes et des programmes à l'écran d'accueil Android TV, consultez notre atelier de programmation sur l'écran d'accueil codelab.