Der Startbildschirm von Android TV bietet eine Benutzeroberfläche, auf der empfohlene Inhalte als Tabelle mit Kanälen und Programmen angezeigt werden. Jede Zeile entspricht einem Channel. Ein Kanal enthält Karten für jedes Programm, das auf diesem Kanal verfügbar ist:
In diesem Dokument wird gezeigt, wie du Kanäle und Programme zum Startbildschirm hinzufügst, Inhalte aktualisierst, Nutzeraktionen verarbeitest und Nutzern die bestmögliche Erfahrung bietest. (Wenn du dich näher mit der API beschäftigen möchtest, probiere das Codelab für den Startbildschirm aus und sieh dir die Android TV-Session der I/O 2017 an.)
Die Benutzeroberfläche des Startbildschirms
Apps können neue Kanäle erstellen, die Programme in einem Kanal hinzufügen, entfernen und aktualisieren sowie die Reihenfolge der Programme in einem Kanal steuern. Eine App kann beispielsweise einen Kanal namens „Neuigkeiten“ erstellen und Karten für neu verfügbare Programme anzeigen.
Apps können die Reihenfolge, in der Kanäle auf dem Startbildschirm angezeigt werden, nicht steuern. Wenn deine App einen neuen Kanal erstellt, wird er auf dem Startbildschirm am Ende der Kanalliste hinzugefügt. Der Nutzer kann Kanäle neu anordnen, ausblenden und einblenden.
Der Kanal „Empfohlene Videos“
Der Kanal „Empfohlene Videos“ ist die zweite Zeile, die auf dem Startbildschirm nach der App-Zeile angezeigt wird. Der Kanal wird vom System erstellt und verwaltet. Deine App kann dem Kanal „Empfohlene Videos“ Programme hinzufügen. Weitere Informationen findest du unter Empfohlene Videos zum Kanal „Als Nächstes ansehen“ hinzufügen.
App-Channels
Die von Ihrer App erstellten Kanäle durchlaufen alle diesen Lebenszyklus:
- Der Nutzer entdeckt einen Kanal in deiner App und fordert an, ihn dem Startbildschirm hinzuzufügen.
- Die App erstellt den Kanal und fügt ihn dem
TvProviderhinzu. Zu diesem Zeitpunkt ist der Kanal nicht sichtbar. - Die App fordert das System auf, den Kanal anzuzeigen.
- Das System fordert den Nutzer auf, den neuen Kanal zu genehmigen.
- Der neue Kanal wird in der letzten Zeile des Startbildschirms angezeigt.
Der Standardkanal
Deine App kann beliebig viele Kanäle anbieten, die der Nutzer dem Startbildschirm hinzufügen kann. Der Nutzer muss in der Regel jeden Kanal auswählen und genehmigen, bevor er auf dem Startbildschirm angezeigt wird. Für jede App kann ein Standardkanal erstellt werden. Der Standardkanal ist etwas Besonderes, da er automatisch auf dem Startbildschirm angezeigt wird. Der Nutzer muss ihn nicht explizit anfordern.
Vorbereitung
Der Android TV-Startbildschirm verwendet die TvProvider-APIs von Android, um die von deiner App erstellten Kanäle und Programme zu verwalten. Füge dem Manifest deiner App die folgende Berechtigung hinzu, um auf die Daten des Anbieters zuzugreifen:
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
Die Supportbibliothek TvProvider erleichtert die Verwendung des Anbieters. Fügen Sie sie den Abhängigkeiten in der Datei build.gradle hinzu:
Groovy
implementation 'androidx.tvprovider:tvprovider:1.0.0'
Kotlin
implementation("androidx.tvprovider:tvprovider:1.0.0")
Wenn du mit Kanälen und Programmen arbeiten möchtest, musst du die folgenden Support-Bibliotheken in dein Programm importieren:
Kotlin
import android.support.media.tv.Channel
import android.support.media.tv.TvContractCompat
import android.support.media.tv.ChannelLogoUtils
import android.support.media.tv.PreviewProgram
import android.support.media.tv.WatchNextProgram
Java
import android.support.media.tv.Channel;
import android.support.media.tv.TvContractCompat;
import android.support.media.tv.ChannelLogoUtils;
import android.support.media.tv.PreviewProgram;
import android.support.media.tv.WatchNextProgram;
Kanäle
Der erste Kanal, den Ihre App erstellt, wird zum Standardkanal. Der Standardkanal wird automatisch auf dem Startbildschirm angezeigt. Alle anderen von dir erstellten Kanäle müssen vom Nutzer ausgewählt und akzeptiert werden, bevor sie auf dem Startbildschirm angezeigt werden können.
Kanal erstellen
Ihre App sollte das System nur dann auffordern, neu hinzugefügte Kanäle anzuzeigen, wenn sie im Vordergrund ausgeführt wird. Dadurch wird verhindert, dass in deiner App ein Dialogfeld angezeigt wird, in dem der Nutzer um die Genehmigung zum Hinzufügen deines Kanals gebeten wird, während er eine andere App verwendet. Wenn du versuchst, einen Kanal hinzuzufügen, während die App im Hintergrund ausgeführt wird, gibt die Methode onActivityResult() der Aktivität den Statuscode RESULT_CANCELED zurück.
So erstellen Sie einen Kanal:
Erstellen Sie einen Channel-Builder und legen Sie seine Attribute fest. Der Kanaltyp muss
TYPE_PREVIEWsein. Fügen Sie nach Bedarf weitere Attribute hinzu.Kotlin
val builder = Channel.Builder() // Every channel you create must have the type `TYPE_PREVIEW` builder.setType(TvContractCompat.Channels.TYPE_PREVIEW) .setDisplayName("Channel Name") .setAppLinkIntentUri(uri)Java
Channel.Builder builder = new Channel.Builder(); // Every channel you create must have the type `TYPE_PREVIEW` builder.setType(TvContractCompat.Channels.TYPE_PREVIEW) .setDisplayName("Channel Name") .setAppLinkIntentUri(uri);Fügen Sie den Kanal in den Anbieter ein:
Kotlin
var channelUri = context.contentResolver.insert( TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues())Java
Uri channelUri = context.getContentResolver().insert( TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues());Du musst die Kanal-ID speichern, um dem Kanal später Programme hinzuzufügen. Extrahieren Sie die Kanal-ID aus dem zurückgegebenen URI:
Kotlin
var channelId = ContentUris.parseId(channelUri)Java
long channelId = ContentUris.parseId(channelUri);Sie müssen ein Logo für Ihren Kanal hinzufügen. Verwenden Sie einen
UrioderBitmap. Das Logo-Symbol muss 80 dp × 80 dp groß und undurchsichtig sein. Es wird unter einer kreisförmigen Maske angezeigt:
Kotlin
// Choose one or the other storeChannelLogo(context: Context, channelId: Long, logoUri: Uri) // also works if logoUri is a URL storeChannelLogo(context: Context, channelId: Long, logo: Bitmap)Java
// Choose one or the other storeChannelLogo(Context context, long channelId, Uri logoUri); // also works if logoUri is a URL storeChannelLogo(Context context, long channelId, Bitmap logo);Standardkanal erstellen (optional): Wenn deine App den ersten Kanal erstellt, kannst du ihn als Standardkanal festlegen, damit er sofort auf dem Startbildschirm angezeigt wird, ohne dass der Nutzer etwas tun muss. Alle anderen von Ihnen erstellten Kanäle sind erst sichtbar, wenn der Nutzer sie explizit auswählt.
Kotlin
TvContractCompat.requestChannelBrowsable(context, channelId)Java
TvContractCompat.requestChannelBrowsable(context, channelId);Legen Sie fest, dass Ihr Standardkanal angezeigt wird, bevor Ihre App geöffnet wird. Dieses Verhalten können Sie erreichen, indem Sie einen
BroadcastReceiverhinzufügen, der auf die Aktionandroid.media.tv.action.INITIALIZE_PROGRAMSwartet, die der Startbildschirm nach der Installation der App sendet:<receiver android:name=".RunOnInstallReceiver" android:exported="true"> <intent-filter> <action android:name="android.media.tv.action.INITIALIZE_PROGRAMS" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </receiver>Wenn Sie Ihre App während der Entwicklung per Sideloading installieren, können Sie diesen Schritt testen, indem Sie den Intent über adb auslösen, wobei your.package.name/.YourReceiverName der
BroadcastReceiverIhrer App ist:adb shell am broadcast -a android.media.tv.action.INITIALIZE_PROGRAMS -n \ your.package.name/.YourReceiverNameIn seltenen Fällen empfängt deine App die Übertragung möglicherweise gleichzeitig mit dem Start der App durch den Nutzer. Achte darauf, dass dein Code nicht versucht, den Standardkanal mehr als einmal hinzuzufügen.
Kanal aktualisieren
Das Aktualisieren von Kanälen funktioniert ähnlich wie das Erstellen.
Verwenden Sie ein weiteres Channel.Builder, um die Attribute festzulegen, die geändert werden müssen.
Verwenden Sie ContentResolver, um den Kanal zu aktualisieren. Verwenden Sie die Kanal-ID, die Sie beim ursprünglichen Hinzufügen des Kanals gespeichert haben:
Kotlin
context.contentResolver.update(
TvContractCompat.buildChannelUri(channelId),
builder.build().toContentValues(),
null,
null
)
Java
context.getContentResolver().update(TvContractCompat.buildChannelUri(channelId),
builder.build().toContentValues(), null, null);
Verwenden Sie storeChannelLogo(), um das Logo eines Kanals zu aktualisieren.
Kanal löschen
Kotlin
context.contentResolver.delete(TvContractCompat.buildChannelUri(channelId), null, null)
Java
context.getContentResolver().delete(TvContractCompat.buildChannelUri(channelId), null, null);
Programme
Programme sind die einzelnen Inhaltskarten, die in einem Kanal angezeigt werden. Du kannst Programme sowohl in den benutzerdefinierten Channels deiner App als auch im vom System verwalteten Channel „Empfohlene Videos“ veröffentlichen.
Programme zu einem App-Kanal hinzufügen
Erstellen Sie ein PreviewProgram.Builder und legen Sie die Attribute fest:
Kotlin
val builder = PreviewProgram.Builder()
builder.setChannelId(channelId)
.setType(TvContractCompat.PreviewPrograms.TYPE_CLIP)
.setTitle("Title")
.setDescription("Program description")
.setPosterArtUri(uri)
.setIntentUri(uri)
.setInternalProviderId(appProgramId)
Java
PreviewProgram.Builder builder = new PreviewProgram.Builder();
builder.setChannelId(channelId)
.setType(TvContractCompat.PreviewPrograms.TYPE_CLIP)
.setTitle("Title")
.setDescription("Program description")
.setPosterArtUri(uri)
.setIntentUri(uri)
.setInternalProviderId(appProgramId);
Fügen Sie je nach Programmtyp weitere Attribute hinzu. Die für die einzelnen Programmtypen verfügbaren Attribute finden Sie in den Tabellen unten.
Fügen Sie das Programm in den Anbieter ein:
Kotlin
var programUri = context.contentResolver.insert(TvContractCompat.PreviewPrograms.CONTENT_URI,
builder.build().toContentValues())
Java
Uri programUri = context.getContentResolver().insert(TvContractCompat.PreviewPrograms.CONTENT_URI,
builder.build().toContentValues());
Rufen Sie die Programm-ID zur späteren Verwendung ab:
Kotlin
val programId = ContentUris.parseId(programUri)
Java
long programId = ContentUris.parseId(programUri);
Programme zum Kanal „Empfohlene Videos“ hinzufügen
Informationen zum Einfügen von Programmen in den Kanal „Empfohlene Videos“ findest du unter Programme zum Kanal „Empfohlene Videos“ hinzufügen.
Programm aktualisieren
Sie können die Informationen zu einem Programm ändern. Beispielsweise kannst du den Mietpreis für einen Film oder eine Fortschrittsanzeige aktualisieren, die zeigt, wie viel von einem Programm der Nutzer angesehen hat.
Verwenden Sie ein PreviewProgram.Builder, um die Attribute festzulegen, die Sie ändern möchten, und rufen Sie dann getContentResolver().update auf, um das Programm zu aktualisieren. Geben Sie die Programm-ID an, die Sie beim ursprünglichen Hinzufügen des Programms gespeichert haben:
Kotlin
context.contentResolver.update(
TvContractCompat.buildPreviewProgramUri(programId),
builder.build().toContentValues(), null, null
)
Java
context.getContentResolver().update(TvContractCompat.buildPreviewProgramUri(programId),
builder.build().toContentValues(), null, null);
Programm löschen
Kotlin
context.contentResolver
.delete(TvContractCompat.buildPreviewProgramUri(programId), null, null)
Java
context.getContentResolver().delete(TvContractCompat.buildPreviewProgramUri(programId), null, null);
Nutzeraktionen verarbeiten
Deine App kann Nutzern helfen, Inhalte zu entdecken, indem sie eine Benutzeroberfläche zum Anzeigen und Hinzufügen von Kanälen bereitstellt. Deine App sollte auch Interaktionen mit deinen Kanälen verarbeiten, nachdem sie auf dem Startbildschirm angezeigt wurden.
Kanäle entdecken und hinzufügen
Deine App kann ein UI-Element bereitstellen, über das der Nutzer die Kanäle auswählen und hinzufügen kann (z. B. eine Schaltfläche, über die der Nutzer aufgefordert wird, den Kanal hinzuzufügen).
Nachdem der Nutzer einen bestimmten Kanal angefordert hat, führe diesen Code aus, um die Berechtigung des Nutzers zum Hinzufügen des Kanals zur Startbildschirm-UI zu erhalten:
Kotlin
val intent = Intent(TvContractCompat.ACTION_REQUEST_CHANNEL_BROWSABLE)
intent.putExtra(TvContractCompat.EXTRA_CHANNEL_ID, channelId)
try {
activity.startActivityForResult(intent, 0)
} catch (e: ActivityNotFoundException) {
// handle error
}
Java
Intent intent = new Intent(TvContractCompat.ACTION_REQUEST_CHANNEL_BROWSABLE);
intent.putExtra(TvContractCompat.EXTRA_CHANNEL_ID, channelId);
try {
activity.startActivityForResult(intent, 0);
} catch (ActivityNotFoundException e) {
// handle error
}
Das System zeigt ein Dialogfeld an, in dem der Nutzer aufgefordert wird, den Kanal zu genehmigen. Verarbeiten Sie das Ergebnis der Anfrage in der Methode onActivityResult Ihrer Aktivität (Activity.RESULT_CANCELED oder Activity.RESULT_OK).
Ereignisse auf dem Android TV-Startbildschirm
Wenn der Nutzer mit den von der App veröffentlichten Programmen und Kanälen interagiert, sendet der Startbildschirm Intents an die App:
- Der Startbildschirm sendet den im Attribut APP_LINK_INTENT_URI eines Kanals gespeicherten
Urian die App, wenn der Nutzer das Logo des Kanals auswählt. Die App sollte nur die Haupt-UI oder eine Ansicht starten, die sich auf den ausgewählten Kanal bezieht. - Der Startbildschirm sendet den im INTENT_URI-Attribut eines Programms gespeicherten
Urian die App, wenn der Nutzer ein Programm auswählt. Die App sollte den ausgewählten Inhalt abspielen. - Der Nutzer kann angeben, dass er nicht mehr an einem Programm interessiert ist und es von der Benutzeroberfläche des Startbildschirms entfernt werden soll. Das System entfernt das Programm aus der Benutzeroberfläche und sendet einen Intent (android.media.tv.ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED oder android.media.tv.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED) mit der ID des Programms an die App, zu der das Programm gehört. Die App sollte das Programm vom Anbieter entfernen und NICHT wieder einfügen.
Erstelle Intent-Filter für alle Uris, die der Startbildschirm für Nutzerinteraktionen sendet, z. B.:
<receiver
android:name=".WatchNextProgramRemoved"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.media.tv.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED" />
</intent-filter>
</receiver>
Weitere Überlegungen
- Bei vielen TV-Apps müssen sich Nutzer anmelden. In diesem Fall sollte der
BroadcastReceiver, der aufandroid.media.tv.action.INITIALIZE_PROGRAMSwartet, Kanalinhalte für nicht authentifizierte Nutzer vorschlagen. Ihre App kann beispielsweise zuerst die besten oder aktuell beliebte Inhalte anzeigen. Nachdem sich der Nutzer angemeldet hat, können personalisierte Inhalte angezeigt werden. Das ist eine gute Gelegenheit, Nutzern vor der Anmeldung ein Upgrade anzubieten. - Wenn sich deine App nicht im Vordergrund befindet und du einen Kanal oder ein Programm aktualisieren musst, verwende den
JobScheduler, um die Arbeit zu planen (sieheJobSchedulerundJobService). - Das System kann die Anbieterberechtigungen deiner App widerrufen, wenn sie sich nicht ordnungsgemäß verhält (z. B. wenn sie den Anbieter kontinuierlich mit Daten überflutet). Achten Sie darauf, den Code, der auf den Anbieter zugreift, mit try-catch-Klauseln zu umschließen, um Sicherheitsausnahmen zu verarbeiten.
Bevor du Programme und Kanäle aktualisierst, frage den Anbieter nach den Daten, die du aktualisieren musst, und gleiche die Daten ab. Es ist beispielsweise nicht erforderlich, ein Programm zu aktualisieren, das der Nutzer aus der Benutzeroberfläche entfernen möchte. Verwenden Sie einen Hintergrundjob, der Ihre Daten in den Anbieter einfügt oder aktualisiert, nachdem die vorhandenen Daten abgefragt wurden und die Genehmigung für Ihre Kanäle angefordert wurde. Sie können diesen Job ausführen, wenn die App gestartet wird und wenn die App ihre Daten aktualisieren muss.
Kotlin
context.contentResolver
.query(
TvContractCompat.buildChannelUri(channelId),
null, null, null, null).use({
cursor-> if (cursor != null and cursor.moveToNext()) {
val channel = Channel.fromCursor(cursor)
if (channel.isBrowsable()) {
//update channel's programs
}
}
})
Java
try (Cursor cursor = context.getContentResolver()
.query(
TvContractCompat.buildChannelUri(channelId),
null,
null,
null,
null)) {
if (cursor != null && cursor.moveToNext()) {
Channel channel = Channel.fromCursor(cursor);
if (channel.isBrowsable()) {
//update channel's programs
}
}
}
Verwenden Sie für alle Bilder (Logos, Symbole, Inhaltsbilder) eindeutige URIs. Verwenden Sie beim Aktualisieren eines Images einen anderen URI. Alle Bilder werden im Cache gespeichert. Wenn Sie die URI beim Ändern des Bildes nicht ändern, wird weiterhin das alte Bild angezeigt.
Denken Sie daran, dass WHERE-Klauseln nicht zulässig sind und Aufrufe an die Anbieter mit WHERE-Klauseln eine Sicherheitsausnahme auslösen.
Attribute
In diesem Abschnitt werden die Kanal- und Programmattribute separat beschrieben.
Kanalattribute
Sie müssen diese Attribute für jeden Kanal angeben:
| Attribut | Hinweise |
|---|---|
| TYP | auf TYPE_PREVIEW festgelegt. |
| DISPLAY_NAME | auf den Namen des Kanals festgelegt ist. |
| APP_LINK_INTENT_URI | Wenn der Nutzer das Logo des Kanals auswählt, sendet das System einen Intent, um eine Aktivität zu starten, die für den Kanal relevante Inhalte präsentiert. Legen Sie dieses Attribut auf den URI fest, der im Intent-Filter für diese Aktivität verwendet wird. |
Darüber hinaus hat ein Kanal sechs Felder, die für die interne App-Nutzung reserviert sind. In diesen Feldern können Schlüssel oder andere Werte gespeichert werden, mit denen die App den Kanal der internen Datenstruktur zuordnen kann:
- INTERNAL_PROVIDER_ID
- INTERNAL_PROVIDER_DATA
- INTERNAL_PROVIDER_FLAG1
- INTERNAL_PROVIDER_FLAG2
- INTERNAL_PROVIDER_FLAG3
- INTERNAL_PROVIDER_FLAG4
Programmattribute
Auf den einzelnen Seiten finden Sie die Attribute für die verschiedenen Programmtypen:
- Attribute für Videoprogramme
- Attribute für Audioprogramme
- Attribute für Spieleprogramme
- Attribute für „Empfohlene Videos“
Beispielcode
Weitere Informationen zum Erstellen von Apps, die mit dem Startbildschirm interagieren, und zum Hinzufügen von Kanälen und Programmen zum Android TV-Startbildschirm findest du in unserem Codelab zum Startbildschirm.