Un service d'entrée TV représente une source de flux multimédia et vous permet de présenter votre contenu multimédia dans un de la TV linéaire et des émissions de mode sous forme de chaînes et de programmes. Avec un service d'entrée TV, vous pouvez fournir le contrôle parental, les informations sur le guide des programmes et la classification du contenu. Le service d'entrée TV fonctionne avec l'appli Android System TV. Enfin, cette application contrôle et affiche le contenu de la chaîne sur le téléviseur. L'appli TV système est développée spécifiquement pour l'appareil et ne peut pas être modifiée. par des applications tierces. Pour en savoir plus sur TV Input Framework (TIF) l'architecture et ses composants, consultez <ph type="x-smartling-placeholder"></ph> Framework d'entrée TV
Créer un service d'entrée TV à l'aide de la bibliothèque TIF Companion
La bibliothèque TIF Companion est un framework qui fournit des les implémentations de fonctionnalités courantes du service d'entrée TV. Il est destiné à être utilisé par les OEM pour construire pour Android 5.0 (niveau d'API 21) à Android 7.1 (niveau d'API 25).
Mettre à jour votre projet
La bibliothèque TIF Companion peut être utilisée par les OEM dans le androidtv-sample-inputs un dépôt de clés. Consultez ce dépôt pour découvrir comment inclure la bibliothèque dans une application.
Déclarer votre service d'entrée TV dans le fichier manifeste
Votre application doit fournir un TvInputService
que le système utilise pour accéder à votre application. Le TIF
La bibliothèque Companion fournit la classe BaseTvInputService
, qui
fournit une implémentation par défaut de TvInputService
.
que vous pouvez personnaliser. Créez une sous-classe de BaseTvInputService
.
et déclarez la sous-classe en tant que service dans votre fichier manifeste.
Dans la déclaration du fichier manifeste, spécifiez
L'autorisation BIND_TV_INPUT
permet d'accorder à
pour connecter l'entrée TV au système. Un service système
effectue la liaison
Autorisation BIND_TV_INPUT
.
L'appli TV du système envoie des requêtes aux services d'entrée TV
via l'interface TvInputManager
.
Dans votre déclaration de service, incluez un filtre d'intent qui spécifie
TvInputService
comme action à effectuer avec la
l'intention. Déclarez également les métadonnées du service en tant que ressource XML distincte. La
la déclaration de service, le filtre d'intent et la déclaration de métadonnées du service sont affichés
dans l'exemple suivant:
<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>
Définissez les métadonnées du service dans un fichier XML distinct. Le service Le fichier XML de métadonnées doit inclure une interface de configuration qui décrit les paramètres de l'entrée TV la configuration initiale et la recherche des canaux. Le fichier de métadonnées doit également contenir Un drapeau indiquant si les utilisateurs sont en mesure ou non d'enregistrer du contenu Pour plus sur la prise en charge de l'enregistrement de contenu dans votre application, consultez Assurer la compatibilité avec l'enregistrement de contenu.
Le fichier de métadonnées du service se trouve dans le répertoire de ressources XML.
pour votre application et doit correspondre au nom de la ressource déclarée dans le
fichier manifeste. En utilisant les entrées du fichier manifeste de l'exemple précédent, vous devez
créez le fichier XML à l'emplacement res/xml/richtvinputservice.xml
, avec le
contenus suivants:
<?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" />
Définir des canaux et créer une activité de configuration
Votre service d'entrée TV doit définir au moins un canal utilisé par les utilisateurs y accéder via l'application system TV. Vous devez enregistrer vos chaînes dans la base de données du système, et fournissent une activité de configuration que le système appelle lorsqu'il ne trouve pas de canal pour votre application.
Tout d'abord, activez les droits de lecture et d'écriture de votre application dans le système Guide de programmation (EPG), dont les données incluent les chaînes et les programmes disponibles pour l'utilisateur. Pour permettre à votre application d'effectuer ces actions et de se synchroniser avec le EPG après le redémarrage de l'appareil, ajoutez les éléments suivants au fichier manifeste de votre application:
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED "/>
Ajoutez l'élément suivant pour vous assurer que votre application s'affiche dans le Google Play Store en tant qu'application qui fournit des chaînes de contenu sur Android TV:
<uses-feature android:name="android.software.live_tv" android:required="true" />
Ensuite, créez une classe qui étend EpgSyncJobService
.
. Cette classe abstraite permet de créer facilement un service de jobs
crée et met à jour les canaux
dans la base de données du système.
Dans votre sous-classe, créez et renvoyez votre liste complète de canaux dans
getChannels()
Si vos chaînes proviennent d'un fichier XMLTV,
utiliser la classe XmlTvParser
; Sinon, générez
de façon programmatique à l'aide de la classe Channel.Builder
.
Pour chaque canal, le système appelle getProgramsForChannel()
lorsqu'il a besoin d'une liste de programmes pouvant être affichés pendant une période donnée
sur la chaîne. Renvoyez une liste d'objets Program
pour le
canal. Utilisez la classe XmlTvParser
pour obtenir des programmes à partir d'une
XMLTV, ou les générer par programmation à l'aide du
Program.Builder
.
Pour chaque objet Program
, utilisez un
InternalProviderData
pour définir les informations du programme telles que
le type de vidéo du programme. Si vous n'avez qu'un nombre limité de programmes
que le canal se répète en boucle, utilisez la méthode
InternalProviderData.setRepeatable()
avec une valeur de
true
lorsque vous configurez des informations sur votre programme.
Après avoir implémenté le service de tâches, ajoutez-le au fichier manifeste de votre application:
<service android:name=".sync.SampleJobService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true" />
Enfin, créez une activité de configuration. Votre activité de configuration doit fournir un moyen pour synchroniser les données des chaînes et des programmes. L'une des façons de le faire consiste à laisser l'utilisateur le faire via l'UI de l'activité. Vous pouvez aussi demander à l'application de le faire automatiquement lorsque l'activité commence. Lorsque l'activité de configuration doit synchroniser la chaîne et informations sur le programme, l'application doit démarrer le service de jobs:
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));
Utiliser la méthode requestImmediateSync()
pour effectuer la synchronisation
le service de jobs. L'utilisateur doit attendre la fin de la synchronisation. Vous devez donc
limitez la période de validité de votre demande.
Utilisez la méthode setUpPeriodicSync()
pour que le service de jobs
synchroniser régulièrement les données des chaînes et des programmes en arrière-plan:
Kotlin
EpgSyncJobService.setUpPeriodicSync( context, inputId, ComponentName(context, SampleJobService::class.java) )
Java
EpgSyncJobService.setUpPeriodicSync(context, inputId, new ComponentName(context, SampleJobService.class));
La bibliothèque TIF Companion fournit
une méthode supplémentaire surchargée de
requestImmediateSync()
, qui vous permet de spécifier la durée
les données de canal à synchroniser
en quelques millisecondes. La méthode par défaut synchronise
de données de canaux.
La bibliothèque TIF Companion fournit également
une méthode supplémentaire surchargée de
setUpPeriodicSync()
, qui vous permet de spécifier la durée
les données de canal à synchroniser et la fréquence à laquelle la synchronisation périodique doit avoir lieu. La
La méthode par défaut synchronise 48 heures de données de la chaîne toutes les 12 heures.
Pour en savoir plus sur les données de chaîne et l'EPG, consultez Exploiter les données des chaînes
Gérer les demandes de réglage et la lecture des contenus multimédias
Lorsqu'un utilisateur sélectionne une chaîne spécifique, l'application System TV utilise un
Session
, créé par votre application, pour se régler sur la chaîne demandée
et lire du contenu. La bibliothèque TIF Companion propose plusieurs
que vous pouvez étendre pour gérer les appels de canal et de session du système.
Votre sous-classe BaseTvInputService
crée des sessions qui gèrent
des requêtes de réglage. Remplacez les
onCreateSession()
, créez une session étendue de
la classe BaseTvInputService.Session
, puis appelez
super.sessionCreated()
par votre nouvelle session. Dans les
Par exemple, onCreateSession()
renvoie une
Objet RichTvInputSessionImpl
qui étend
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; }
Lorsque l'utilisateur utilise l'application System TV pour commencer à regarder l'une de vos chaînes,
le système appelle la méthode onPlayChannel()
de votre session. Remplacement
cette méthode si vous devez initialiser un canal spécial avant que
commence la lecture du programme.
Le système obtient alors le programme actuellement planifié et appelle votre
la méthode onPlayProgram()
de la session, en spécifiant le programme
et l'heure de début en millisecondes. Utilisez les
TvPlayer
pour commencer à lire le programme.
Le code de votre lecteur multimédia doit implémenter TvPlayer
pour gérer
des événements de lecture spécifiques. La classe TvPlayer
gère les fonctionnalités
comme le contrôle du direct, sans compliquer
Implémentation de BaseTvInputService
.
Dans la méthode getTvPlayer()
de votre session, renvoyez
votre lecteur multimédia qui implémente TvPlayer
. La
<ph type="x-smartling-placeholder"></ph>
L'application exemple TV Input Service implémente un lecteur multimédia qui utilise
ExoPlayer :
Créer un service d'entrée TV à l'aide du framework d'entrée TV
Si votre service d'entrée TV ne peut pas utiliser la bibliothèque TIF associée, vous devez : pour implémenter les composants suivants:
TvInputService
fournit une disponibilité de longue durée en arrière-plan pour l'entrée TVTvInputService.Session
maintient l'état de l'entrée TV et communique avec l'application d'hébergementTvContract
décrit les chaînes et les programmes disponibles sur le téléviseur entréeTvContract.Channels
représente les informations sur une chaîne de télévision.TvContract.Programs
décrit un programme télévisé contenant des données telles que titre et heure de débutTvTrackInfo
représente une piste audio, vidéo ou de sous-titres.TvContentRating
décrit une classification de contenu et permet de personnaliser le contenu systèmes d'évaluationTvInputManager
fournit une API à l'application System TV et gère l'interaction avec les entrées TV et les applications
Vous devez également effectuer les opérations suivantes:
- Déclarez votre service d'entrée TV dans le fichier manifeste, comme suit : décrit dans la section Déclarer votre service d'entrée TV dans le fichier manifeste.
- Créez le fichier de métadonnées du service.
- Créez et enregistrez les informations sur votre chaîne et votre programme.
- Créez votre activité de configuration.
Définir votre service d'entrée TV
Pour votre service, vous allez étendre la classe TvInputService
. A
L'implémentation de TvInputService
est
service lié où le service système
est le client qui s'y lie. Les méthodes du cycle de vie du service
que vous devez implémenter sont illustrés dans la figure 1.
La méthode onCreate()
initialise et démarre
HandlerThread
, qui fournit un thread de processus distinct du thread UI pour
pour gérer les actions déclenchées par le système. Dans l'exemple suivant, onCreate()
initialise CaptioningManager
et se prépare à gérer
le ACTION_BLOCKED_RATINGS_CHANGED
et ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED
. Ces
les actions décrivent les intents système déclenchés lorsque l'utilisateur modifie les paramètres de contrôle parental et quand
la liste des notes bloquées a changé.
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=0000&hl=fr)
Figure 1. Cycle de vie de TvInputService
Voir <ph type="x-smartling-placeholder"></ph>
"Contrôler le contenu" pour en savoir plus sur la manière de travailler avec du contenu bloqué et de fournir
le contrôle parental. Consultez TvInputManager
pour découvrir d'autres actions système qui
que vous devrez gérer
dans votre service d'entrée TV.
Le TvInputService
crée un
TvInputService.Session
qui implémente Handler.Callback
.
pour gérer les changements d'état du lecteur. Avec
onSetSurface()
,
TvInputService.Session
définit Surface
avec
du contenu vidéo. Consultez Intégrer le lecteur à la surface.
pour en savoir plus sur le rendu vidéo avec Surface
.
TvInputService.Session
gère les
onTune()
lorsque l'utilisateur sélectionne une chaîne, et informe l'application TV du système des modifications apportées au contenu et
métadonnées de contenu. Ces méthodes notify()
sont décrites dans
<ph type="x-smartling-placeholder"></ph>
Contrôler le contenu et gérer la sélection des titres
dans la suite de cette formation.
Définir votre activité de configuration
L'application système TV fonctionne avec l'activité de configuration que vous définissez pour votre entrée TV. La une activité de configuration est requise et doit fournir au moins un enregistrement de canal pour la base de données système. La L'appli TV système appelle l'activité de configuration lorsqu'elle ne trouve pas de chaîne pour l'entrée TV.
L'activité de configuration décrit à l'application système TV les chaînes mises à disposition via le téléviseur. comme dans la leçon suivante, Créer et mettre à jour les données de la chaîne.