Consigli su Android N e versioni precedenti

Quando interagiscono con la TV, generalmente gli utenti preferiscono fornire un input minimo prima di guardare contenuti. Uno scenario ideale per molti utenti di TV è: siediti, accendi la TV e guarda il video. Il minor numero di passaggi indirizzare gli utenti verso i contenuti che preferiscono è in genere il percorso che preferiscono.

Nota:per fornire suggerimenti, utilizza le API qui descritte. solo nelle app con versioni di Android fino ad Android 7.1 (livello API 25) incluso. Da fornire consigli per le app eseguite su Android 8.0 (livello API 26) e versioni successive, l'app deve usare canali per i consigli.

Il framework Android garantisce un'interazione minima degli input fornendo una riga di suggerimenti sulla schermata Home. I contenuti consigliati vengono visualizzati nella prima riga della schermata Home della TV dopo al primo utilizzo del dispositivo. I suggerimenti dal catalogo di contenuti della tua app possono essere di aiuto riportare gli utenti sulla tua app.

Figura 1. Un esempio della riga dei suggerimenti.

Questa guida ti insegna come creare consigli e fornirli al framework Android in modo che gli utenti possano scoprire e usufruire facilmente dei contenuti della tua app. Vedi anche l'implementazione di esempio in il Esempio di app Leanback di Google.

Best practice per i consigli

I consigli consentono agli utenti di trovare rapidamente i contenuti e le app che preferiscono. Creazione in corso... di alta qualità e pertinenti per gli utenti è un fattore importante per la creazione un'esperienza utente ottimale con la tua app TV. Per questo motivo, devi considerare attentamente consigli che offri all'utente e gestirli da vicino.

Tipi di consigli

Quando crei consigli, devi ricollegare gli utenti alle attività di visualizzazione incomplete oppure suggerisci attività che estendono questo aspetto ai contenuti correlati. Di seguito sono riportati alcuni tipi specifici consigli che dovresti prendere in considerazione:

  • Consigli relativi ai contenuti di continuazione per la puntata successiva per consentire agli utenti di riprendere guardando una serie. In alternativa, utilizza i consigli sulla continuazione per film, programmi TV o podcast in pausa in modo che gli utenti possano tornare a guardare i contenuti in pausa con pochi clic.
  • Consigli relativi ai nuovi contenuti, ad esempio per una nuova puntata in prima visione, se l'utente ha finito di guardare un'altra serie. Inoltre, se la tua app consente agli utenti di abbonarsi, seguire o monitorare usa i nuovi consigli sui contenuti per gli elementi non guardati nell'elenco dei contenuti monitorati.
  • Consigli nei contenuti correlati in base agli utenti dell'attuale comportamento di visualizzazione.

Per saperne di più su come progettare le schede dei consigli per la migliore esperienza utente, consulta Riga dei consigli nelle specifiche per la progettazione di Android TV.

Aggiorna i consigli

Quando aggiorni i consigli, non limitarti a rimuoverli e ripubblicarli, perché questo comporta i consigli verranno visualizzati alla fine della riga corrispondente. Una volta che un contenuto, come film, è stato riprodotto, rimuoverlo dai consigli.

Consigli personalizzati

Puoi personalizzare le schede dei consigli per trasmettere le informazioni di branding impostando l'interfaccia utente elementi quali l'immagine in primo piano e di sfondo della scheda, il colore, l'icona dell'app, il titolo e il sottotitolo. Per saperne di più, vedi Riga dei consigli nelle specifiche per la progettazione di Android TV.

Consigli sul gruppo

Facoltativamente, puoi raggruppare i suggerimenti in base all'origine del suggerimento. Ad esempio, la tua app può fornire due gruppi di consigli: consigli sui contenuti a cui l'utente è iscritto, e consigli su nuovi contenuti di tendenza di cui l'utente potrebbe non essere a conoscenza.

Il sistema classifica e ordini i suggerimenti separatamente per ciascun gruppo durante la creazione o l'aggiornamento la riga del suggerimento. Fornendo informazioni sul gruppo per i tuoi consigli, puoi assicurarti che i tuoi consigli non vengano ordinati come indicato di seguito.

Utilizza le funzionalità di NotificationCompat.Builder.setGroup() per impostare la stringa della chiave del gruppo di un suggerimento. Per Ad esempio, per contrassegnare un consiglio come appartenente a un gruppo che include nuovi contenuti di tendenza, potresti chiamare setGroup("trending").

Creare un servizio di suggerimenti

I suggerimenti sui contenuti vengono creati con l'elaborazione in background. Affinché la tua applicazione contribuire ai consigli, creare un servizio che aggiunga periodicamente schede dal tuo catalogo dell'app all'elenco di consigli del sistema.

L'esempio di codice seguente illustra come estendere IntentService a crea un servizio di suggerimenti per la tua applicazione:

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;
    }
}

Affinché questo servizio venga riconosciuto dal sistema ed eseguito, registralo utilizzando la tua manifest dell'app. Il seguente snippet di codice illustra come dichiarare questa classe come servizio:

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

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

Suggerimenti sulla creazione

Una volta avviata l'esecuzione, il servizio di suggerimenti deve creare e trasmetterli il framework Android. Il framework riceve i suggerimenti come Notification oggetti che utilizzano un modello specifico e sono contrassegnati con un categoria.

Impostazione dei valori

Per impostare i valori degli elementi UI per la scheda dei suggerimenti, crea una classe del builder che: il pattern del builder descritto di seguito. Innanzitutto, imposta i valori della scheda dei consigli elementi.

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;
        }
...

Crea la notifica

Dopo aver impostato i valori, puoi creare la notifica, assegnando i valori dallo strumento di creazione classe alla notifica e chiamata NotificationCompat.Builder.build().

Inoltre, ricordati di chiamare setLocalOnly() quindi la notifica NotificationCompat.BigPictureStyle non verrà visualizzata su altri dispositivi.

Il seguente esempio di codice mostra come creare un suggerimento.

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;
    }
}

Esegui il servizio di suggerimenti

Il servizio di suggerimenti della tua app deve essere eseguito periodicamente per poter creare suggerimenti personalizzati. Per eseguire il servizio, crea una classe che esegua un timer e richiami a intervalli regolari. L'esempio di codice seguente estende la classe BroadcastReceiver per avviare l'esecuzione periodica di un servizio di suggerimenti ogni mezz'ora:

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);
    }
}

Questa implementazione della classe BroadcastReceiver deve essere eseguita dopo l'avvio del dispositivo TV su cui è installato. A questo scopo, registra questo corso nella tua app con un filtro per intent che rimane in ascolto per il completamento del processo di avvio del dispositivo. La Il seguente codice di esempio mostra come aggiungere questa configurazione al file manifest:

<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: per ricevere una notifica di avvio completato è necessario che l'app richiede l'autorizzazione RECEIVE_BOOT_COMPLETED. Per ulteriori informazioni, vedi ACTION_BOOT_COMPLETED.

Nella classe del servizio per suggerimenti onHandleIntent() , pubblica il suggerimento nell'amministratore come segue:

Kotlin

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

Java

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