Kanäle auf dem Startbildschirm

Der Android TV-Startbildschirm, oder einfach der Startbildschirm, stellt eine Benutzeroberfläche bereit, auf der empfohlene Inhalte in einer Tabelle mit Kanälen und Programmen angezeigt werden. Jede Zeile entspricht einem Channel. Ein Kanal enthält Infokarten für jedes dort verfügbare Programm:

Startbildschirm des Fernsehers

In diesem Dokument wird erläutert, wie Sie Kanäle und Programme zum Startbildschirm hinzufügen, Inhalte aktualisieren, Nutzeraktionen verarbeiten und die beste Nutzererfahrung bieten. Weitere Informationen zur API finden Sie im Codelab für den Startbildschirm und in der Android TV-Sitzung I/O 2017.

Hinweis:Empfehlungskanäle sind erst ab Android 8.0 (API-Level 26) verfügbar. Sie müssen sie verwenden, um Empfehlungen für Apps zu geben, die unter Android 8.0 (API-Level 26) und höher ausgeführt werden. Um Empfehlungen für Apps bereitzustellen, die unter früheren Android-Versionen ausgeführt werden, muss Ihre App stattdessen die Zeile „Empfehlungen“ verwenden.

Benutzeroberfläche des Startbildschirms

Apps können neue Kanäle erstellen, Programme in einem Kanal hinzufügen, entfernen und aktualisieren und die Reihenfolge der Programme in einem Kanal steuern. Beispielsweise kann eine App einen Kanal namens „Neue Funktionen“ erstellen und Karten für neu verfügbare Programme anzeigen.

Apps können nicht steuern, in welcher Reihenfolge Kanäle auf dem Startbildschirm angezeigt werden. Wenn Ihre 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 anzeigen.

Kanal „Als Nächstes ansehen“

Der Kanal „Empfohlene Videos“ ist die zweite Zeile, die auf dem Startbildschirm nach der App-Zeile angezeigt wird. Der Channel wird vom System erstellt und verwaltet. Deine App kann dem Kanal „Als Nächstes ansehen“ Programme hinzufügen. Weitere Informationen findest du unter Programme zum Kanal „Als Nächstes ansehen“ hinzufügen.

App-Kanäle

Alle von Ihrer App erstellten Channels folgen diesem Lebenszyklus:

  1. Der Nutzer stößt in deiner App auf einen Kanal und bittet ihn, ihn zum Startbildschirm hinzuzufügen.
  2. Die App erstellt den Kanal und fügt ihn dem TvProvider hinzu. Zu diesem Zeitpunkt ist der Kanal nicht sichtbar.
  3. Die App fordert das System auf, den Kanal anzuzeigen.
  4. Der Nutzer wird vom System aufgefordert, den neuen Kanal zu genehmigen.
  5. Der neue Kanal wird in der letzten Zeile des Startbildschirms angezeigt.

Standardkanal

Ihre App kann eine beliebige Anzahl von Kanälen anbieten, die der Nutzer zum 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 besonders, da er automatisch auf dem Startbildschirm angezeigt wird. Der Nutzer muss ihn nicht explizit anfordern.

Voraussetzungen

Auf dem Android TV-Startbildschirm werden die TvProvider APIs von Android verwendet, um die von deiner App erstellten Kanäle und Programme zu verwalten. Fügen Sie dem Manifest Ihrer 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 TvProvider-Supportbibliothek erleichtert die Verwendung des Anbieters. Fügen Sie ihn den Abhängigkeiten in der Datei build.gradle hinzu:

Groovig

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, achte darauf, die folgenden unterstützenden Bibliotheksimporte in dein Programm aufzunehmen:

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 deine App erstellt, wird als Standardkanal festgelegt. Der Standardkanal wird automatisch auf dem Startbildschirm angezeigt. Alle anderen Kanäle, die du erstellst, 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 auffordern, neu hinzugefügte Kanäle nur dann anzuzeigen, wenn sie im Vordergrund ausgeführt werden. Dadurch wird in deiner App kein Dialogfeld angezeigt, in dem das Hinzufügen deines Kanals genehmigt werden muss, während der Nutzer eine andere App ausführt. Wenn du versuchst, einen Kanal hinzuzufügen, während er im Hintergrund ausgeführt wird, gibt die Methode onActivityResult() der Aktivität den Statuscode RESULT_CANCELED zurück.

So erstellst du einen Kanal:

  1. Einen Channel-Builder erstellen und seine Attribute festlegen Der Kanaltyp muss TYPE_PREVIEW sein. Fügen Sie bei 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);
    
  2. 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());
    
  3. Du musst die Kanal-ID speichern, um dem Kanal später Programme hinzufügen zu können. Extrahieren Sie die Kanal-ID aus dem zurückgegebenen URI:

    Kotlin

    var channelId = ContentUris.parseId(channelUri)
    

    Java

    long channelId = ContentUris.parseId(channelUri);
    
  4. Du musst deinem Kanal ein Logo hinzufügen. Verwenden Sie Uri oder Bitmap. Das Logo muss eine Größe von 80 dp x 80 dp haben und undurchsichtig sein. Sie wird unter einer kreisförmigen Maske angezeigt:

    Maske für Symbol des Fernseher-Startbildschirms

    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);
    
  5. Standardkanal erstellen (optional): Wenn Ihre App den ersten Kanal erstellt, können Sie sie als Standardkanal festlegen. Sie wird dann sofort ohne Nutzeraktion auf dem Startbildschirm angezeigt. Andere Kanäle, die Sie erstellen, sind erst sichtbar, wenn der Nutzer sie explizit auswählt.

    Kotlin

    TvContractCompat.requestChannelBrowsable(context, channelId)
    

    Java

    TvContractCompat.requestChannelBrowsable(context, channelId);
    

  6. Du kannst festlegen, dass dein Standardkanal angezeigt wird, bevor deine App geöffnet wird. Dazu kannst du ein BroadcastReceiver hinzufügen, das auf die Aktion android.media.tv.action.INITIALIZE_PROGRAMS wartet, die vom Startbildschirm nach der Installation der App gesendet wird:
    <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>
    
    Beim Sideloading deiner App während der Entwicklung kannst du diesen Schritt testen, indem du den Intent über ADB auslöst, wobei your.package.name/.YourReceiverName die BroadcastReceiver deiner App ist:

    adb shell am broadcast -a android.media.tv.action.INITIALIZE_PROGRAMS -n \
        your.package.name/.YourReceiverName
    

    In seltenen Fällen kann es vorkommen, dass Ihre App den Broadcast gleichzeitig empfängt, während der Nutzer Ihre App startet. Achten Sie darauf, dass Ihr Code nicht versucht, den Standardkanal mehr als einmal hinzuzufügen.

Kanal aktualisieren

Das Aktualisieren von Channels ist dem Erstellen von Channels sehr ähnlich.

Verwenden Sie einen anderen Channel.Builder, um die Attribute festzulegen, die geändert werden müssen.

Verwende die ContentResolver, um den Kanal zu aktualisieren. Verwende die Kanal-ID, die du beim Hinzufügen des Kanals gespeichert hast:

Kotlin

context.contentResolver.update(
        TvContractCompat.buildChannelUri(channelId),
        builder.build().toContentValues(),
        null,
        null
)

Java

context.getContentResolver().update(TvContractCompat.buildChannelUri(channelId),
    builder.build().toContentValues(), null, null);

Verwende 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

Programmen zu einem App-Kanal hinzufügen

Erstellen Sie eine PreviewProgram.Builder und legen Sie ihre 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 Art des Programms weitere Attribute hinzu. Die für die einzelnen Programmtypen verfügbaren Attribute finden Sie in den nachfolgenden Tabellen.

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 für später ab:

Kotlin

val programId = ContentUris.parseId(programUri)

Java

long programId = ContentUris.parseId(programUri);

Programme zum Kanal „Als Nächstes ansehen“ hinzufügen

Informationen dazu, wie du Programme in den Kanal „Als Nächstes ansehen“ einfügst, findest du unter Programme zum Kanal „Als Nächstes ansehen“ hinzufügen.

Programm aktualisieren

Sie können die Informationen eines Programms ändern. Sie können beispielsweise den Leihpreis für einen Film oder eine Fortschrittsanzeige aktualisieren, die anzeigt, wie viel ein Programm sich der Nutzer angesehen hat.

Verwenden Sie PreviewProgram.Builder, um die Attribute festzulegen, die Sie ändern müssen, und rufen Sie dann getContentResolver().update auf, um das Programm zu aktualisieren. Gib die Programm-ID an, die du gespeichert hast, als das Programm hinzugefügt wurde:

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

Umgang mit Nutzeraktionen

Deine App kann Nutzern beim Entdecken von Inhalten helfen, 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 diese auf dem Startbildschirm angezeigt wurden.

Kanäle entdecken und hinzufügen

Ihre App kann ein UI-Element bereitstellen, über das der Nutzer Kanäle auswählen und hinzufügen kann, z. B. eine Schaltfläche, über die der Kanal hinzugefügt werden kann.

Nachdem der Nutzer einen bestimmten Kanal angefordert hat, führe diesen Code aus, um die Berechtigung des Nutzers zu erhalten, ihn zur Benutzeroberfläche des Startbildschirms hinzuzufügen:

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
}

Im System wird ein Dialogfeld angezeigt, 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).

Android TV-Startbildschirm-Ereignisse

Wenn der Nutzer mit den von der App veröffentlichten Programmen/Kanälen interagiert, sendet der Startbildschirm Intents an die App:

  • Wenn der Nutzer das Logo des Kanals auswählt, wird vom Startbildschirm die im Attribut APP_LINK_INTENT_URI eines Kanals gespeicherte Uri an die App gesendet. Die App sollte nur die Hauptbenutzeroberfläche oder eine Ansicht aufrufen, die sich auf den ausgewählten Kanal bezieht.
  • Wenn der Nutzer ein Programm auswählt, sendet der Startbildschirm die im Attribut INTENT_URI eines Programms gespeicherte Uri an die App. Die App sollte die ausgewählten Inhalte wiedergeben.
  • Der Nutzer kann angeben, dass er nicht mehr an einem Programm interessiert ist und es von der Benutzeroberfläche des Startbildschirms entfernen lassen möchte. Das System entfernt das Programm von der Benutzeroberfläche und sendet der App, die Inhaber des Programms ist, einen Intent (android.media.tv.ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED oder android.media.tv.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED) mit der Programm-ID. Die App sollte das Programm vom Anbieter entfernen und NICHT noch einmal einsetzen.

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>

Best Practices

  • Bei vielen TV-Apps müssen sich Nutzer anmelden. In diesem Fall sollte der BroadcastReceiver, der auf android.media.tv.action.INITIALIZE_PROGRAMS wartet, Kanalinhalte für nicht authentifizierte Nutzer vorschlagen.Ihre App kann beispielsweise zuerst die besten Inhalte oder aktuell beliebte Inhalte anzeigen. Nach der Anmeldung werden personalisierte Inhalte angezeigt. Dies ist eine gute Chance für Apps, Up-Selling zu betreiben, bevor sie sich anmelden.
  • Wenn deine App nicht im Vordergrund ausgeführt wird und du einen Kanal oder ein Programm aktualisieren musst, verwende JobScheduler, um die Arbeit zu planen (siehe: JobScheduler und JobService).
  • Das System kann die Anbieterberechtigungen der App widerrufen, wenn sich die App falsch verhält (z. B. ständiges Spamming des Anbieters mit Daten). Sie müssen den Code, der auf den Anbieter zugreift, mit „try-catch“-Klauseln verpacken, um Sicherheitsausnahmen zu verarbeiten.
  • Fragen Sie vor dem Aktualisieren von Programmen und Kanälen den Anbieter nach den Daten ab, die Sie aktualisieren und abgleichen müssen. Beispielsweise muss ein Programm, das der Nutzer aus der Benutzeroberfläche entfernen möchte, nicht aktualisiert werden. Verwenden Sie einen Hintergrundjob, mit dem Ihre Daten beim Anbieter eingefügt oder aktualisiert werden, nachdem die vorhandenen Daten abgefragt und dann die Genehmigung für Ihre Kanäle angefordert wurde. Sie können diesen Job beim Start der Anwendung und immer dann ausführen, wenn die Anwendung 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 eindeutige URIs für alle Bilder (Logos, Symbole, Inhaltsbilder). Achten Sie darauf, einen anderen URI zu verwenden, wenn Sie ein Bild aktualisieren. Alle Bilder werden im Cache gespeichert. Wenn Sie den 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 der Anbieter mit WHERE-Klauseln eine Sicherheitsausnahme auslösen.

Merkmale

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 ist auf den Namen des Channels festgelegt.
APP_LINK_INTENT_URI Wenn der Nutzer das Logo des Kanals auswählt, sendet das System eine Absicht zum Starten einer Aktivität, bei der für den Kanal relevante Inhalte präsentiert werden. Legen Sie für dieses Attribut den URI fest, der im Intent-Filter für diese Aktivität verwendet wird.

Darüber hinaus verfügt ein Kanal über 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 ihrer internen Datenstruktur zuordnen kann:

  • INTERN_ANBIETER_ID
  • INTERN_ANBIETERDATEN
  • INTERN_ANBIETER_FLAG1
  • INTERN_ANBIETER_FLAG2
  • INTERN_ANBIETER_FLAG3
  • INTERN_ANBIETER_FLAG4

Programmattribute

Die Attribute für die einzelnen Programmtypen finden Sie auf den einzelnen Seiten:

Beispielcode

Weitere Informationen zum Erstellen von Apps, die mit dem Startbildschirm interagieren und Kanäle und Programme zum Android TV-Startbildschirm hinzufügen, finden Sie in unserem Codelab für den Startbildschirm.