Développer un service d'entrée TV

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 TV
  • TvInputService.Session maintient l'état de l'entrée TV et communique avec l'application d'hébergement
  • TvContract décrit les chaînes et les programmes disponibles sur le téléviseur entrée
  • TvContract.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ébut
  • TvTrackInfo 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'évaluation
  • TvInputManager 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:

  1. 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.
  2. Créez le fichier de métadonnées du service.
  3. Créez et enregistrez les informations sur votre chaîne et votre programme.
  4. 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);
}

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.

Autres références