TV-Eingabedienst entwickeln

Ein TV-Eingabedienst stellt eine Medienstreamquelle dar. Damit können Sie Ihre Medieninhalte in einem lineares Fernsehen als Kanäle und Programme zu übertragen. Mit einem TV-Eingabedienst können Sie Jugendschutzeinstellungen, Informationen zur Programmübersicht und Altersfreigaben. Der TV-Eingabedienst funktioniert mit der Android System TV App. Über diese App werden Kanalinhalte gesteuert und präsentiert. auf dem Fernseher. Die System-TV-App wurde speziell für das Gerät entwickelt und ist unveränderlich durch Drittanbieter-Apps. Weitere Informationen zum TV Input Framework (TIF) Architektur und ihren Komponenten <ph type="x-smartling-placeholder"></ph> TV Input Framework.

TV-Eingabedienst mithilfe der TIF-Companion-Bibliothek erstellen

Die TIF-Companion-Bibliothek ist ein Framework, das erweiterbare Implementierungen gängiger Funktionen der TV-Eingabedienste. Es ist für OEMs gedacht, um nur für Android 5.0 (API-Level 21) bis Android 7.1 (API-Level 25) verfügbar.

Projekt aktualisieren

Die TIF-Companion-Bibliothek steht OEMs zur alten Verwendung in den androidtv-sample-inputs zu erstellen. In diesem Repository finden Sie ein Beispiel dafür, wie Sie die Bibliothek in eine App einbinden können.

TV-Eingabedienst im Manifest deklarieren

Deine App muss eine mit TvInputService kompatible Dienst, über den das System auf deine App zugreift. Das TIF Die Companion-Bibliothek enthält die Klasse BaseTvInputService, die bietet eine Standardimplementierung von TvInputService die Sie anpassen können. Erstellen Sie eine abgeleitete Klasse von BaseTvInputService, und deklarieren Sie die abgeleitete Klasse in Ihrem Manifest als Dienst.

Gib in der Manifestdeklaration an, Berechtigung BIND_TV_INPUT, um Folgendes zuzulassen: , um den TV-Eingang mit dem System zu verbinden. Ein Systemdienst führt die Bindung aus und Berechtigung „BIND_TV_INPUT“. Die TV-System-App sendet Anfragen an TV-Eingabedienste. über die TvInputManager-Schnittstelle.

Fügen Sie in Ihre Dienstdeklaration einen Intent-Filter ein, der Folgendes angibt: TvInputService als die auszuführende Aktion mit dem die Nutzerabsicht verstehen. Geben Sie außerdem die Dienstmetadaten als separate XML-Ressource an. Die Dienstdeklaration, Intent-Filter und Dienstmetadatendeklaration werden angezeigt im folgenden Beispiel:

<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>

Definieren Sie die Dienstmetadaten in einer separaten XML-Datei. Dienst Metadaten-XML-Datei muss eine Einrichtungsschnittstelle enthalten, in der die TV-Eingabe der ersten Konfiguration und der Kanalsuche. Die Metadatendatei sollte außerdem einen Angabe, ob Nutzer Inhalte aufzeichnen können Weitere Informationen Informationen zur Unterstützung der Aufzeichnung von Inhalten in deiner App findest du unter Unterstützung der Aufzeichnung von Inhalten

Die Dienstmetadatendatei befindet sich im XML-Ressourcenverzeichnis. für Ihre App und muss mit dem Namen der Ressource übereinstimmen, die Sie in der Manifests. Mit den Manifesteinträgen aus dem vorherigen Beispiel Erstellen Sie die XML-Datei unter res/xml/richtvinputservice.xml, mit dem folgenden Inhalt:

<?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" />

Channels definieren und Einrichtungsaktivität erstellen

Ihr TV-Eingabedienst muss mindestens einen Kanal definieren, den Nutzer über die System-TV-App. Du solltest deine Kanäle registrieren. in der Systemdatenbank speichern und eine Einrichtungsaktivität angeben, die das System wird aufgerufen, wenn kein Kanal für Ihre App gefunden werden kann.

Zuerst muss deine App Daten aus der Elektronik des Systems lesen und in diese schreiben können Programming Guide (EPG), dessen Daten verfügbare Kanäle und Programme enthalten für den Nutzer. Um zu ermöglichen, dass Ihre App diese Aktionen ausführen kann, und synchronisieren Sie Fügen Sie nach dem Geräteneustart des elektronischen Programmführers Ihrem App-Manifest die folgenden Elemente hinzu:

<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED "/>

Fügen Sie das folgende Element hinzu, damit Ihre App im Google Play Store als App, die Inhaltskanäle in Android TV anbietet:

<uses-feature
    android:name="android.software.live_tv"
    android:required="true" />

Erstellen Sie als Nächstes eine Klasse, die die EpgSyncJobService erweitert. . Mit dieser abstrakten Klasse können Sie ganz einfach einen Jobdienst erstellen, der Erstellt und aktualisiert Channels in der Systemdatenbank.

Erstellen Sie in Ihrer abgeleiteten Klasse die vollständige Liste der Channels in getChannels() Wenn deine Kanäle aus einer XMLTV-Datei stammen, XmlTvParser verwenden. Andernfalls generieren Sie Kanäle mithilfe der Klasse Channel.Builder programmatisch.

Für jeden Kanal ruft das System getProgramsForChannel() auf. Wenn eine Liste von Programmen benötigt wird, die innerhalb eines bestimmten Zeitfensters angesehen werden können auf dem Kanal. Gibt eine Liste von Program-Objekten zurück für die Kanal. Mit der Klasse XmlTvParser können Sie Programme aus einem XMLTV-Datei oder programmatisch generieren mithilfe der Klasse Program.Builder.

Verwenden Sie für jedes Program-Objekt einen InternalProviderData-Objekt zum Festlegen von Programminformationen wie dem den Videotyp des Programms. Wenn Sie nur eine begrenzte Anzahl von Programmen haben, die Sie der Kanal in einer Schleife wiederholt werden soll, InternalProviderData.setRepeatable()-Methode mit dem Wert true, wenn Sie Informationen zu Ihrem Programm festlegen.

Nachdem Sie den Jobdienst implementiert haben, fügen Sie ihn Ihrem App-Manifest hinzu:

<service
    android:name=".sync.SampleJobService"
    android:permission="android.permission.BIND_JOB_SERVICE"
    android:exported="true" />

Erstellen Sie abschließend eine Einrichtungsaktivität. Ihre Einrichtungsaktivität sollte Ihnen dabei helfen, um Kanal- und Programmdaten zu synchronisieren. Eine Möglichkeit, dies zu tun, besteht darin, über die Benutzeroberfläche in der Aktivität. Vielleicht wird dies auch automatisch von der App erledigt. wann die Aktivität beginnt. Wenn bei der Einrichtung der Kanal und die Programminformationen sollte die App den Jobdienst starten:

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));

Methode requestImmediateSync() für die Synchronisierung verwenden und den Jobdienst. Der Nutzer muss warten, bis die Synchronisierung abgeschlossen ist. Sie sollten sollte der Anfragezeitraum relativ kurz sein.

Verwenden Sie die Methode setUpPeriodicSync(), um den Jobdienst zu erhalten Synchronisieren Sie Kanal- und Programmdaten regelmäßig im Hintergrund:

Kotlin

EpgSyncJobService.setUpPeriodicSync(
        context,
        inputId,
        ComponentName(context, SampleJobService::class.java)
)

Java

EpgSyncJobService.setUpPeriodicSync(context, inputId,
        new ComponentName(context, SampleJobService.class));

Die TIF-Companion-Bibliothek bietet eine zusätzliche überlastete Methode, requestImmediateSync(), mit dem Sie die Dauer der zu synchronisierende Kanaldaten in Millisekunden. Die Standardmethode synchronisiert mit Kanaldaten.

Die TIF-Companion-Bibliothek bietet außerdem eine zusätzliche überlastete Methode zur setUpPeriodicSync(), mit dem Sie die Dauer der die zu synchronisierenden Kanaldaten und wie oft die regelmäßige Synchronisierung stattfinden sollte. Die Bei der Standardmethode werden alle 12 Stunden Kanaldaten für 48 Stunden synchronisiert.

Weitere Informationen zu Kanaldaten und zum elektronischen Programmführer findest du unter Mit Kanaldaten arbeiten

Abstimmungsanfragen und Medienwiedergabe verarbeiten

Wenn ein Nutzer einen bestimmten Kanal auswählt, verwendet die System-TV-App einen Session, von deiner App erstellt, um den angeforderten Kanal einzustellen und Inhalte abspielen. Die TIF-Companion-Bibliothek bietet mehrere Klassen, die Sie erweitern können, um Kanal- und Sitzungsaufrufe aus dem System zu verarbeiten.

Ihre abgeleitete BaseTvInputService-Klasse erstellt Sitzungen, Abstimmungsanfragen. Überschreiben Sie die Methode onCreateSession(), Sitzung erstellen, erweitert von BaseTvInputService.Session und rufen Sie auf super.sessionCreated() durch Ihre neue Sitzung. Im Folgenden Beispiel: onCreateSession() gibt eine RichTvInputSessionImpl-Objekt, das erweitert 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;
}

Wenn der Nutzer die System-TV-App verwendet, um einen Ihrer Kanäle anzusehen, ruft das System die Methode onPlayChannel() Ihrer Sitzung auf. Überschreiben diese Methode verwenden, wenn Sie vor dem Ereignis beginnt die Wiedergabe des Programms.

Das System ruft dann das aktuell geplante Programm ab und ruft Ihre Die Methode onPlayProgram() der Sitzung, die das Programm angibt und die Startzeit in Millisekunden. Verwenden Sie die Methode TvPlayer-Schnittstelle, um die Wiedergabe des Programms zu starten.

Im Code Ihres Mediaplayers sollte TvPlayer implementiert werden, damit bestimmte Wiedergabeereignisse. Die Klasse TvPlayer übernimmt Funktionen z. B. zeitversetzte Nutzung, ohne die Komplexität BaseTvInputService-Implementierung.

Geben Sie in der getTvPlayer()-Methode Ihrer Sitzung Ihrem Mediaplayer, in dem TvPlayer implementiert ist. Die <ph type="x-smartling-placeholder"></ph> Die Beispiel-App „TV Input Service“ implementiert einen Mediaplayer, der ExoPlayer:

TV-Eingabedienst mithilfe des TV-Eingabe-Frameworks erstellen

Wenn Ihr TV-Eingabedienst die TIF-Companion-Bibliothek nicht verwenden kann, müssen Sie um die folgenden Komponenten zu implementieren:

  • TvInputService bietet lange Laufzeit und Hintergrundverfügbarkeit für den TV-Eingang
  • TvInputService.Session behält den TV-Eingabestatus bei und kommuniziert mit der Hosting-App
  • TvContract beschreibt die Kanäle und Programme, die auf dem Fernseher verfügbar sind Eingang
  • TvContract.Channels steht für Informationen zu einem Fernsehkanal
  • TvContract.Programs beschreibt ein Fernsehprogramm mit Daten wie einer Sendung Titel und Beginn
  • TvTrackInfo steht für einen Audio-, Video- oder Untertiteltrack
  • TvContentRating beschreibt eine Altersfreigabe und ermöglicht benutzerdefinierte Inhalte. Bewertungssysteme
  • TvInputManager stellt eine API für die System-TV-App bereit und verwaltet die Interaktion mit TV-Eingängen und Apps

Führen Sie außerdem die folgenden Schritte aus:

  1. Deklariere deinen TV-Eingabedienst im Manifest als wie im Artikel TV-Eingabedienst deklarieren Manifestdatei.
  2. Erstellen Sie die Dienstmetadatendatei.
  3. Erstelle und registriere deine Kanal- und Programminformationen.
  4. Erstellen Sie die Einrichtungsaktivität.

TV-Eingabedienst definieren

Für Ihren Dienst erweitern Sie die TvInputService-Klasse. A Die Implementierung von TvInputService ist ein gebundener Dienst, bei dem der Systemdienst ist der Client, der sich daran bindet. Methoden des Dienstlebenszyklus die in Abbildung 1 dargestellt sind.

Die Methode onCreate() initialisiert und startet den HandlerThread, die einen vom UI-Thread getrennten Prozessthread für und systemgesteuerte Aktionen durchführen. Im folgenden Beispiel wird der onCreate() initialisiert CaptioningManager und bereitet sich auf die Verarbeitung ACTION_BLOCKED_RATINGS_CHANGED und ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED Aktionen. Diese Aktionen beschreiben System-Intents, die ausgelöst werden, wenn der Nutzer die Jugendschutzeinstellungen ändert und wenn Es gibt eine Änderung bei der Liste der blockierten Bewertungen.

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);
}

Abbildung 1.TvInputService-Lebenszyklus:

Weitere Informationen finden Sie unter . Unter „Inhalte verwalten“ finden Sie weitere Informationen zum Umgang mit blockierten Inhalten und zum Bereitstellen Jugendschutzeinstellungen. Unter TvInputManager finden Sie weitere systemgesteuerte Aktionen, die die Sie in Ihrem TV-Eingabedienst verarbeiten können.

Der TvInputService erstellt ein TvInputService.Session, die Handler.Callback implementiert um Änderungen des Player-Status zu verarbeiten. Mit onSetSurface(), Der TvInputService.Session legt den Surface mit dem Wert Videoinhalte. Siehe Player in Oberfläche integrieren finden Sie weitere Informationen zur Verwendung von Surface zum Rendern von Videos.

TvInputService.Session verarbeitet die onTune() wenn der Nutzer einen Kanal auswählt und die System-TV-App über Änderungen an Inhalten und Inhaltsmetadaten. Diese notify()-Methoden werden beschrieben in <ph type="x-smartling-placeholder"></ph> Inhalte verwalten und Track-Auswahl verwalten in dieser Schulung weiter.

Einrichtungsaktivität definieren

Die System-TV-App arbeitet mit der Einrichtungsaktivität, die Sie für Ihre TV-Eingabe definieren. Die Einrichtungsaktivität ist erforderlich und muss mindestens einen Kanaldatensatz für die Systemdatenbank bereitstellen. Die Die System-TV-App ruft die Einrichtungsaktivität auf, wenn kein Kanal für die TV-Eingabe gefunden wird.

In der Einrichtungsaktivität werden für die System-TV-App die Kanäle beschrieben, die über den Fernseher zur Verfügung gestellt werden. wie in der nächsten Lektion, Erstellen und Kanaldaten aktualisieren.

Zusätzliche Referenzen