TV-Apps suchbar machen

Android TV verwendet die Suchoberfläche von Android, um Inhaltsdaten aus installierten Apps abzurufen und dem Nutzer Suchergebnisse zu liefern. Die Inhaltsdaten Ihrer App können in diese Ergebnisse aufgenommen werden, um dem Nutzer sofortigen Zugriff auf die Inhalte der App zu ermöglichen.

Ihre App muss Android TV die Datenfelder zur Verfügung stellen, aus denen Android TV vorgeschlagene Suchergebnisse generieren kann, wenn der Nutzer Zeichen in das Suchdialogfeld eingibt. Dazu muss in deiner App ein Contentanbieter implementiert werden, der die Vorschläge zusammen mit einer searchable.xml-Konfigurationsdatei bereitstellt. Diese Datei enthält eine Beschreibung des Contentanbieters und andere wichtige Informationen für Android TV. Außerdem benötigen Sie eine Aktivität, die den Intent verarbeitet, der ausgelöst wird, wenn der Nutzer ein vorgeschlagenes Suchergebnis auswählt. Weitere Informationen finden Sie unter Benutzerdefinierte Suchvorschläge hinzufügen. In diesem Leitfaden werden die wichtigsten Punkte für Android TV-Apps behandelt.

Machen Sie sich vor dem Lesen dieser Anleitung mit den Konzepten vertraut, die im Search API-Leitfaden erläutert werden. Lesen Sie auch den Artikel Suchfunktion hinzufügen.

Der Beispielcode in diesem Leitfaden stammt aus der Leanback-Beispiel-App.

Spalten identifizieren

Der SearchManager beschreibt die erwarteten Datenfelder, indem er sie als Spalten einer lokalen Datenbank darstellt. Unabhängig vom Format der Daten müssen Sie die Datenfelder diesen Spalten zuordnen. Dies geschieht normalerweise in der Klasse, die auf die Inhaltsdaten zugreift. Informationen zum Erstellen einer Klasse, die Ihre vorhandenen Daten den erforderlichen Feldern zuordnet, finden Sie unter Tabelle mit Vorschlägen erstellen.

Die Klasse SearchManager enthält mehrere Spalten für Android TV. Einige der wichtigeren Spalten werden in der folgenden Tabelle beschrieben.

Antwort Beschreibung
SUGGEST_COLUMN_TEXT_1 Der Name der Inhalte (erforderlich)
SUGGEST_COLUMN_TEXT_2 Eine Textbeschreibung Ihrer Inhalte
SUGGEST_COLUMN_RESULT_CARD_IMAGE Ein Bild, ein Poster oder ein Cover für Ihre Inhalte
SUGGEST_COLUMN_CONTENT_TYPE Der MIME-Typ Ihrer Medien
SUGGEST_COLUMN_VIDEO_WIDTH Die Auflösungsbreite deiner Medien
SUGGEST_COLUMN_VIDEO_HEIGHT Die Höhe der Auflösung deiner Medien
SUGGEST_COLUMN_PRODUCTION_YEAR Das Produktionsjahr deiner Inhalte (erforderlich)
SUGGEST_COLUMN_DURATION Die Dauer Ihrer Medien in Millisekunden (erforderlich)

Für das Such-Framework sind folgende Spalten erforderlich:

Wenn die Werte dieser Spalten für Ihren Inhalt mit den Werten für denselben Inhalt übereinstimmen, die von den Google-Servern gefunden wurden, stellt das System in der Detailansicht des Inhalts einen Deeplink zu Ihrer App sowie Links zu den Apps anderer Anbieter bereit. Weitere Informationen dazu finden Sie im Abschnitt Deeplink zu Ihrer App im Detailbildschirm.

Die Datenbankklasse Ihrer Anwendung definiert die Spalten möglicherweise so:

Kotlin

class VideoDatabase {
    companion object {
        // The columns we'll include in the video database table
        val KEY_NAME = SearchManager.SUGGEST_COLUMN_TEXT_1
        val KEY_DESCRIPTION = SearchManager.SUGGEST_COLUMN_TEXT_2
        val KEY_ICON = SearchManager.SUGGEST_COLUMN_RESULT_CARD_IMAGE
        val KEY_DATA_TYPE = SearchManager.SUGGEST_COLUMN_CONTENT_TYPE
        val KEY_IS_LIVE = SearchManager.SUGGEST_COLUMN_IS_LIVE
        val KEY_VIDEO_WIDTH = SearchManager.SUGGEST_COLUMN_VIDEO_WIDTH
        val KEY_VIDEO_HEIGHT = SearchManager.SUGGEST_COLUMN_VIDEO_HEIGHT
        val KEY_AUDIO_CHANNEL_CONFIG = SearchManager.SUGGEST_COLUMN_AUDIO_CHANNEL_CONFIG
        val KEY_PURCHASE_PRICE = SearchManager.SUGGEST_COLUMN_PURCHASE_PRICE
        val KEY_RENTAL_PRICE = SearchManager.SUGGEST_COLUMN_RENTAL_PRICE
        val KEY_RATING_STYLE = SearchManager.SUGGEST_COLUMN_RATING_STYLE
        val KEY_RATING_SCORE = SearchManager.SUGGEST_COLUMN_RATING_SCORE
        val KEY_PRODUCTION_YEAR = SearchManager.SUGGEST_COLUMN_PRODUCTION_YEAR
        val KEY_COLUMN_DURATION = SearchManager.SUGGEST_COLUMN_DURATION
        val KEY_ACTION = SearchManager.SUGGEST_COLUMN_INTENT_ACTION
        ...
    }
    ...
}

Java

public class VideoDatabase {
    // The columns we'll include in the video database table
    public static final String KEY_NAME = SearchManager.SUGGEST_COLUMN_TEXT_1;
    public static final String KEY_DESCRIPTION = SearchManager.SUGGEST_COLUMN_TEXT_2;
    public static final String KEY_ICON = SearchManager.SUGGEST_COLUMN_RESULT_CARD_IMAGE;
    public static final String KEY_DATA_TYPE = SearchManager.SUGGEST_COLUMN_CONTENT_TYPE;
    public static final String KEY_IS_LIVE = SearchManager.SUGGEST_COLUMN_IS_LIVE;
    public static final String KEY_VIDEO_WIDTH = SearchManager.SUGGEST_COLUMN_VIDEO_WIDTH;
    public static final String KEY_VIDEO_HEIGHT = SearchManager.SUGGEST_COLUMN_VIDEO_HEIGHT;
    public static final String KEY_AUDIO_CHANNEL_CONFIG =
            SearchManager.SUGGEST_COLUMN_AUDIO_CHANNEL_CONFIG;
    public static final String KEY_PURCHASE_PRICE = SearchManager.SUGGEST_COLUMN_PURCHASE_PRICE;
    public static final String KEY_RENTAL_PRICE = SearchManager.SUGGEST_COLUMN_RENTAL_PRICE;
    public static final String KEY_RATING_STYLE = SearchManager.SUGGEST_COLUMN_RATING_STYLE;
    public static final String KEY_RATING_SCORE = SearchManager.SUGGEST_COLUMN_RATING_SCORE;
    public static final String KEY_PRODUCTION_YEAR = SearchManager.SUGGEST_COLUMN_PRODUCTION_YEAR;
    public static final String KEY_COLUMN_DURATION = SearchManager.SUGGEST_COLUMN_DURATION;
    public static final String KEY_ACTION = SearchManager.SUGGEST_COLUMN_INTENT_ACTION;
...

Wenn Sie die Zuordnung aus den SearchManager-Spalten zu Ihren Datenfeldern erstellen, müssen Sie auch die _ID angeben, damit jeder Zeile eine eindeutige ID zugeteilt wird.

Kotlin


companion object {
    ....
    private fun buildColumnMap(): Map<String, String> {
        return mapOf(
          KEY_NAME to KEY_NAME,
          KEY_DESCRIPTION to KEY_DESCRIPTION,
          KEY_ICON to KEY_ICON,
          KEY_DATA_TYPE to KEY_DATA_TYPE,
          KEY_IS_LIVE to KEY_IS_LIVE,
          KEY_VIDEO_WIDTH to KEY_VIDEO_WIDTH,
          KEY_VIDEO_HEIGHT to KEY_VIDEO_HEIGHT,
          KEY_AUDIO_CHANNEL_CONFIG to KEY_AUDIO_CHANNEL_CONFIG,
          KEY_PURCHASE_PRICE to KEY_PURCHASE_PRICE,
          KEY_RENTAL_PRICE to KEY_RENTAL_PRICE,
          KEY_RATING_STYLE to KEY_RATING_STYLE,
          KEY_RATING_SCORE to KEY_RATING_SCORE,
          KEY_PRODUCTION_YEAR to KEY_PRODUCTION_YEAR,
          KEY_COLUMN_DURATION to KEY_COLUMN_DURATION,
          KEY_ACTION to KEY_ACTION,
          BaseColumns._ID to ("rowid AS " + BaseColumns._ID),
          SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID to ("rowid AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID),
          SearchManager.SUGGEST_COLUMN_SHORTCUT_ID to ("rowid AS " + SearchManager.SUGGEST_COLUMN_SHORTCUT_ID)
        )
    }
}

Java

...
  private static HashMap<String, String> buildColumnMap() {
    HashMap<String, String> map = new HashMap<String, String>();
    map.put(KEY_NAME, KEY_NAME);
    map.put(KEY_DESCRIPTION, KEY_DESCRIPTION);
    map.put(KEY_ICON, KEY_ICON);
    map.put(KEY_DATA_TYPE, KEY_DATA_TYPE);
    map.put(KEY_IS_LIVE, KEY_IS_LIVE);
    map.put(KEY_VIDEO_WIDTH, KEY_VIDEO_WIDTH);
    map.put(KEY_VIDEO_HEIGHT, KEY_VIDEO_HEIGHT);
    map.put(KEY_AUDIO_CHANNEL_CONFIG, KEY_AUDIO_CHANNEL_CONFIG);
    map.put(KEY_PURCHASE_PRICE, KEY_PURCHASE_PRICE);
    map.put(KEY_RENTAL_PRICE, KEY_RENTAL_PRICE);
    map.put(KEY_RATING_STYLE, KEY_RATING_STYLE);
    map.put(KEY_RATING_SCORE, KEY_RATING_SCORE);
    map.put(KEY_PRODUCTION_YEAR, KEY_PRODUCTION_YEAR);
    map.put(KEY_COLUMN_DURATION, KEY_COLUMN_DURATION);
    map.put(KEY_ACTION, KEY_ACTION);
    map.put(BaseColumns._ID, "rowid AS " +
            BaseColumns._ID);
    map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, "rowid AS " +
            SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
    map.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID, "rowid AS " +
            SearchManager.SUGGEST_COLUMN_SHORTCUT_ID);
    return map;
  }
...

Beachten Sie im vorherigen Beispiel die Zuordnung zum Feld SUGGEST_COLUMN_INTENT_DATA_ID. Dies ist der Teil des URI, der auf den für die Daten in dieser Zeile eindeutigen Inhalt verweist. Dies ist der letzte Teil des URI, der beschreibt, wo der Inhalt gespeichert ist. Der erste Teil des URI, der in allen Zeilen der Tabelle gemeinsam ist, wird in der Datei searchable.xml als Attribut android:searchSuggestIntentData festgelegt, wie im Abschnitt Suchvorschläge verarbeiten beschrieben.

Wenn der erste Teil des URI für jede Zeile in der Tabelle unterschiedlich ist, ordnen Sie diesen Wert dem Feld SUGGEST_COLUMN_INTENT_DATA zu. Wenn der Nutzer diesen Inhalt auswählt, liefert der ausgelöste Intent die Intent-Daten aus der Kombination von SUGGEST_COLUMN_INTENT_DATA_ID und entweder dem Attribut android:searchSuggestIntentData oder dem Feldwert SUGGEST_COLUMN_INTENT_DATA.

Daten zu Suchvorschlägen bereitstellen

Implementieren Sie einen Contentanbieter, damit im Suchdialogfeld von Android TV Vorschläge für Suchbegriffe angezeigt werden. Das System fragt Ihren Contentanbieter nach Vorschlägen ab, indem bei jeder Eingabe eines Buchstabens die Methode query() aufgerufen wird. Bei der Implementierung von query() durchsucht Ihr Contentanbieter Ihre Vorschlagsdaten und gibt ein Cursor zurück, das auf die Zeilen verweist, die Sie für Vorschläge angegeben haben.

Kotlin

fun query(uri: Uri, projection: Array<String>, selection: String, selectionArgs: Array<String>,
        sortOrder: String): Cursor {
    // Use the UriMatcher to see what kind of query we have and format the db query accordingly
    when (URI_MATCHER.match(uri)) {
        SEARCH_SUGGEST -> {
            Log.d(TAG, "search suggest: ${selectionArgs[0]} URI: $uri")
            if (selectionArgs == null) {
                throw IllegalArgumentException(
                        "selectionArgs must be provided for the Uri: $uri")
            }
            return getSuggestions(selectionArgs[0])
        }
        else -> throw IllegalArgumentException("Unknown Uri: $uri")
    }
}

private fun getSuggestions(query: String): Cursor {
    val columns = arrayOf<String>(
            BaseColumns._ID,
            VideoDatabase.KEY_NAME,
            VideoDatabase.KEY_DESCRIPTION,
            VideoDatabase.KEY_ICON,
            VideoDatabase.KEY_DATA_TYPE,
            VideoDatabase.KEY_IS_LIVE,
            VideoDatabase.KEY_VIDEO_WIDTH,
            VideoDatabase.KEY_VIDEO_HEIGHT,
            VideoDatabase.KEY_AUDIO_CHANNEL_CONFIG,
            VideoDatabase.KEY_PURCHASE_PRICE,
            VideoDatabase.KEY_RENTAL_PRICE,
            VideoDatabase.KEY_RATING_STYLE,
            VideoDatabase.KEY_RATING_SCORE,
            VideoDatabase.KEY_PRODUCTION_YEAR,
            VideoDatabase.KEY_COLUMN_DURATION,
            VideoDatabase.KEY_ACTION,
            SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID
    )
    return videoDatabase.getWordMatch(query.toLowerCase(), columns)
}

Java

@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
        String sortOrder) {
    // Use the UriMatcher to see what kind of query we have and format the db query accordingly
    switch (URI_MATCHER.match(uri)) {
        case SEARCH_SUGGEST:
            Log.d(TAG, "search suggest: " + selectionArgs[0] + " URI: " + uri);
            if (selectionArgs == null) {
                throw new IllegalArgumentException(
                        "selectionArgs must be provided for the Uri: " + uri);
            }
            return getSuggestions(selectionArgs[0]);
        default:
            throw new IllegalArgumentException("Unknown Uri: " + uri);
    }
}

private Cursor getSuggestions(String query) {
    query = query.toLowerCase();
    String[] columns = new String[]{
        BaseColumns._ID,
        VideoDatabase.KEY_NAME,
        VideoDatabase.KEY_DESCRIPTION,
        VideoDatabase.KEY_ICON,
        VideoDatabase.KEY_DATA_TYPE,
        VideoDatabase.KEY_IS_LIVE,
        VideoDatabase.KEY_VIDEO_WIDTH,
        VideoDatabase.KEY_VIDEO_HEIGHT,
        VideoDatabase.KEY_AUDIO_CHANNEL_CONFIG,
        VideoDatabase.KEY_PURCHASE_PRICE,
        VideoDatabase.KEY_RENTAL_PRICE,
        VideoDatabase.KEY_RATING_STYLE,
        VideoDatabase.KEY_RATING_SCORE,
        VideoDatabase.KEY_PRODUCTION_YEAR,
        VideoDatabase.KEY_COLUMN_DURATION,
        VideoDatabase.KEY_ACTION,
        SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID
    };
    return videoDatabase.getWordMatch(query, columns);
}
...

In Ihrer Manifestdatei erhält der Contentanbieter eine Sonderbehandlung. Er wird nicht als Aktivität getaggt, sondern als <provider> beschrieben. Der Anbieter enthält das Attribut android:authorities, um dem System den Namespace Ihres Contentanbieters mitzuteilen. Außerdem musst du das Attribut android:exported auf "true" setzen, damit die von ihr zurückgegebenen Ergebnisse für die globale Android-Suche verwendet werden können.

<provider android:name="com.example.android.tvleanback.VideoContentProvider"
    android:authorities="com.example.android.tvleanback"
    android:exported="true" />

Suchvorschläge verarbeiten

Deine App muss die Datei res/xml/searchable.xml enthalten, damit die Einstellungen für Suchvorschläge konfiguriert werden können.

Fügen Sie in der Datei res/xml/searchable.xml das Attribut android:searchSuggestAuthority ein, um dem System den Namespace Ihres Contentanbieters mitzuteilen. Er muss mit dem Stringwert übereinstimmen, den Sie im Attribut android:authorities des Elements <provider> in der Datei AndroidManifest.xml angegeben haben.

Fügen Sie auch ein Label hinzu, also den Namen der Anwendung. In den Einstellungen der Systemsuche wird dieses Label bei der Aufzählung der suchbaren Anwendungen verwendet.

Die Datei searchable.xml muss außerdem android:searchSuggestIntentAction mit dem Wert "android.intent.action.VIEW" enthalten, um die Intent-Aktion für die Bereitstellung eines benutzerdefinierten Vorschlags zu definieren. Dies unterscheidet sich von der Intent-Aktion zum Bereitstellen eines Suchbegriffs, die im folgenden Abschnitt beschrieben wird. Weitere Möglichkeiten zum Deklarieren der Intent-Aktion für Vorschläge finden Sie unter Intent-Aktion deklarieren.

Zusammen mit der Intent-Aktion muss Ihre App die Intent-Daten zur Verfügung stellen, die Sie mit dem Attribut android:searchSuggestIntentData angeben. Dies ist der erste Teil des URI, der auf den Inhalt verweist. Damit wird der Teil des URI beschrieben, der allen Zeilen in der Zuordnungstabelle für diesen Inhalt gemeinsam ist. Der Teil des URI, der für jede Zeile eindeutig ist, wird mit dem Feld SUGGEST_COLUMN_INTENT_DATA_ID festgelegt, wie im Abschnitt Spalten identifizieren beschrieben. Weitere Möglichkeiten zur Deklaration von Intent-Daten für Vorschläge finden Sie unter Intent-Daten deklarieren.

Das Attribut android:searchSuggestSelection=" ?" gibt den Wert an, der als selection-Parameter der Methode query() übergeben wird. Das Fragezeichen (?) wird durch den Text der Abfrage ersetzt.

Abschließend müssen Sie auch das Attribut android:includeInGlobalSearch mit dem Wert "true" angeben. Hier ist ein Beispiel für eine searchable.xml-Datei:

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/search_label"
    android:hint="@string/search_hint"
    android:searchSettingsDescription="@string/settings_description"
    android:searchSuggestAuthority="com.example.android.tvleanback"
    android:searchSuggestIntentAction="android.intent.action.VIEW"
    android:searchSuggestIntentData="content://com.example.android.tvleanback/video_database_leanback"
    android:searchSuggestSelection=" ?"
    android:searchSuggestThreshold="1"
    android:includeInGlobalSearch="true">
</searchable>

Suchbegriffe verarbeiten

Sobald im Suchdialogfeld ein Wort enthalten ist, das mit dem Wert in einer der Spalten Ihrer App übereinstimmt (siehe Abschnitt Spalten identifizieren), löst das System den Intent ACTION_SEARCH aus. Die Aktivität in Ihrer Anwendung, die diesen Intent verarbeitet, durchsucht das Repository nach Spalten mit dem angegebenen Wort in ihren Werten und gibt eine Liste von Inhaltselementen mit diesen Spalten zurück. In der Datei AndroidManifest.xml legen Sie die Aktivität fest, die den ACTION_SEARCH-Intent verarbeitet, wie im folgenden Beispiel gezeigt:

...
  <activity
      android:name="com.example.android.tvleanback.DetailsActivity"
      android:exported="true">

      <!-- Receives the search request. -->
      <intent-filter>
          <action android:name="android.intent.action.SEARCH" />
          <!-- No category needed, because the Intent will specify this class component -->
      </intent-filter>

      <!-- Points to searchable meta data. -->
      <meta-data android:name="android.app.searchable"
          android:resource="@xml/searchable" />
  </activity>
...
  <!-- Provides search suggestions for keywords against video meta data. -->
  <provider android:name="com.example.android.tvleanback.VideoContentProvider"
      android:authorities="com.example.android.tvleanback"
      android:exported="true" />
...

Die Aktivität muss auch die durchsuchbare Konfiguration mit einem Verweis auf die Datei searchable.xml beschreiben. Damit das Dialogfeld für die globale Suche verwendet werden kann, muss im Manifest beschrieben werden, welche Aktivität Suchanfragen erhalten soll. Das Manifest muss außerdem das Element <provider> genau so beschreiben, wie in der Datei searchable.xml beschrieben.

Deeplink zu Ihrer App auf dem Detailbildschirm

Wenn du die Suchkonfiguration wie im Abschnitt Suchvorschläge verarbeiten beschrieben und die Felder SUGGEST_COLUMN_TEXT_1, SUGGEST_COLUMN_PRODUCTION_YEAR und SUGGEST_COLUMN_DURATION wie im Abschnitt Spalten identifizieren beschrieben zugeordnet hast, wird auf dem Detailbildschirm ein Deeplink zu einer Wiedergabeaktion für deine Inhalte angezeigt, der gestartet wird, wenn der Nutzer ein Suchergebnis auswählt:

Deeplink auf dem Detailbildschirm

Wenn der Nutzer den Link für Ihre App auswählt, der auf der Schaltfläche **Verfügbar für** im Detailbildschirm angezeigt wird, startet das System die Aktivität, die die ACTION_VIEW verarbeitet, die als android:searchSuggestIntentAction mit dem Wert "android.intent.action.VIEW" in der Datei searchable.xml festgelegt wurde.

Sie können auch eine benutzerdefinierte Zielgruppe mit gemeinsamer Absicht einrichten, um Ihre Aktivität zu starten. Dies wird in der Leanback-Beispiel-App veranschaulicht. Die Beispiel-App startet ihre eigene LeanbackDetailsFragment, um die Details für die ausgewählten Medien anzuzeigen. Starten Sie in Ihren Apps die Aktivität, mit der die Medien sofort wiedergegeben werden, um dem Nutzer weitere Klicks zu ersparen.

Suchverhalten

Die Suche ist in Android TV auf dem Startbildschirm und in der App verfügbar. Die Suchergebnisse unterscheiden sich in diesen beiden Fällen.

Auf dem Startbildschirm suchen

Wenn der Nutzer auf dem Startbildschirm eine Suche ausführt, wird das erste Ergebnis auf einer Entitätskarte angezeigt. Wenn es Apps gibt, mit denen die Inhalte wiedergegeben werden können, wird unten auf der Karte ein Link zu jeder dieser Apps angezeigt:

Wiedergabe von TV-Suchergebnissen

Sie können eine App nicht programmatisch auf der Entitätskarte platzieren. Damit eine App als Wiedergabeoption einbezogen werden kann, müssen die Suchergebnisse mit dem Titel, dem Jahr und der Dauer des gesuchten Inhalts übereinstimmen.

Unter Umständen sind unter der Karte weitere Suchergebnisse verfügbar. Um sie zu sehen, muss der Nutzer auf die Fernbedienung drücken und nach unten scrollen. Die Ergebnisse für jede App werden in einer separaten Zeile angezeigt. Sie können die Zeilenreihenfolge nicht steuern. Apps, die Wiedergabeaktionen unterstützen, werden zuerst aufgeführt.

TV-Suchergebnisse

Über die App suchen

Der Nutzer kann auch aus Ihrer App heraus eine Suche starten, indem er das Mikrofon über den Fernbedienungs- oder Gamepad-Controller initiiert. Die Suchergebnisse werden in einer einzelnen Zeile über dem Inhalt der App angezeigt. Ihre App generiert Suchergebnisse mithilfe eines eigenen globalen Suchanbieters.

Suchergebnisse für In-App-TV

Weitere Informationen

Weitere Informationen zur Suche nach einer TV-App findest du unter Android-Suchfunktionen in deine App integrieren und Suchfunktionen hinzufügen.

Weitere Informationen zum Anpassen der In-App-Suche mit einem SearchFragment findest du unter In TV-Apps suchen.