La schermata Home di Android TV fornisce un'interfaccia utente che mostra i contenuti consigliati come una tabella di canali e programmi. Ogni riga è un canale. Un canale contiene schede per ogni programma disponibile su quel canale:
Questo documento mostra come aggiungere canali e programmi alla schermata Home, aggiornare i contenuti, gestire le azioni dell'utente e offrire la migliore esperienza ai tuoi utenti. (Se vuoi approfondire l'API, prova il codelab della schermata Home e guarda la sessione di Android TV di I/O 2017)
L'interfaccia utente della schermata Home
Le app possono creare nuovi canali, aggiungere, rimuovere e aggiornare i programmi in un canale e controllare l'ordine dei programmi in un canale. Ad esempio, un'app può creare un canale chiamato "Novità" e mostrare schede per i programmi appena disponibili.
Le app non possono controllare l'ordine in cui i canali vengono visualizzati nella schermata Home. Quando la tua app crea un nuovo canale, la schermata Home lo aggiunge in fondo all'elenco dei canali. L'utente può riordinare, nascondere e mostrare i canali.
Il canale Cosa guardare
Il canale Cosa guardare è la seconda riga che viene visualizzata nella schermata Home, dopo la riga delle app. Il sistema crea e gestisce questo canale. La tua app può aggiungere programmi al canale Cosa guardare. Per ulteriori informazioni, vedi Aggiungere programmi a il canale Cosa guardare.
Canali app
I canali creati dalla tua app seguono tutti questo ciclo di vita:
- L'utente scopre un canale nella tua app e richiede 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
La tua app può offrire un numero qualsiasi di canali che l'utente può aggiungere alla schermata Home. In genere, l'utente deve selezionare e approvare ogni canale prima che venga visualizzato nella schermata Home. Ogni app ha la possibilità di creare un canale predefinito. Il canale predefinito è speciale perché viene visualizzato 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 provider, aggiungi la seguente autorizzazione al manifest dell'app:
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
La libreria di supporto TvProvider semplifica l'utilizzo del provider. Aggiungila alle dipendenze nel file build.gradle:
Alla moda
implementation 'androidx.tvprovider:tvprovider:1.0.0'
Kotlin
implementation("androidx.tvprovider:tvprovider:1.0.0")
Per lavorare con canali e programmi, assicurati di includere queste importazioni della libreria di supporto nel tuo programma:
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 suo canale predefinito. Il canale predefinito viene visualizzato automaticamente nella schermata Home. Tutti gli altri canali creati devono essere selezionati e accettati dall'utente prima di poter essere visualizzati nella schermata Home.
Creazione di un canale
L'app deve chiedere al sistema di mostrare i canali appena aggiunti solo quando è in esecuzione in primo piano. In questo modo, l'app non visualizzerà una finestra di dialogo che richiede l'approvazione per aggiungere il canale mentre l'utente sta eseguendo un'altra app. Se provi ad aggiungere un canale mentre è in esecuzione in background, il metodo onActivityResult() dell'attività restituisce il codice di stato RESULT_CANCELED.
Per creare un canale:
Crea un generatore di canali e imposta i relativi attributi. Tieni presente che il tipo di canale deve essere
TYPE_PREVIEW. Aggiungi altri attributi in base alle esigenze.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 i 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
Urio unBitmap. L'icona del logo deve essere di 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);Crea il canale predefinito (facoltativo): quando la tua app crea il suo primo canale, puoi impostarlo come canale predefinito in modo che venga visualizzato immediatamente nella schermata Home senza alcuna azione dell'utente. Gli altri canali creati non sono visibili finché l'utente non li seleziona esplicitamente.
Kotlin
TvContractCompat.requestChannelBrowsable(context, channelId)Java
TvContractCompat.requestChannelBrowsable(context, channelId);Fai in modo che il canale predefinito venga visualizzato prima dell'apertura dell'app. Puoi ottenere questo comportamento aggiungendo un
BroadcastReceiverche ascolta 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 dell'app durante lo sviluppo, puoi testare questo passaggio attivando l'intent tramite adb, dove your.package.name/.YourReceiverName è il
BroadcastReceiverdella tua app:adb shell am broadcast -a android.media.tv.action.INITIALIZE_PROGRAMS -n \ your.package.name/.YourReceiverNameIn rari casi, l'app potrebbe ricevere la trasmissione contemporaneamente all'avvio dell'app da parte dell'utente. Assicurati che il codice non tenti di aggiungere il canale predefinito più di una volta.
Aggiornamento di un canale
L'aggiornamento dei canali è molto simile alla loro creazione.
Utilizza un altro Channel.Builder per impostare gli attributi da modificare.
Utilizza ContentResolver per aggiornare il canale. Utilizza l'ID canale che hai salvato quando il canale è stato aggiunto originariamente:
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
I programmi sono le singole schede di contenuti visualizzate all'interno di un canale. Puoi pubblicare programmi sia sui canali personalizzati della tua app sia sul canale Cosa guardare gestito dal sistema.
Aggiunta di programmi a un canale 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 visualizzare gli attributi disponibili per ogni tipo di programma, consulta le tabelle 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 Cosa guardare
Per inserire i programmi nel canale Cosa guardare, vedi Aggiungere programmi al canale Cosa guardare.
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 quantità di un programma che l'utente ha guardato.
Utilizza un PreviewProgram.Builder per impostare gli attributi da modificare, quindi chiama getContentResolver().update per aggiornare il programma. Specifica l'ID programma che hai salvato quando il programma è stato aggiunto originariamente:
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 i contenuti fornendo un'interfaccia utente per visualizzare e aggiungere canali. La tua app deve anche gestire le interazioni con i tuoi canali dopo che vengono visualizzati nella schermata Home.
Scoperta e aggiunta di canali
La tua app può fornire un elemento dell'interfaccia utente che consente all'utente di selezionare e aggiungere i suoi canali (ad esempio, un pulsante che chiede di aggiungere il canale).
Dopo che l'utente ha richiesto 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 che chiede 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 e i canali pubblicati dall'app, la schermata Home invia intent all'app:
- La schermata Home invia l'
Urimemorizzato nell'attributo APP_LINK_INTENT_URI di un canale all'app quando l'utente seleziona il logo del canale. L'app deve semplicemente avviare l'interfaccia utente principale o una visualizzazione correlata al canale selezionato. - La schermata Home invia l'
Urimemorizzato nell'attributo INTENT_URI di un programma all'app quando l'utente seleziona un programma. L'app deve riprodurre i contenuti selezionati. - L'utente può indicare di non essere più interessato a un programma e di volerlo rimuovere dall'interfaccia utente della schermata Home. Il sistema rimuove il programma dall'interfaccia utente e invia all'app proprietaria del programma 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 provider e NON deve reinserirlo.
Assicurati di creare filtri per intent per tutti gli Uris che la schermata Home
invia per le interazioni dell'utente, 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>
Considerazioni aggiuntive
- Molte app TV richiedono agli utenti di accedere. In questo caso, il
BroadcastReceiverche ascoltaandroid.media.tv.action.INITIALIZE_PROGRAMSdeve suggerire contenuti del canale per gli utenti non autenticati. Ad esempio, l'app può inizialmente mostrare i contenuti migliori o i contenuti attualmente più popolari. Dopo che l'utente ha eseguito l'accesso, può mostrare contenuti personalizzati. Questa è un'ottima opportunità per le app di eseguire l'upselling degli utenti prima che accedano. - Quando l'app non è in primo piano e devi aggiornare un canale o un
programma, utilizza
JobSchedulerper pianificare il lavoro (vediJobSchedulereJobService). - Il sistema può revocare le autorizzazioni del provider della tua app se l'app si comporta in modo improprio (ad esempio, inviando continuamente spam al provider con i dati). Assicurati di racchiudere il codice che accede al provider con clausole try-catch per gestire le eccezioni di sicurezza.
Prima di aggiornare i programmi e i canali, esegui una query sul provider per i dati da aggiornare e riconcilia i dati. Ad esempio, non è necessario aggiornare un programma che l'utente vuole rimuovere dall'interfaccia utente. Utilizza un job in background che inserisce o aggiorna i dati nel provider dopo aver eseguito una query sui dati esistenti e aver richiesto l'approvazione per i tuoi canali. Puoi eseguire questo job all'avvio dell'app e ogni volta che l'app deve aggiornare i suoi 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 dei contenuti). Assicurati di utilizzare un Uri diverso quando aggiorni un'immagine. Tutte le immagini vengono memorizzate nella cache. Se non modifichi l'Uri quando modifichi l'immagine, continuerà a essere visualizzata l'immagine precedente.
Ricorda che le clausole WHERE non sono consentite e le chiamate ai provider con clausole WHERE genereranno un'eccezione di sicurezza.
Attributi
Questa sezione descrive separatamente gli attributi di canale e programma.
Attributi del canale
Devi specificare questi attributi per ogni canale:
| Attributo | Note |
|---|---|
| TIPO | Imposta su TYPE_PREVIEW. |
| DISPLAY_NAME | Imposta sul nome del canale. |
| APP_LINK_INTENT_URI | Quando l'utente seleziona il logo del canale, il sistema invia un intent per avviare un'attività che presenta contenuti pertinenti al canale. Imposta questo attributo sull'Uri utilizzato nel filtro per intent per questa attività. |
Inoltre, un canale ha anche sei campi riservati all'utilizzo interno dell'app. Questi campi possono essere utilizzati per memorizzare chiavi o altri valori che possono aiutare l'app a mappare il canale alla sua 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 per gli attributi di ogni tipo di programma:
- Attributi del programma video
- Attributi del programma audio
- Attributi del programma di gioco
- Attributi del programma Cosa guardare
Codice di esempio
Per saperne di più sulla creazione di app che interagiscono con la schermata Home e sull'aggiunta di canali e programmi alla schermata Home di Android TV, consulta il nostro codelab della schermata Home .