Cuando los usuarios interactúan con TVs, por lo general, prefieren realizar una entrada mínima antes de mirar el contenido. contenido. Una situación ideal para muchos usuarios consiste en sentarse, encender la TV y mirar el contenido. El menor número de pasos para lograr que los usuarios accedan al contenido que les gusta es, por lo general, el camino que prefieren.
Nota: Utiliza las APIs que se describen aquí para hacer recomendaciones en apps que se ejecutan en versiones de Android hasta Android 7.1 (nivel de API 25) inclusive. Para suministrar para las apps que se ejecutan en Android 8.0 (nivel de API 26) y versiones posteriores, tu app debe usar canales de recomendaciones.
El framework de Android ayuda con la interacción mínima de entrada proporcionando una fila de recomendaciones. en la pantalla de inicio. Las recomendaciones de contenido aparecen en la primera fila de la pantalla principal de la TV después de el primer uso del dispositivo. Colaborar con las recomendaciones del catálogo de contenido de tu app puede ser útil para que los usuarios vuelvan a la app.
En esta guía, aprenderás a crear recomendaciones y proporcionarlas al framework de Android para que los usuarios puedan descubrir y disfrutar el contenido de tu app con facilidad. Consulta también la implementación de muestra en el App de ejemplo de Leanback de Google Cloud.
Prácticas recomendadas para las recomendaciones
Las recomendaciones permiten que los usuarios encuentren rápidamente el contenido y las apps que les gustan. Creando recomendaciones de alta calidad y relevantes para los usuarios es un factor importante a la hora de crear un una gran experiencia del usuario con tu app para TV. Por este motivo, debes considerar cuidadosamente recomendaciones que presentas al usuario y las administras de cerca.
Tipos de recomendaciones
Cuando creas recomendaciones, debes vincular a los usuarios con actividades de visualización incompletas. sugerirá actividades que extienden eso al contenido relacionado. Estos son algunos tipos específicos de recomendaciones que debes tener en cuenta:
- Recomendaciones de contenido de continuación para el siguiente episodio para que los usuarios lo reanuden mirando una serie. También puedes usar las recomendaciones de continuación para películas, programas de TV o podcasts pausados de modo que los usuarios puedan volver a ver el contenido pausado con solo unos clics.
- Recomendaciones de contenido nuevo, como para un episodio que se estrenó por primera vez, si el usuario si terminaste de ver otra serie. Además, si tu app permite que los usuarios se suscriban, sigan o hagan un seguimiento de contenido, usa nuevas recomendaciones de contenido para los elementos no vistos en su lista de contenido con seguimiento.
- Recomendaciones de contenido relacionado basadas en el comportamiento de visualización histórico de los usuarios.
Para obtener más información sobre cómo diseñar tarjetas de recomendaciones para obtener la mejor experiencia del usuario, consulta Fila de Recommendation en las especificaciones de diseño de Android TV.
Cómo actualizar las recomendaciones
Cuando actualices recomendaciones, no las quites y vuelvas a publicarlas, ya que esto provoca las recomendaciones aparecen al final de la fila de recomendaciones. Cuando se crea un elemento de contenido, como película, se reprodujo, quítalo de las recomendaciones.
Cómo personalizar las recomendaciones
Puedes personalizar las tarjetas de recomendaciones para transmitir información de marca estableciendo la interfaz de usuario elementos como la imagen en primer y segundo plano de la tarjeta, el color, el ícono de la app, el título y el subtítulo. Para obtener más información, consulta Fila de Recommendation en las especificaciones de diseño de Android TV.
Recomendaciones de grupo
También puedes agrupar las recomendaciones según su origen. Por ejemplo, tu app puede ofrecer dos grupos de recomendaciones: recomendaciones sobre el contenido al que se suscribió el usuario y recomendaciones de contenido nuevo del momento que el usuario podría no estar al tanto.
El sistema clasifica y ordena las recomendaciones para cada grupo por separado durante la creación o actualización la fila de recomendaciones. Si proporcionas información del grupo para tus recomendaciones, puedes asegurarte para que tus recomendaciones no se ordenen debajo de las recomendaciones no relacionadas.
Usa
NotificationCompat.Builder.setGroup()
para establecer la string clave del grupo de una recomendación. Para
Por ejemplo, para marcar una recomendación como perteneciente a un grupo que incluye contenido del momento nuevo,
puedes llamar a setGroup("trending")
.
Cómo crear un servicio de recomendaciones
Las recomendaciones de contenido se crean con procesos en segundo plano. Para que tu aplicación pueda contribuir con recomendaciones, crear un servicio que agregue periódicamente fichas de tus catálogo de la app a la lista de recomendaciones del sistema.
En el siguiente ejemplo de código, se muestra cómo extender IntentService
a
crea un servicio de recomendación para tu aplicación:
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; } }
Para que el sistema reconozca este servicio y lo ejecute, regístralo con tu manifiesto de la app. En el siguiente fragmento de código, se muestra cómo declarar esta clase como servicio:
<manifest ... > <application ... > ... <service android:name="com.example.android.tvleanback.UpdateRecommendationsService" android:enabled="true" /> </application> </manifest>
Cómo compilar las recomendaciones
Una vez que tu servicio de recomendaciones comienza a ejecutarse, debe crear recomendaciones y pasarlas a
el framework de Android. El framework recibe las recomendaciones como objetos Notification
que usan una plantilla específica y están marcados con una
categoría.
Cómo configurar los valores
Para establecer los valores de los elementos de la IU correspondientes a la tarjeta de recomendaciones, crea una clase de compilador que siga estos pasos: el patrón de compilador que se describe de la siguiente manera. Primero, establece los valores de la tarjeta de recomendaciones o de terceros.
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; } ...
Cómo crear la notificación
Una vez que hayas establecido los valores, compila la notificación y asigna los valores desde el compilador.
a la notificación y llamando a NotificationCompat.Builder.build()
.
Además, asegúrate de llamar
setLocalOnly()
por lo que la notificación de NotificationCompat.BigPictureStyle
no aparecerá
en otros dispositivos.
En el siguiente código, se muestra cómo compilar una recomendación.
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; } }
Ejecuta el servicio de recomendaciones
El servicio de recomendaciones de tu app se debe ejecutar de forma periódica para crear una
recomendaciones. Para ejecutar tu servicio, crea una clase que ejecute un temporizador y, luego, invoque
a intervalos regulares. En el siguiente ejemplo de código, se extiende la clase BroadcastReceiver
para iniciar la ejecución periódica de un servicio de recomendación.
cada media hora:
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); } }
Esta implementación de la clase BroadcastReceiver
se debe ejecutar después del inicio.
en la parte superior del dispositivo de TV donde está instalado. Para ello, registra esta clase en tu app
con un filtro de intents que escucha cuando se completa el proceso de inicio del dispositivo. El
El siguiente código de ejemplo muestra cómo agregar esta configuración al manifiesto:
<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>
Importante: Para recibir una notificación de que se completó el inicio, tu app debe
solicita el permiso RECEIVE_BOOT_COMPLETED
.
Para obtener más información, consulta ACTION_BOOT_COMPLETED
.
En tu clase de servicio de recomendación onHandleIntent()
, publica la recomendación para el administrador de la siguiente manera:
Kotlin
val notification = notificationBuilder.build() notificationManager.notify(id, notification)
Java
Notification notification = notificationBuilder.build(); notificationManager.notify(id, notification);