La schermata Home di Android TV, o semplicemente la schermata Home, offre un'interfaccia utente che mostra i contenuti consigliati sotto forma di tabella di canali e programmi. Ogni riga rappresenta un canale. Un canale contiene schede per ogni programma disponibile su quel canale:
Questo documento spiega come aggiungere canali e programmi alla schermata Home, aggiornare i contenuti, gestire le azioni degli utenti e offrire agli utenti la migliore esperienza possibile. Se vuoi saperne di più sull'API, prova il codelab sulla schermata Home e guarda la sessione su Android TV I/O 2017.
Nota: i canali Consigli sono disponibili solo in Android 8.0 (livello API 26) e versioni successive. Devi utilizzarle per fornire suggerimenti per le app eseguite con Android 8.0 (livello API 26) e versioni successive. Per fornire suggerimenti per le app eseguite con versioni precedenti di Android, la tua app deve utilizzare invece la riga dei suggerimenti.
L'UI della schermata Home
Le app possono creare nuovi canali, aggiungere, rimuovere e aggiornare i programmi di un canale, nonché controllare l'ordine dei programmi al suo interno. Ad esempio, un'app può creare un canale chiamato "Novità" e mostrare schede relative ai programmi appena disponibili.
Le app non possono controllare l'ordine di visualizzazione dei canali nella schermata Home. Quando la tua app crea un nuovo canale, la schermata Home lo aggiunge in fondo all'elenco di canali. L'utente può riordinare, nascondere e mostrare i canali.
Il canale Guarda in seguito
Il canale Guarda in seguito è la seconda riga visualizzata nella schermata Home, dopo la riga delle app. Il sistema crea e gestisce questo canale. L'app può aggiungere programmi al canale Guarda in seguito. Per ulteriori informazioni, consulta la sezione Aggiungere programmi al canale Guarda in seguito.
Canali app
I canali creati dalla tua app seguono questo ciclo di vita:
- L'utente scopre un canale nella tua app e chiede di aggiungerlo alla schermata Home.
- L'app crea il canale e lo aggiunge a
TvProvider
(a questo punto il canale non è visibile). - L'app chiede al sistema di visualizzare il canale.
- Il sistema chiede all'utente di approvare il nuovo canale.
- Il nuovo canale viene visualizzato nell'ultima riga della schermata Home.
Il canale predefinito
L'app può offrire all'utente un numero qualsiasi di canali da aggiungere alla schermata Home. Solitamente l'utente deve selezionare e approvare ciascun canale prima che questo venga visualizzato nella schermata Home. Ogni app ha la possibilità di creare un canale predefinito. Il canale predefinito è speciale perché appare automaticamente nella schermata Home; l'utente non deve richiederlo esplicitamente.
Prerequisiti
La schermata Home di Android TV utilizza le API TvProvider
di Android per gestire i canali e i programmi creati dalla tua app.
Per accedere ai dati del fornitore, aggiungi la seguente autorizzazione al file manifest dell'app:
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
La libreria di assistenza TvProvider
semplifica l'utilizzo del provider. Aggiungilo alle dipendenze nel tuo file build.gradle
:
Trendy
implementation 'androidx.tvprovider:tvprovider:1.0.0'
Kotlin
implementation("androidx.tvprovider:tvprovider:1.0.0")
Per lavorare con canali e programmi, assicurati di includere nel programma le seguenti importazioni della libreria di supporto:
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;
Canali
Il primo canale creato dalla tua app diventa il canale predefinito. Il canale predefinito viene visualizzato automaticamente nella schermata Home. Tutti gli altri canali che crei devono essere selezionati e accettati dall'utente prima di poter essere visualizzati nella schermata Home.
Creazione di un canale
L'app dovrebbe chiedere al sistema di mostrare i canali appena aggiunti solo quando sono in esecuzione in primo piano. Questo impedisce alla tua app di mostrare una finestra di dialogo che richiede l'approvazione per aggiungere il tuo canale mentre l'utente utilizza un'altra app. Se provi ad aggiungere un canale mentre viene eseguito in background, il metodo onActivityResult()
dell'attività restituisce il codice di stato RESULT_CANCELED
.
Per creare un canale:
Creare uno strumento per la creazione di canali e impostarne gli attributi. Tieni presente che il tipo di canale deve essere
TYPE_PREVIEW
. Aggiungi altri attributi come richiesto.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);Inserisci il canale nel provider:
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());
-
Devi salvare l'ID canale per aggiungere programmi al canale in un secondo momento. Estrai l'ID canale dall'URI restituito:
Kotlin
var channelId = ContentUris.parseId(channelUri)
Java
long channelId = ContentUris.parseId(channelUri);
Devi aggiungere un logo per il tuo canale. Utilizza un
Uri
o unBitmap
. L'icona del logo deve essere 80 dp x 80 dp e deve essere opaca. Viene visualizzata sotto una maschera circolare: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);
(Facoltativo) Crea il canale predefinito: quando l'app crea il primo canale, puoi impostarlo come canale predefinito in modo che venga visualizzato immediatamente nella schermata Home senza alcuna azione dell'utente. Tutti gli altri canali che crei non sono visibili finché l'utente non li seleziona esplicitamente.
Kotlin
TvContractCompat.requestChannelBrowsable(context, channelId)
Java
TvContractCompat.requestChannelBrowsable(context, channelId);
- Mostra il tuo canale predefinito prima dell'apertura dell'app. Puoi
ottenere questo comportamento aggiungendo un
BroadcastReceiver
che ascolti l'azioneandroid.media.tv.action.INITIALIZE_PROGRAMS
, che la schermata Home invia dopo l'installazione dell'app:<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>
Quando esegui il sideload della tua app durante lo sviluppo, puoi testare questo passaggio attivando l'intent tramite adb, dove your.package.name/.YourReceiverName è l'BroadcastReceiver
della tua app:adb shell am broadcast -a android.media.tv.action.INITIALIZE_PROGRAMS -n \ your.package.name/.YourReceiverName
In rari casi, la tua app potrebbe ricevere la trasmissione nello stesso momento in cui l'utente avvia l'app. Assicurati che il codice non provi ad aggiungere il canale predefinito più di una volta.
Aggiornare un canale
Aggiornare i canali è molto simile alla loro creazione.
Utilizza un altro Channel.Builder
per impostare gli attributi che devono essere modificati.
Usa ContentResolver
per aggiornare il canale. Utilizza l'ID canale salvato al momento dell'aggiunta iniziale del canale:
Kotlin
context.contentResolver.update( TvContractCompat.buildChannelUri(channelId), builder.build().toContentValues(), null, null )
Java
context.getContentResolver().update(TvContractCompat.buildChannelUri(channelId), builder.build().toContentValues(), null, null);
Per aggiornare il logo di un canale, utilizza storeChannelLogo()
.
Eliminazione di un canale
Kotlin
context.contentResolver.delete(TvContractCompat.buildChannelUri(channelId), null, null)
Java
context.getContentResolver().delete(TvContractCompat.buildChannelUri(channelId), null, null);
Programmi
Aggiunta di programmi a un canale dell'app
Crea un PreviewProgram.Builder
e imposta i relativi attributi:
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);
Aggiungi altri attributi a seconda del tipo di programma. Per vedere gli attributi disponibili per ciascun tipo di programma, fai riferimento alle tabelle riportate di seguito.
Inserisci il programma nel provider:
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());
Recupera l'ID programma per riferimento futuro:
Kotlin
val programId = ContentUris.parseId(programUri)
Java
long programId = ContentUris.parseId(programUri);
Aggiunta di programmi al canale Guarda in seguito
Per inserire programmi nel canale Guarda in seguito, consulta Aggiungere programmi al canale Guarda successivo.
Aggiornamento di un programma
Puoi modificare le informazioni di un programma. Ad esempio, potresti voler aggiornare il prezzo di noleggio di un film o aggiornare una barra di avanzamento che mostra la durata della visione del programma.
Utilizza PreviewProgram.Builder
per impostare gli attributi da modificare,
quindi chiama getContentResolver().update
per aggiornare il programma. Specifica l'ID programma salvato quando il programma è stato aggiunto inizialmente:
Kotlin
context.contentResolver.update( TvContractCompat.buildPreviewProgramUri(programId), builder.build().toContentValues(), null, null )
Java
context.getContentResolver().update(TvContractCompat.buildPreviewProgramUri(programId), builder.build().toContentValues(), null, null);
Eliminazione di un programma
Kotlin
context.contentResolver .delete(TvContractCompat.buildPreviewProgramUri(programId), null, null)
Java
context.getContentResolver().delete(TvContractCompat.buildPreviewProgramUri(programId), null, null);
Gestione delle azioni dell'utente
La tua app può aiutare gli utenti a scoprire contenuti fornendo una UI per visualizzare e aggiungere canali. L'app deve gestire anche le interazioni con i canali dopo che sono visualizzati nella schermata Home.
Scoprire e aggiungere canali
La tua app può fornire un elemento UI che consenta all'utente di selezionare e aggiungere i suoi canali (ad esempio, un pulsante che chiede di aggiungere il canale).
Quando l'utente richiede un canale specifico, esegui questo codice per ottenere l'autorizzazione dell'utente ad aggiungerlo all'interfaccia utente della schermata Home:
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 }
Il sistema visualizza una finestra di dialogo in cui viene chiesto all'utente di approvare il canale.
Gestisci il risultato della richiesta nel metodo onActivityResult
della tua attività (Activity.RESULT_CANCELED
o Activity.RESULT_OK
).
Eventi della schermata Home di Android TV
Quando l'utente interagisce con i programmi/canali pubblicati dall'app, la schermata Home invia intent all'app:
- La schermata Home invia all'app i
Uri
memorizzati nell'attributo APP_LINK_INTENT_URI di un canale quando l'utente seleziona il logo del canale. L'app dovrebbe semplicemente avviare l'interfaccia utente principale o una visualizzazione relativa al canale selezionato. - La schermata Home invia all'app i
Uri
memorizzati nell'attributo INTENT_URI di un programma quando l'utente seleziona un programma. L'app dovrebbe riprodurre i contenuti selezionati. - L'utente può indicare che non è più interessato a un programma e vuole che venga rimosso dall'interfaccia utente della schermata Home. Il sistema rimuove il programma dall'interfaccia utente e invia all'app proprietaria un intent (android.media.tv.ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED o android.media.tv.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED) con l'ID del programma. L'app deve rimuovere il programma dal fornitore e NON reinserirlo.
Assicurati di creare filtri per intent per tutti i Uris
inviati dalla schermata Home per le interazioni degli utenti, ad esempio:
<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>
Best practice
- Molte app per TV richiedono l'accesso degli utenti. In questo caso, l'
BroadcastReceiver
che ascoltaandroid.media.tv.action.INITIALIZE_PROGRAMS
deve suggerire contenuti del canale per gli utenti non autenticati.Ad esempio, l'app può inizialmente mostrare i contenuti migliori o i contenuti attualmente popolari. Dopo che l'utente esegue l'accesso, può mostrare contenuti personalizzati. Questa è una grande opportunità per le app di upsell per gli utenti prima che accedano. - Se la tua app non è in primo piano e devi aggiornare un canale o un
programma, utilizza
JobScheduler
per programmare il lavoro (consulta JobScheduler e JobService). - Il sistema può revocare le autorizzazioni del provider dell'app se quest'ultima funziona in modo anomalo (ad esempio inviando spam continuamente al provider con dati). Assicurati di eseguire il wrapping del codice che accede al provider con clausole di prova-catch per gestire le eccezioni di sicurezza.
Prima di aggiornare programmi e canali, chiedi al fornitore i dati che devi aggiornare e riconciliare i dati. Ad esempio, non è necessario aggiornare un programma che l'utente vuole rimuovere dalla UI. Utilizza un job in background che inserisce/aggiorna i dati nel provider dopo aver eseguito query sui dati esistenti e successivamente richiedendo l'approvazione per i canali. Puoi eseguire questo job all'avvio e ogni volta che l'app deve aggiornarne i dati.
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 } } }
Utilizza URI univoci per tutte le immagini (loghi, icone, immagini di contenuti). Assicurati di utilizzare un URI diverso quando aggiorni un'immagine. Tutte le immagini vengono memorizzate nella cache. Se non cambi l'URI quando cambi l'immagine, continuerà a essere visualizzata la vecchia immagine.
Ricorda che le clausole WHERE non sono consentite e le chiamate ai provider con clausole WHERE generano un'eccezione di sicurezza.
Attributi
In questa sezione vengono descritti gli attributi del canale e del programma separatamente.
Attributi del canale
Devi specificare i seguenti attributi per ogni canale:
Attributo | Notes |
---|---|
TIPO | impostato su TYPE_PREVIEW . |
DISPLAY_NAME | sul nome del canale. |
APP_LINK_INTENT_URI | Quando l'utente seleziona il logo del canale, il sistema invia l'intenzione di avviare un'attività che presenta contenuti pertinenti per il canale. Imposta questo attributo sull'URI utilizzato nel filtro per intent per l'attività in questione. |
Inoltre, un canale dispone di sei campi riservati all'uso interno delle app. Questi campi possono essere utilizzati per archiviare chiavi o altri valori che possono aiutare l'app a mappare il canale alla struttura di dati interna:
- INTERNAL_PROVIDER_ID
- INTERNAL_PROVIDER_DATA
- INTERNAL_PROVIDER_FLAG1
- INTERNAL_PROVIDER_FLAG2
- INTERNAL_PROVIDER_FLAG3
- INTERNAL_PROVIDER_FLAG4
Attributi del programma
Consulta le singole pagine degli attributi per ciascun tipo di programma:
- Attributi del programma video
- Attributi del programma audio
- Attributi del programma di gioco
- Attributi del programma Guarda Next
Codice di esempio
Per ulteriori informazioni sulla creazione di app che interagiscono con la schermata Home e aggiungono canali e programmi alla schermata Home di Android TV, consulta il nostro codelab sulla schermata Home.