Un servizio di input TV rappresenta un'origine di stream multimediale e consente di presentare i contenuti multimediali in un la moda lineare, in ambito televisivo come canali e programmi. Con un servizio di input TV, puoi fornire Controllo genitori, informazioni sulla guida ai programmi e classificazioni dei contenuti. Il servizio di ingresso TV funziona con l'app Android System TV. Questa app controlla e presenta i contenuti del canale sulla TV. L'app di sistema TV è sviluppata appositamente per il dispositivo e immutabile da app di terze parti. Per ulteriori informazioni sul TIF (TV Input Framework) dell'architettura e dei suoi componenti, Framework di input TV.
Creare un servizio di ingresso TV utilizzando la libreria complementare TIF
La libreria companion TIF è un framework che fornisce funzionalità implementazioni di funzionalità comuni dei servizi di input TV. È destinata agli OEM per creare disponibili solo per i canali Android dalla versione 5.0 (livello API 21) ad Android 7.1 (livello API 25).
Aggiorna il progetto
La libreria companion TIF è disponibile per l'utilizzo precedente da parte degli OEM nei input-di-esempio-androidtv repository Git. Guarda quel repository per un esempio di come includere la libreria in un'app.
Dichiara il tuo servizio di input TV nel file manifest
La tua app deve fornire una versione compatibile con TvInputService
servizio utilizzato dal sistema per accedere alla tua app. Il TIF
La libreria companion fornisce la classe BaseTvInputService
, che
fornisce un'implementazione predefinita di TvInputService
che puoi personalizzare. Crea una sottoclasse BaseTvInputService
,
e dichiarare la sottoclasse nel file manifest come servizio.
Nella dichiarazione del file manifest, specifica
l'autorizzazione BIND_TV_INPUT
per consentire l'accesso a
per collegare l'ingresso della TV al sistema. Un servizio di sistema
esegue l'associazione e ha
Autorizzazione BIND_TV_INPUT
.
L'app di sistema per la TV invia richieste ai servizi di ingresso della TV
tramite l'interfaccia TvInputManager
.
Nella dichiarazione del servizio, includi un filtro per intent che specifichi
TvInputService
come azione da eseguire con
l'intento. Dichiara anche i metadati del servizio come risorsa XML separata. La
vengono mostrate la dichiarazione del servizio, il filtro per intent e la dichiarazione dei metadati del servizio
nel seguente esempio:
<service android:name=".rich.RichTvInputService" android:label="@string/rich_input_label" android:permission="android.permission.BIND_TV_INPUT"> <!-- Required filter used by the system to launch our account service. --> <intent-filter> <action android:name="android.media.tv.TvInputService" /> </intent-filter> <!-- An XML file which describes this input. This provides pointers to the RichTvInputSetupActivity to the system/TV app. --> <meta-data android:name="android.media.tv.input" android:resource="@xml/richtvinputservice" /> </service>
Definisci i metadati del servizio in un file XML separato. Il servizio Il file XML dei metadati deve includere un'interfaccia di configurazione che descriva l'input della TV configurazione iniziale e scansione dei canali. Il file dei metadati deve contenere anche che indica se gli utenti sono in grado di registrare o meno i contenuti. Per ulteriori informazioni informazioni su come supportare la registrazione di contenuti nella tua app, consulta Supporto della registrazione di contenuti.
Il file dei metadati del servizio si trova nella directory delle risorse XML
per la tua app e deve corrispondere al nome della risorsa che hai dichiarato
del file manifest. Utilizzando le voci manifest dell'esempio precedente,
crea il file XML all'indirizzo res/xml/richtvinputservice.xml
, con
seguenti contenuti:
<?xml version="1.0" encoding="utf-8"?> <tv-input xmlns:android="http://schemas.android.com/apk/res/android" android:canRecord="true" android:setupActivity="com.example.android.sampletvinput.rich.RichTvInputSetupActivity" />
Definisci i canali e crea la tua attività di configurazione
Il tuo servizio di input TV deve definire almeno un canale a cui gli utenti l'accesso tramite l'app di sistema per la TV. Devi registrare i tuoi canali nel database di sistema e fornire un'attività di configurazione che il sistema quando non riesce a trovare un canale per la tua app.
Innanzitutto, abilita l'app a leggere e scrivere sul sistema Guida alla programmazione (EPG), i cui dati includono canali e programmi disponibili all'utente. Per consentire alla tua app di eseguire queste azioni ed eseguire la sincronizzazione con EPG dopo il riavvio del dispositivo, aggiungi i seguenti elementi al file manifest dell'app:
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED "/>
Aggiungi il seguente elemento per assicurarti che la tua app venga visualizzata nel Il Google Play Store come app che fornisce canali di contenuti su Android TV:
<uses-feature android:name="android.software.live_tv" android:required="true" />
Quindi, crea una classe che ampli EpgSyncJobService
. Questa classe astratta semplifica la creazione di un servizio job che
crea e aggiorna i canali nel database del sistema.
Nella sottoclasse, crea e restituisci l'elenco completo dei canali in
getChannels()
. Se i tuoi canali provengono da un file XMLTV,
usa la classe XmlTvParser
. Altrimenti, genera
i canali in modo programmatico utilizzando la classe Channel.Builder
.
Per ogni canale, il sistema chiama getProgramsForChannel()
quando ha bisogno di un elenco di programmi che possono essere visualizzati in un determinato periodo di tempo.
sul canale. Restituisce un elenco di Program
oggetti per il
canale. Utilizza il corso XmlTvParser
per ottenere programmi da un
XMLTV o generali in modo programmatico utilizzando il
Program.Builder
corso.
Per ogni oggetto Program
, utilizza un'istruzione
InternalProviderData
per impostare le informazioni del programma, come
tipo di video del programma. Se disponi solo di un numero limitato di programmi
vuoi che il canale si ripeta in loop, usa
InternalProviderData.setRepeatable()
con il valore
true
quando imposti le informazioni sul programma.
Dopo aver implementato il servizio di job, aggiungilo al file manifest dell'app:
<service android:name=".sync.SampleJobService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true" />
Infine, crea un'attività di configurazione. L'attività di configurazione dovrebbe fornirti un modo per sincronizzare i dati del canale e del programma. Un modo per farlo è che l'utente lo faccia tramite l'interfaccia utente nell'attività. Potresti anche chiedere all'app di farlo automaticamente all'inizio dell'attività. Quando è necessario sincronizzare canale e attività di configurazione informazioni sul programma, l'app deve avviare il servizio job:
Kotlin
val inputId = getActivity().intent.getStringExtra(TvInputInfo.EXTRA_INPUT_ID) EpgSyncJobService.cancelAllSyncRequests(getActivity()) EpgSyncJobService.requestImmediateSync( getActivity(), inputId, ComponentName(getActivity(), SampleJobService::class.java) )
Java
String inputId = getActivity().getIntent().getStringExtra(TvInputInfo.EXTRA_INPUT_ID); EpgSyncJobService.cancelAllSyncRequests(getActivity()); EpgSyncJobService.requestImmediateSync(getActivity(), inputId, new ComponentName(getActivity(), SampleJobService.class));
Usa il metodo requestImmediateSync()
per la sincronizzazione
del job di job. L'utente deve attendere il completamento della sincronizzazione, quindi dovresti
che il periodo di richiesta sia relativamente breve.
Utilizza il metodo setUpPeriodicSync()
per richiedere il servizio job
sincronizza periodicamente i dati del canale e del programma in background:
Kotlin
EpgSyncJobService.setUpPeriodicSync( context, inputId, ComponentName(context, SampleJobService::class.java) )
Java
EpgSyncJobService.setUpPeriodicSync(context, inputId, new ComponentName(context, SampleJobService.class));
La libreria companion TIF offre un ulteriore metodo di sovraccarico di
requestImmediateSync()
che ti consente di specificare la durata
dati del canale da sincronizzare in millisecondi. Il metodo predefinito sincronizza
di dati del canale.
La libreria companion TIF fornisce anche un ulteriore metodo di sovraccarico di
setUpPeriodicSync()
che ti consente di specificare la durata
i dati dei canali da sincronizzare e la frequenza della sincronizzazione periodica. La
il metodo predefinito sincronizza 48 ore di dati del canale ogni 12 ore.
Per ulteriori dettagli sui dati del canale e sull'EPG, consulta Lavora con i dati del canale.
Gestire le richieste di ottimizzazione e la riproduzione di contenuti multimediali
Quando un utente seleziona un canale specifico, l'app TV di sistema utilizza un
Session
, creato dalla tua app, per sintonizzarti sul canale richiesto
e riprodurre contenuti. La libreria companion TIF offre diverse
che puoi estendere per gestire le chiamate di canale e sessione dal sistema.
La sottoclasse BaseTvInputService
crea sessioni che gestiscono
richieste di ottimizzazione. Sostituisci il valore
Metodo onCreateSession()
, crea una sessione estesa da
la classe BaseTvInputService.Session
e richiama
super.sessionCreated()
con la nuova sessione. Nel seguente
Ad esempio, onCreateSession()
restituisce un
Oggetto RichTvInputSessionImpl
che si estende
BaseTvInputService.Session
:
Kotlin
override fun onCreateSession(inputId: String): Session = RichTvInputSessionImpl(this, inputId).apply { setOverlayViewEnabled(true) }
Java
@Override public final Session onCreateSession(String inputId) { RichTvInputSessionImpl session = new RichTvInputSessionImpl(this, inputId); session.setOverlayViewEnabled(true); return session; }
Quando l'utente utilizza l'app di sistema TV per iniziare a visualizzare uno dei tuoi canali,
il sistema chiama il metodo onPlayChannel()
della tua sessione. Esegui override
questo metodo se devi eseguire un'inizializzazione speciale del canale prima
viene avviata la riproduzione del programma.
Il sistema ottiene quindi il programma attualmente in programma e chiama il tuo
il metodo onPlayProgram()
della sessione, specificando il programma
informazioni e l'ora di inizio in millisecondi. Utilizza la
Interfaccia TvPlayer
per avviare la riproduzione del programma.
Per poter gestire il codice del media player, devi implementare TvPlayer
specifici eventi di riproduzione. La classe TvPlayer
gestisce le funzionalità
come i controlli timeshift senza complicare le cose
Implementazione di BaseTvInputService
.
Nel metodo getTvPlayer()
della tua sessione, torna
il media player che implementa TvPlayer
. La
L'app di esempio TV Input Service implementa un media player che utilizza
ExoPlayer.
Creare un servizio di input TV utilizzando il framework di input TV
Se il tuo servizio di ingresso TV non può utilizzare la libreria complementare TIF, devi avere per implementare i seguenti componenti:
TvInputService
offre disponibilità a lungo termine e in background per l'ingresso TVTvInputService.Session
mantiene lo stato di ingresso della TV e comunica con l'app di hostingTvContract
descrive i canali e i programmi disponibili per la TV inputTvContract.Channels
rappresenta informazioni su un canale TVTvContract.Programs
descrive un programma TV con dati come il programma titolo e ora di inizioTvTrackInfo
rappresenta una traccia audio, video o di sottotitoliTvContentRating
descrive una classificazione dei contenuti e consente contenuti personalizzati schemi di valutazioneTvInputManager
fornisce un'API all'app TV di sistema e gestisce l'interazione con ingressi e app TV
Devi inoltre effettuare le seguenti operazioni:
- Dichiara il tuo servizio di input TV nel file manifest, come descritto nella sezione Dichiarare il servizio di ingresso TV nel del file manifest.
- Crea il file dei metadati del servizio.
- Crea e registra le informazioni sul tuo canale e sul programma.
- Crea la tua attività di configurazione.
Definisci il servizio di ingresso TV
Per il tuo servizio, estendi la classe TvInputService
. R
L'implementazione di TvInputService
è
servizio associato in cui il servizio di sistema
è il client che vi vincola. Metodi del ciclo di vita dei servizi
che devi implementare sono illustrati nella Figura 1.
Il metodo onCreate()
inizializza e avvia il metodo
HandlerThread
, che fornisce un thread di processo separato dal thread dell'interfaccia utente a
gestire le azioni basate sul sistema. Nell'esempio seguente, onCreate()
inizializza CaptioningManager
e si prepara a gestire
ACTION_BLOCKED_RATINGS_CHANGED
e ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED
azioni. Questi
descrivono gli intent di sistema attivati quando l'utente modifica le impostazioni del Controllo genitori e quando
c'è una modifica nell'elenco
delle valutazioni bloccate.
Kotlin
override fun onCreate() { super.onCreate() handlerThread = HandlerThread(javaClass.simpleName).apply { start() } dbHandler = Handler(handlerThread.looper) handler = Handler() captioningManager = getSystemService(Context.CAPTIONING_SERVICE) as CaptioningManager setTheme(android.R.style.Theme_Holo_Light_NoActionBar) sessions = mutableListOf<BaseTvInputSessionImpl>() val intentFilter = IntentFilter().apply { addAction(TvInputManager.ACTION_BLOCKED_RATINGS_CHANGED) addAction(TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED) } registerReceiver(broadcastReceiver, intentFilter) }
Java
@Override public void onCreate() { super.onCreate(); handlerThread = new HandlerThread(getClass() .getSimpleName()); handlerThread.start(); dbHandler = new Handler(handlerThread.getLooper()); handler = new Handler(); captioningManager = (CaptioningManager) getSystemService(Context.CAPTIONING_SERVICE); setTheme(android.R.style.Theme_Holo_Light_NoActionBar); sessions = new ArrayList<BaseTvInputSessionImpl>(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(TvInputManager .ACTION_BLOCKED_RATINGS_CHANGED); intentFilter.addAction(TvInputManager .ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED); registerReceiver(broadcastReceiver, intentFilter); }
![](https://developer.android.google.cn/static/images/tv/tvinput-life.png?authuser=9&hl=it)
Figura 1.Ciclo di vita di TVInputService.
Vedi
Controlla i contenuti per ulteriori informazioni su come gestire i contenuti bloccati e fornire
Controllo genitori. Consulta TvInputManager
per altre azioni basate sul sistema che
che potresti voler gestire nel tuo servizio di input TV.
L'TvInputService
crea un
TvInputService.Session
che implementa Handler.Callback
per gestire le modifiche
dello stato del player. Con
onSetSurface()
,
TvInputService.Session
imposta Surface
con
contenuti video. Vedi Integrare il player con la piattaforma
per ulteriori informazioni sull'utilizzo di Surface
per il rendering dei video.
TvInputService.Session
gestisce
onTune()
evento quando l'utente seleziona un canale e avvisa l'app di sistema TV per eventuali modifiche ai contenuti e
metadati dei contenuti. Questi notify()
metodi sono descritti in
Controllare i contenuti e Gestire la selezione delle tracce
in questo corso di formazione.
Definisci l'attività di configurazione
L'app di sistema TV utilizza l'attività di configurazione che definisci per l'ingresso della TV. La l'attività di configurazione è obbligatoria e deve fornire almeno un record di canale per il database di sistema. La L'app per TV di sistema richiama l'attività di configurazione quando non riesce a trovare un canale per l'ingresso della TV.
L'attività di configurazione descrive all'app di sistema TV i canali resi disponibili tramite la TV come mostrato nella prossima lezione, Creare e aggiornare i dati del canale.