Deine TV-Eingabe muss Daten des elektronischen Programmführers (Electronic Program Guide, EPG) für mindestens für einen Kanal eingerichtet haben. Sie sollten auch diese regelmäßig aktualisieren, Daten unter Berücksichtigung der Größe des Updates und des Verarbeitungs-Threads das sich darum kümmert. Außerdem können Sie App-Links für Kanäle die Nutzende zu ähnlichen Inhalten und Aktivitäten führen. In dieser Lektion erfahren Sie, wie Sie Kanal- und Programmdaten auf der Systemdatenbank diese Überlegungen im Hinterkopf.
Probieren Sie die aus. Beispiel-App „TV Input Service“
Berechtigung einholen
Damit auf Ihrem TV-Eingang Daten aus dem elektronischen Programmführer verarbeitet werden können, muss Folgendes deklariert werden: Schreibberechtigung in der Android-Manifestdatei wie folgt:
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
Kanäle in der Datenbank registrieren
In der Android TV-Systemdatenbank werden Datensätze der Kanaldaten für TV-Eingaben gespeichert. In der Einrichtung
-Aktivität ist, müssen Sie Ihre Channel-Daten für jeden Channel folgenden Feldern der Spalte
Klasse TvContract.Channels
:
COLUMN_DISPLAY_NAME
– der angezeigte Name des KanalCOLUMN_DISPLAY_NUMBER
– der angezeigte Kanal NummerCOLUMN_INPUT_ID
: die ID des TV-EingabedienstesCOLUMN_SERVICE_TYPE
– der Diensttyp des KanalsCOLUMN_TYPE
: der Übertragungsstandard des Kanals TypCOLUMN_VIDEO_FORMAT
– das Standardvideoformat für den Kanal
Obwohl das TV-Eingabesystem allgemein genug ist, um sowohl traditionelle Fernsehsendungen als auch Over-the-Top-Inhalte (OTT) ohne Unterscheidung verwenden möchten, können Sie die folgenden Spalten in ergänzen, um herkömmliche Fernsehkanäle besser identifizieren zu können:
COLUMN_ORIGINAL_NETWORK_ID
– der Fernseher Netzwerk-IDCOLUMN_SERVICE_ID
– die Dienst-IDCOLUMN_TRANSPORT_STREAM_ID
– der Transportstream ID
Wenn du Details zu App-Links für deine Kanäle angeben möchtest, musst du um einige zusätzliche Felder zu aktualisieren. Weitere Informationen zu Feldern für App-Links finden Sie unter Fügen Sie Informationen zu App-Links hinzu.
Weisen Sie bei TV-Eingängen, die auf Internetstreaming basieren, dem Obengen Ihre eigenen Werte zu, damit kann jeder Channel eindeutig identifiziert werden.
Rufe deine Kanalmetadaten (in XML, JSON usw.) von deinem Backend-Server und in deiner Einrichtung ab. werden die Werte folgendermaßen der Systemdatenbank zugeordnet:
Kotlin
val values = ContentValues().apply { put(TvContract.Channels.COLUMN_DISPLAY_NUMBER, channel.number) put(TvContract.Channels.COLUMN_DISPLAY_NAME, channel.name) put(TvContract.Channels.COLUMN_ORIGINAL_NETWORK_ID, channel.originalNetworkId) put(TvContract.Channels.COLUMN_TRANSPORT_STREAM_ID, channel.transportStreamId) put(TvContract.Channels.COLUMN_SERVICE_ID, channel.serviceId) put(TvContract.Channels.COLUMN_VIDEO_FORMAT, channel.videoFormat) } val uri = context.contentResolver.insert(TvContract.Channels.CONTENT_URI, values)
Java
ContentValues values = new ContentValues(); values.put(Channels.COLUMN_DISPLAY_NUMBER, channel.number); values.put(Channels.COLUMN_DISPLAY_NAME, channel.name); values.put(Channels.COLUMN_ORIGINAL_NETWORK_ID, channel.originalNetworkId); values.put(Channels.COLUMN_TRANSPORT_STREAM_ID, channel.transportStreamId); values.put(Channels.COLUMN_SERVICE_ID, channel.serviceId); values.put(Channels.COLUMN_VIDEO_FORMAT, channel.videoFormat); Uri uri = context.getContentResolver().insert(TvContract.Channels.CONTENT_URI, values);
Im obigen Beispiel ist channel
ein Objekt, das Kanalmetadaten aus dem
Back-End-Server.
Kanal- und Programminformationen präsentieren
Die System TV App zeigt Nutzern beim Blättern durch Kanäle Kanal- und Programminformationen an. wie in Abbildung 1 dargestellt. Um sicherzugehen, dass Kanal- und Programminformationen mit den Programmfunktionen der System TV App kompatibel sind, Präsentation von Kanal- und Programminformationen gemäß den unten stehenden Richtlinien.
- Kanalnummer (
COLUMN_DISPLAY_NUMBER
) - Symbol
(
android:icon
in der TV-Eingabe-Manifest) - Programmbeschreibung (
COLUMN_SHORT_DESCRIPTION
) - Programmtitel (
COLUMN_TITLE
) - Kanallogo (
TvContract.Channels.Logo
) <ph type="x-smartling-placeholder">- </ph>
- Verwenden Sie die Farbe #EEEEEE zur Anpassung an den umgebenden Text
- Keine Abstände hinzufügen
- Poster (
COLUMN_POSTER_ART_URI
) <ph type="x-smartling-placeholder">- </ph>
- Seitenverhältnis zwischen 16:9 und 4:3
Die System-TV-App bietet dieselben Informationen über die Programmübersicht, einschließlich Postergrafiken, wie in Abbildung 2 dargestellt.
Kanaldaten aktualisieren
Verwenden Sie beim Aktualisieren vorhandener Channel-Daten die Methode
update()
anstatt die Daten zu löschen und wieder hinzuzufügen. Sie können die aktuelle Version der Daten
mit Channels.COLUMN_VERSION_NUMBER
und Programs.COLUMN_VERSION_NUMBER
bei der Auswahl der zu aktualisierenden Einträge.
Hinweis: Kanaldaten werden zum ContentProvider
hinzugefügt.
kann einige Zeit in Anspruch nehmen. Aktuelle Programme hinzufügen (im Umkreis von zwei Stunden ab der aktuellen Uhrzeit)
wenn du dein EpgSyncJobService
so konfigurierst, dass der Rest aktualisiert wird
der Kanaldaten im Hintergrund. Weitere Informationen finden Sie unter
die
Android TV Live TV Sample App.
Kanaldaten im Batch laden
Wenn du die Systemdatenbank mit einer großen Menge an Kanaldaten aktualisierst, verwende die ContentResolver
applyBatch()
oder
bulkInsert()
. Hier ein Beispiel mit applyBatch()
:
Kotlin
val ops = ArrayList<ContentProviderOperation>() val programsCount = channelInfo.mPrograms.size channelInfo.mPrograms.forEachIndexed { index, program -> ops += ContentProviderOperation.newInsert( TvContract.Programs.CONTENT_URI).run { withValues(programs[index]) withValue(TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS, programStartSec * 1000) withValue( TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS, (programStartSec + program.durationSec) * 1000 ) build() } programStartSec += program.durationSec if (index % 100 == 99 || index == programsCount - 1) { try { contentResolver.applyBatch(TvContract.AUTHORITY, ops) } catch (e: RemoteException) { Log.e(TAG, "Failed to insert programs.", e) return } catch (e: OperationApplicationException) { Log.e(TAG, "Failed to insert programs.", e) return } ops.clear() } }
Java
ArrayList<ContentProviderOperation> ops = new ArrayList<>(); int programsCount = channelInfo.mPrograms.size(); for (int j = 0; j < programsCount; ++j) { ProgramInfo program = channelInfo.mPrograms.get(j); ops.add(ContentProviderOperation.newInsert( TvContract.Programs.CONTENT_URI) .withValues(programs.get(j)) .withValue(Programs.COLUMN_START_TIME_UTC_MILLIS, programStartSec * 1000) .withValue(Programs.COLUMN_END_TIME_UTC_MILLIS, (programStartSec + program.durationSec) * 1000) .build()); programStartSec = programStartSec + program.durationSec; if (j % 100 == 99 || j == programsCount - 1) { try { getContentResolver().applyBatch(TvContract.AUTHORITY, ops); } catch (RemoteException | OperationApplicationException e) { Log.e(TAG, "Failed to insert programs.", e); return; } ops.clear(); } }
Kanaldaten asynchron verarbeiten
Datenmanipulation, z. B. das Abrufen eines Streams vom Server oder der Zugriff auf die Datenbank, sollte
den UI-Thread nicht blockieren. Ein AsyncTask
wird verwendet
Aktualisierungen asynchron durchführen. Wenn du beispielsweise Kanalinformationen
von einem Backend-Server lädst,
können Sie AsyncTask
so verwenden:
Kotlin
private class LoadTvInputTask(val context: Context) : AsyncTask<Uri, Unit, Unit>() { override fun doInBackground(vararg uris: Uri) { try { fetchUri(uris[0]) } catch (e: IOException) { Log.d("LoadTvInputTask", "fetchUri error") } } @Throws(IOException::class) private fun fetchUri(videoUri: Uri) { context.contentResolver.openInputStream(videoUri).use { inputStream -> Xml.newPullParser().also { parser -> try { parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false) parser.setInput(inputStream, null) sTvInput = ChannelXMLParser.parseTvInput(parser) sSampleChannels = ChannelXMLParser.parseChannelXML(parser) } catch (e: XmlPullParserException) { e.printStackTrace() } } } } }
Java
private static class LoadTvInputTask extends AsyncTask<Uri, Void, Void> { private Context mContext; public LoadTvInputTask(Context context) { mContext = context; } @Override protected Void doInBackground(Uri... uris) { try { fetchUri(uris[0]); } catch (IOException e) { Log.d("LoadTvInputTask", "fetchUri error"); } return null; } private void fetchUri(Uri videoUri) throws IOException { InputStream inputStream = null; try { inputStream = mContext.getContentResolver().openInputStream(videoUri); XmlPullParser parser = Xml.newPullParser(); try { parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); parser.setInput(inputStream, null); sTvInput = ChannelXMLParser.parseTvInput(parser); sSampleChannels = ChannelXMLParser.parseChannelXML(parser); } catch (XmlPullParserException e) { e.printStackTrace(); } } finally { if (inputStream != null) { inputStream.close(); } } } }
Wenn Sie EPG-Daten regelmäßig aktualisieren müssen, sollten Sie
WorkManager
um den Aktualisierungsvorgang bei Inaktivität auszuführen, z. B. täglich um 3:00 Uhr.
Weitere Techniken, um die Datenaktualisierungsaufgaben vom UI-Thread zu trennen, sind unter anderem die Verwendung des
HandlerThread
-Klasse, oder Sie können Ihre eigene mit Looper
implementieren.
und Handler
Klassen. Weitere Informationen finden Sie unter .
Prozesse und Threads.
App-Link-Informationen hinzufügen
Kanäle können App-Links verwenden, damit Nutzer auf einfache Weise eine ähnliche während sie sich Kanalinhalte ansehen. Kanal-Apps verwenden um das Nutzer-Engagement zu erhöhen, indem Sie Aktivitäten starten, oder zusätzliche Inhalte. Zum Beispiel können Sie App-Links um Folgendes zu tun:
- Nutzer anleiten, ähnliche Inhalte zu entdecken und zu kaufen
- Hier kannst du zusätzliche Informationen zu den aktuell wiedergegebenen Inhalten angeben.
- Bei der Wiedergabe von Serieninhalten kannst du die nächste Folge in einer .
- Lassen Sie den Nutzer mit Inhalten interagieren, z. B. Bewerten oder Erfahrungsberichte schreiben. ohne die Wiedergabe zu unterbrechen.
App-Links werden angezeigt, wenn der Nutzer auf Auswählen drückt. TV-Menü während der Wiedergabe von Kanalinhalten.
Wenn der Nutzer den App-Link auswählt, startet das System eine Aktivität mit einen Intent-URI, der von der Kanal-App angegeben wird. Inhalte des Kanals werden weiterhin wiedergegeben während die App-Link-Aktivität aktiv ist. Der Nutzer kann zum Kanal zurückkehren. indem Sie auf Zurück drücken.
App-Link-Kanaldaten angeben
Android TV erstellt automatisch einen App-Link für jeden Kanal,
anhand von Informationen aus den Kanaldaten. Um Informationen zu App-Links bereitzustellen,
geben Sie die folgenden Details in Ihrem
TvContract.Channels
-Felder:
COLUMN_APP_LINK_COLOR
: Die Akzentfarbe des App-Links für diesen Kanal. Ein Beispiel für eine Akzentfarbe siehe Abbildung 2, Zusatzinformationen 3.COLUMN_APP_LINK_ICON_URI
– Der URI für das App-Badge-Symbol des App-Links für diesen Kanal. Für eine Beispiel für ein App-Badge, siehe Abbildung 2, Zusatzinformationen 2.COLUMN_APP_LINK_INTENT_URI
– Der Intent-URI des App-Links für diesen Kanal. Sie können den URI erstellen, Verwendung vontoUri(int)
mitURI_INTENT_SCHEME
und konvertieren Sie den URI zurück in den ursprünglichen Intent mitparseUri()
COLUMN_APP_LINK_POSTER_ART_URI
– URI für das Poster, das als Hintergrund des App-Links verwendet wird für diesen Kanal. Ein Beispiel für ein Posterbild finden Sie in Abbildung 2, Zusatzinformationen 1.COLUMN_APP_LINK_TEXT
– Der beschreibende Linktext des App-Links für diesen Kanal. Beispiel App-Link-Beschreibung, siehe Text in Abbildung 2, Zusatzinformationen 3.
Wenn in den Kanaldaten keine App-Link-Informationen angegeben sind, wird ein Standard-App-Link erstellt. Das System wählt die Standarddetails wie folgt aus:
- Für den Intent-URI
(
COLUMN_APP_LINK_INTENT_URI
), verwendet das System dieACTION_MAIN
Aktivität für die KategorieCATEGORY_LEANBACK_LAUNCHER
, in der Regel im App-Manifest definiert. Wenn diese Aktivität nicht definiert ist, wird ein nicht funktionierender App-Link angezeigt, sofern wenn der Nutzer darauf klickt, passiert nichts. - Für den beschreibenden Text
(
COLUMN_APP_LINK_TEXT
), das System verwendet „app-name öffnen“. Wenn kein gültiger URI für den App-Link-Intent definiert ist, verwendet das System „Kein Link verfügbar“. - Für die Akzentfarbe
(
COLUMN_APP_LINK_COLOR
), verwendet das System die Standard-App-Farbe. - Für das Posterbild
(
COLUMN_APP_LINK_POSTER_ART_URI
), verwendet das System das Banner für den Startbildschirm der App. Wenn die App keine Banner verwenden, verwendet das System ein Standardbild für die TV-App. - Für das Logosymbol
(
COLUMN_APP_LINK_ICON_URI
), die verwendet ein Logo, das den App-Namen zeigt. Verwendet das System auch die App-Banner oder Standard-App-Bild für das Posterbild, es wird kein App-Logo angezeigt.
App-Linkdetails für Ihre Kanäle geben Sie in der
Einrichtungsaktivität. Sie können diese App-Linkdetails jederzeit aktualisieren.
App-Link aktualisieren, wenn ein App-Link mit Kanaländerungen übereinstimmen muss
Linkdetails und Anruf
ContentResolver.update()
nach Bedarf. Weitere Informationen zum Aktualisieren
Weitere Informationen zum Aktualisieren von Kanaldaten