Recommandations dans Android N et les versions antérieures

Lorsqu'ils interagissent avec un téléviseur, les utilisateurs préfèrent généralement donner un minimum d'informations avant de regarder contenus. Le scénario idéal pour de nombreux téléspectateurs est le suivant: s'asseoir, allumer et regarder. Le moins d'étapes pour rediriger les utilisateurs vers le contenu qu'ils apprécient est généralement la méthode qu'ils préfèrent.

Remarque:Utilisez les API décrites ici pour émettre des recommandations. dans les applications fonctionnant sous Android 7.1 (niveau d'API 25) inclus uniquement. Pour fournir recommandations pour les applications fonctionnant sous Android 8.0 (niveau d'API 26) ou version ultérieure, votre application doit utiliser canaux de recommandation.

Le framework Android facilite l'interaction en entrée en fournissant une ligne de recommandations. sur l'écran d'accueil. Les recommandations de contenus s'affichent sur la première ligne de l'écran d'accueil du téléviseur après la première utilisation de l’appareil. Contribuer aux recommandations du catalogue de contenu de votre application peut aider inciter les utilisateurs à revenir vers votre application.

Figure 1 : Exemple de ligne de recommandations.

Ce guide vous explique comment créer des recommandations et les transmettre au framework Android. pour que les utilisateurs puissent facilement découvrir et profiter du contenu de votre application. Consultez également l'exemple d'implémentation dans la <ph type="x-smartling-placeholder"></ph> Exemple d'application Leanback pour en savoir plus.

Bonnes pratiques en matière de recommandations

Les recommandations aident les utilisateurs à trouver rapidement les contenus et les applications qu'ils apprécient. Création... de haute qualité et pertinentes pour les utilisateurs est un facteur important une excellente expérience utilisateur avec votre application TV. C'est pourquoi vous devez bien réfléchir recommandations que vous présentez à l'utilisateur et les gérez de près.

Types de recommandations

Lorsque vous créez des recommandations, vous devez rediriger les utilisateurs vers des activités de visionnage incomplètes ou suggèrent des activités qui étendent cela à du contenu associé. Voici quelques types spécifiques recommandations à prendre en compte:

  • Recommandations de contenus complémentaires pour l'épisode suivant que les utilisateurs peuvent reprendre regarder une série. Vous pouvez également utiliser les recommandations de continuation pour les films, séries TV ou podcasts mis en pause afin que les utilisateurs puissent reprendre le visionnage d'un contenu mis en pause en quelques clics.
  • Des recommandations de nouveaux contenus, comme un nouvel épisode en première diffusion, si l'utilisateur fini de regarder une autre série. De plus, si votre application permet aux utilisateurs de s'abonner à contenus, utiliser les recommandations de nouveaux contenus pour les éléments non regardés de sa liste de contenus suivis.
  • Recommandations de contenus associés en fonction des utilisateurs les historiques de visionnage.

Pour en savoir plus sur la conception de fiches de recommandations afin d'optimiser l'expérience utilisateur, consultez Ligne "Recommendation" dans les spécifications de conception Android TV.

Actualiser les recommandations

Lorsque vous actualisez les recommandations, ne vous contentez pas de les supprimer et de les republier, les recommandations s'affichent à la fin de la ligne correspondante. Une fois qu'un élément de contenu, par exemple film, a été lu, la supprimer des recommandations.

Personnaliser les recommandations

Vous pouvez personnaliser les fiches de recommandation pour transmettre des informations sur le branding en définissant l'interface utilisateur tels que l'image de premier plan et d'arrière-plan, la couleur, l'icône de l'application, le titre et le sous-titre. Pour en savoir plus, consultez Ligne "Recommendation" dans les spécifications de conception Android TV.

Recommandations de groupes

Vous pouvez éventuellement regrouper les recommandations en fonction de leur source. Par exemple, votre application peut fournir deux groupes de recommandations: des recommandations de contenus auxquels l'utilisateur est abonné, et des recommandations de nouveaux contenus tendance que l'utilisateur ne connaît peut-être pas.

Le système classe et ordonne les recommandations pour chaque groupe séparément lors de la création ou de la mise à jour sur la ligne de recommandation. En fournissant des informations de groupe pour vos recommandations, vous vous assurez que vos recommandations ne s'affichent pas en dessous de celles sans rapport.

Utilisez NotificationCompat.Builder.setGroup() pour définir la chaîne de clé de groupe d'une recommandation. Pour Par exemple, pour indiquer qu'une recommandation appartient à un groupe qui contient de nouveaux contenus tendance, vous pouvez appeler setGroup("trending").

Créer un service de recommandations

Les recommandations de contenu sont créées avec le traitement en arrière-plan. Pour que votre application contribuent aux recommandations, créez un service qui ajoute régulièrement des listes le catalogue de l'application à la liste des recommandations du système.

L'exemple de code suivant montre comment étendre IntentService à créez un service de recommandation pour votre application:

Kotlin

class UpdateRecommendationsService : IntentService("RecommendationService") {
    override protected fun onHandleIntent(intent: Intent) {
        Log.d(TAG, "Updating recommendation cards")
        val recommendations = VideoProvider.getMovieList()
        if (recommendations == null) return

        var count = 0

        try {
            val builder = RecommendationBuilder()
                    .setContext(applicationContext)
                    .setSmallIcon(R.drawable.videos_by_google_icon)

            for (entry in recommendations.entrySet()) {
                for (movie in entry.getValue()) {
                    Log.d(TAG, "Recommendation - " + movie.getTitle())

                    builder.setBackground(movie.getCardImageUrl())
                            .setId(count + 1)
                            .setPriority(MAX_RECOMMENDATIONS - count)
                            .setTitle(movie.getTitle())
                            .setDescription(getString(R.string.popular_header))
                            .setImage(movie.getCardImageUrl())
                            .setIntent(buildPendingIntent(movie))
                            .build()
                    if (++count >= MAX_RECOMMENDATIONS) {
                        break
                    }
                }
                if (++count >= MAX_RECOMMENDATIONS) {
                    break
                }
            }
        } catch (e: IOException) {
            Log.e(TAG, "Unable to update recommendation", e)
        }
    }

    private fun buildPendingIntent(movie: Movie): PendingIntent {
        val detailsIntent = Intent(this, DetailsActivity::class.java)
        detailsIntent.putExtra("Movie", movie)

        val stackBuilder = TaskStackBuilder.create(this)
        stackBuilder.addParentStack(DetailsActivity::class.java)
        stackBuilder.addNextIntent(detailsIntent)

        // Ensure a unique PendingIntents, otherwise all
        // recommendations end up with the same PendingIntent
        detailsIntent.setAction(movie.getId().toString())

        val intent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
        return intent
    }

    companion object {
        private val TAG = "UpdateRecommendationsService"
        private val MAX_RECOMMENDATIONS = 3
    }
}

Java

public class UpdateRecommendationsService extends IntentService {
    private static final String TAG = "UpdateRecommendationsService";
    private static final int MAX_RECOMMENDATIONS = 3;

    public UpdateRecommendationsService() {
        super("RecommendationService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.d(TAG, "Updating recommendation cards");
        HashMap<String, List<Movie>> recommendations = VideoProvider.getMovieList();
        if (recommendations == null) return;

        int count = 0;

        try {
            RecommendationBuilder builder = new RecommendationBuilder()
                    .setContext(getApplicationContext())
                    .setSmallIcon(R.drawable.videos_by_google_icon);

            for (Map.Entry<String, List<Movie>> entry : recommendations.entrySet()) {
                for (Movie movie : entry.getValue()) {
                    Log.d(TAG, "Recommendation - " + movie.getTitle());

                    builder.setBackground(movie.getCardImageUrl())
                            .setId(count + 1)
                            .setPriority(MAX_RECOMMENDATIONS - count)
                            .setTitle(movie.getTitle())
                            .setDescription(getString(R.string.popular_header))
                            .setImage(movie.getCardImageUrl())
                            .setIntent(buildPendingIntent(movie))
                            .build();

                    if (++count >= MAX_RECOMMENDATIONS) {
                        break;
                    }
                }
                if (++count >= MAX_RECOMMENDATIONS) {
                    break;
                }
            }
        } catch (IOException e) {
            Log.e(TAG, "Unable to update recommendation", e);
        }
    }

    private PendingIntent buildPendingIntent(Movie movie) {
        Intent detailsIntent = new Intent(this, DetailsActivity.class);
        detailsIntent.putExtra("Movie", movie);

        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        stackBuilder.addParentStack(DetailsActivity.class);
        stackBuilder.addNextIntent(detailsIntent);
        // Ensure a unique PendingIntents, otherwise all
        // recommendations end up with the same PendingIntent
        detailsIntent.setAction(Long.toString(movie.getId()));

        PendingIntent intent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        return intent;
    }
}

Pour que ce service soit reconnu et exécuté par le système, enregistrez-le à l'aide de votre fichier manifeste d'application. L'extrait de code suivant montre comment déclarer cette classe en tant que service:

<manifest ... >
  <application ... >
    ...

    <service
            android:name="com.example.android.tvleanback.UpdateRecommendationsService"
            android:enabled="true" />
  </application>
</manifest>

Créer des recommandations

Une fois que votre service de recommandations est lancé, il doit créer des recommandations et les transmettre à le framework Android. Le framework reçoit les recommandations sous la forme d'objets Notification qui utilisent un modèle spécifique et qui sont marqués d'un catégorie.

Définir les valeurs

Pour définir les valeurs des éléments d'interface utilisateur pour la fiche de recommandation, vous devez créer une classe de compilateur qui suit le schéma de compilateur décrit ci-dessous. Vous définissez d'abord les valeurs de la fiche de recommandation éléments.

Kotlin

class RecommendationBuilder {
    ...

    fun setTitle(title: String): RecommendationBuilder {
        this.title = title
        return this
    }

    fun setDescription(description: String): RecommendationBuilder {
        this.description = description
        return this
    }

    fun setImage(uri: String): RecommendationBuilder {
        imageUri = uri
        return this
    }

    fun setBackground(uri: String): RecommendationBuilder {
        backgroundUri = uri
        return this
    }

...

Java

public class RecommendationBuilder {
    ...

    public RecommendationBuilder setTitle(String title) {
            this.title = title;
            return this;
        }

        public RecommendationBuilder setDescription(String description) {
            this.description = description;
            return this;
        }

        public RecommendationBuilder setImage(String uri) {
            imageUri = uri;
            return this;
        }

        public RecommendationBuilder setBackground(String uri) {
            backgroundUri = uri;
            return this;
        }
...

Créer la notification

Une fois les valeurs définies, créez la notification en attribuant les valeurs à partir du compilateur. à la notification, puis appelez NotificationCompat.Builder.build().

N'oubliez pas d'appeler setLocalOnly() pour que la notification NotificationCompat.BigPictureStyle ne s'affiche pas sur d'autres appareils.

L'exemple de code suivant montre comment créer une recommandation.

Kotlin

class RecommendationBuilder {
    ...

    @Throws(IOException::class)
    fun build(): Notification {
        ...

        val notification = NotificationCompat.BigPictureStyle(
        NotificationCompat.Builder(context)
                .setContentTitle(title)
                .setContentText(description)
                .setPriority(priority)
                .setLocalOnly(true)
                .setOngoing(true)
                .setColor(context.resources.getColor(R.color.fastlane_background))
                .setCategory(Notification.CATEGORY_RECOMMENDATION)
                .setLargeIcon(image)
                .setSmallIcon(smallIcon)
                .setContentIntent(intent)
                .setExtras(extras))
                .build()

        return notification
    }
}

Java

public class RecommendationBuilder {
    ...

    public Notification build() throws IOException {
        ...

        Notification notification = new NotificationCompat.BigPictureStyle(
                new NotificationCompat.Builder(context)
                        .setContentTitle(title)
                        .setContentText(description)
                        .setPriority(priority)
                        .setLocalOnly(true)
                        .setOngoing(true)
                        .setColor(context.getResources().getColor(R.color.fastlane_background))
                        .setCategory(Notification.CATEGORY_RECOMMENDATION)
                        .setLargeIcon(image)
                        .setSmallIcon(smallIcon)
                        .setContentIntent(intent)
                        .setExtras(extras))
                .build();

        return notification;
    }
}

Service de recommandations d'exécution

Le service de recommandation de votre application doit s'exécuter régulièrement pour créer recommandations. Pour exécuter votre service, créez une classe qui exécute un minuteur et appelle à intervalles réguliers. L'exemple de code suivant étend la classe BroadcastReceiver pour démarrer l'exécution périodique d'un service de recommandation toutes les demi-heures:

Kotlin

class BootupActivity : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        Log.d(TAG, "BootupActivity initiated")
        if (intent.action.endsWith(Intent.ACTION_BOOT_COMPLETED)) {
            scheduleRecommendationUpdate(context)
        }
    }

    private fun scheduleRecommendationUpdate(context: Context) {
        Log.d(TAG, "Scheduling recommendations update")
        val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        val recommendationIntent = Intent(context, UpdateRecommendationsService::class.java)
        val alarmIntent = PendingIntent.getService(context, 0, recommendationIntent, 0)
        alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                INITIAL_DELAY,
                AlarmManager.INTERVAL_HALF_HOUR,
                alarmIntent
        )
    }

    companion object {
        private val TAG = "BootupActivity"
        private val INITIAL_DELAY:Long = 5000
    }
}

Java

public class BootupActivity extends BroadcastReceiver {
    private static final String TAG = "BootupActivity";

    private static final long INITIAL_DELAY = 5000;

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "BootupActivity initiated");
        if (intent.getAction().endsWith(Intent.ACTION_BOOT_COMPLETED)) {
            scheduleRecommendationUpdate(context);
        }
    }

    private void scheduleRecommendationUpdate(Context context) {
        Log.d(TAG, "Scheduling recommendations update");

        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Intent recommendationIntent = new Intent(context, UpdateRecommendationsService.class);
        PendingIntent alarmIntent = PendingIntent.getService(context, 0, recommendationIntent, 0);

        alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                INITIAL_DELAY,
                AlarmManager.INTERVAL_HALF_HOUR,
                alarmIntent);
    }
}

Cette implémentation de la classe BroadcastReceiver doit s'exécuter après le démarrage du téléviseur sur lequel elle est installée. Pour ce faire, enregistrez ce cours dans votre application manifeste avec un filtre d'intent qui écoute l'achèvement du processus de démarrage de l'appareil. La L'exemple de code suivant montre comment ajouter cette configuration au fichier manifeste:

<manifest ... >
  <application ... >
    <receiver android:name="com.example.android.tvleanback.BootupActivity"
              android:enabled="true"
              android:exported="false">
      <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
      </intent-filter>
    </receiver>
  </application>
</manifest>

Important:Pour recevoir une notification de fin de démarrage, votre application doit demande l'autorisation RECEIVE_BOOT_COMPLETED. Pour en savoir plus, consultez ACTION_BOOT_COMPLETED.

Dans votre classe de service de recommandation onHandleIntent() , publiez la recommandation sur le responsable comme suit:

Kotlin

val notification = notificationBuilder.build()
notificationManager.notify(id, notification)

Java

Notification notification = notificationBuilder.build();
notificationManager.notify(id, notification);