Android TV verwendet die Android-Suchoberfläche um Inhaltsdaten aus installierten Apps abzurufen und dem Nutzer Suchergebnisse zu liefern. Der können Inhaltsdaten in diese Ergebnisse aufgenommen werden, um dem Nutzer sofortigen Zugriff auf die Inhalte in für Ihre App.
Ihre App muss die Datenfelder an Android TV senden, aus denen Android TV die Vorschläge für die Suche generieren kann
während der Nutzer Zeichen in das Suchdialogfeld eingibt. Dazu muss in Ihrer App ein
Contentanbieter, der Ihre Inhalte bereitstellt
die Vorschläge zusammen mit einem
searchable.xml
-Konfigurationsdatei, die den Inhalt beschreibt
Anbieter und andere wichtige Informationen für Android TV. Sie benötigen auch eine Aktivität,
Intent, der ausgelöst wird, wenn der Nutzer ein vorgeschlagenes Suchergebnis auswählt. Für
erhalten Sie unter
benutzerdefinierte Suchvorschläge In diesem Leitfaden werden die wichtigsten Punkte zu Android TV-Apps behandelt.
Machen Sie sich vor dem Lesen dieses Leitfadens mit den Konzepten vertraut, die in den Leitfaden zur Search API Lesen Sie auch den Hilfeartikel Suchfunktion hinzufügen.
Der Beispielcode in diesem Handbuch stammt aus dem <ph type="x-smartling-placeholder"></ph> Leanback-Beispiel-App .
Spalten identifizieren
In SearchManager
werden die erwarteten Datenfelder beschrieben, indem sie als
Spalten einer lokalen Datenbank. Unabhängig vom Format der Daten müssen Sie Ihre Datenfelder
in der Regel in der Klasse, die auf Ihre Inhaltsdaten zugreift. Informationen zum Erstellen
eine Klasse erstellen, die Ihre vorhandenen Daten den erforderlichen Feldern zuordnet, siehe
<ph type="x-smartling-placeholder"></ph>
Tabelle mit Vorschlägen erstellen
Die Klasse SearchManager
enthält mehrere Spalten für Android TV. Einige der
wichtige Spalten in der folgenden Tabelle beschrieben.
Wert | Beschreibung |
---|---|
SUGGEST_COLUMN_TEXT_1 |
Der Name des Inhalts (erforderlich) |
SUGGEST_COLUMN_TEXT_2 |
Eine Textbeschreibung deiner Inhalte |
SUGGEST_COLUMN_RESULT_CARD_IMAGE |
Ein Bild, Poster oder Cover für deine Inhalte |
SUGGEST_COLUMN_CONTENT_TYPE |
Der MIME-Typ Ihrer Medien |
SUGGEST_COLUMN_VIDEO_WIDTH |
Die Auflösungsbreite deiner Medien |
SUGGEST_COLUMN_VIDEO_HEIGHT |
Die Auflösungshöhe deiner Medien |
SUGGEST_COLUMN_PRODUCTION_YEAR |
Das Produktionsjahr deiner Inhalte (erforderlich) |
SUGGEST_COLUMN_DURATION |
Die Dauer des Mediums in Millisekunden (erforderlich) |
Für das Such-Framework sind folgende Spalten erforderlich:
Wenn die Werte dieser Spalten für Ihren Content mit den Werten für denselben Content aus anderen von Google-Servern gefunden werden, stellt das System eine Deeplink zu Ihrer App in den Details sowie Links zu den Apps anderer Anbieter. Dies wird ausführlicher in im Abschnitt Deeplink zu Ihrer App.
Die Datenbankklasse Ihrer Anwendung könnte die Spalten wie folgt definieren:
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 der SearchManager
-Spalten zu Ihren Datenfeldern erstellen,
muss auch die _ID
angeben, damit jeder Zeile eine eindeutige ID zugewiesen 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 zur SUGGEST_COLUMN_INTENT_DATA_ID
.
ein. Dies ist der Teil der URI, der auf den eindeutigen Inhalt für die Daten in dieser
Zeile: Der letzte Teil des URI, der den Speicherort des Inhalts beschreibt. Der erste Teil des URI,
für alle Zeilen in der Tabelle gilt, wird in der
searchable.xml
als
<ph type="x-smartling-placeholder"></ph>
android:searchSuggestIntentData
, wie in den
Umgang mit Suchvorschlägen.
Wenn sich der erste Teil des URI für jede Zeile in der
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 dem
Kombination aus SUGGEST_COLUMN_INTENT_DATA_ID
und entweder das Attribut android:searchSuggestIntentData
oder
SUGGEST_COLUMN_INTENT_DATA
-Feldwert.
Daten zu Suchvorschlägen angeben
Contentanbieter implementieren
, um Vorschläge für Suchbegriffe im Suchdialog von Android TV zurückzugeben. Ihre Inhalte werden vom System abgefragt.
Anbieter für Vorschläge durch Aufrufen der Methode query()
jedes Mal
ein Buchstabe eingegeben wird. Bei der Implementierung von query()
werden Ihre Inhalte
sucht der Anbieter nach Ihren Vorschlagsdaten und gibt eine Cursor
zurück, die auf
den Zeilen, die Sie für Vorschläge vorgesehen 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 wird der Contentanbieter gesondert behandelt. Anstelle von
wird sie als Aktivität bezeichnet,
<provider>
Die
Der Anbieter verwendet das Attribut android:authorities
, um dem System mitzuteilen,
-Namespace Ihres Contentanbieters. Außerdem müssen Sie das Attribut android:exported
auf
"true"
verwenden, damit die globale Android-Suche die von ihr zurückgegebenen Ergebnisse verwenden kann.
<provider android:name="com.example.android.tvleanback.VideoContentProvider" android:authorities="com.example.android.tvleanback" android:exported="true" />
Suchvorschläge verarbeiten
Deine App muss ein enthalten.
res/xml/searchable.xml
, um die Einstellungen für Suchvorschläge zu konfigurieren.
Fügen Sie in die Datei res/xml/searchable.xml
das
android:searchSuggestAuthority
, um dem System den Namespace Ihres
Contentanbieter. Er muss mit dem Stringwert übereinstimmen, den Sie in den
android:authorities
<provider>
-Attribut
-Element in der Datei AndroidManifest.xml
enthalten.
Fügen Sie außerdem ein Label, Dies ist der Name der Anwendung. In den Einstellungen der Systemsuche wird dieses Label bei der Aufzählung verwendet durchsuchbaren Apps.
Die Datei searchable.xml
muss auch den
android:searchSuggestIntentAction
mit dem Wert "android.intent.action.VIEW"
, um die Intent-Aktion für einen benutzerdefinierten Vorschlag zu definieren. Dies unterscheidet sich von der Absicht,
Aktion zur Angabe eines Suchbegriffs, wie im folgenden Abschnitt beschrieben.
Weitere Möglichkeiten zum Deklarieren der Intent-Aktion für Vorschläge
siehe Deklarieren der
Intent-Aktion.
Zusammen mit der Intent-Aktion muss Ihre App die Intent-Daten bereitstellen, die Sie mit dem
<ph type="x-smartling-placeholder"></ph>
android:searchSuggestIntentData
. Dies ist der erste Teil des URI, der auf
an den Inhalt, wodurch der Teil des URI beschrieben wird, der allen Zeilen in der Zuordnungstabelle gemeinsam ist.
Inhalte. Der Teil des URI, der für jede Zeile eindeutig ist, wird über das Feld SUGGEST_COLUMN_INTENT_DATA_ID
erstellt.
enthalten, wie im Abschnitt Spalten identifizieren beschrieben.
Weitere Möglichkeiten zum Deklarieren der Intent-Daten für Vorschläge findest du unter
Angaben
die Intent-Daten.
Das Attribut android:searchSuggestSelection=" ?"
gibt den übergebenen Wert an
als selection
-Parameter von query()
. Das Fragezeichen (?
) wird durch den Abfragetext ersetzt.
Abschließend müssen Sie auch den Parameter
android:includeInGlobalSearch
-Attribut mit dem Wert "true"
. Hier ist ein Beispiel
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 das Suchdialogfeld ein Wort enthält, das mit dem Wert in einer der Spalten Ihrer App übereinstimmt,
Spalten identifizieren beschrieben, löst das System die
ACTION_SEARCH
Intent.
Die Aktivität in Ihrer App, die dies verarbeitet
Intent durchsucht das Repository nach Spalten, die das angegebene Wort in ihren Werten enthalten, und gibt eine Liste zurück
mit diesen Spalten zu sortieren. In der Datei AndroidManifest.xml
legen Sie fest,
die die ACTION_SEARCH
Intents 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
searchable.xml
-Datei.
So verwenden Sie das Dialogfeld für die globale Suche:
Im Manifest muss angegeben sein, für welche Aktivität Suchanfragen erfasst werden sollen. Das Manifest muss außerdem
<provider>
beschreiben
-Element enthalten, genau so, wie es in der Datei searchable.xml
beschrieben ist.
Deeplink zu Ihrer App auf dem Detailbildschirm
Wenn Sie die Suchkonfiguration wie im Abschnitt zur Verarbeitung der Suche
Vorschläge hinzugefügt und SUGGEST_COLUMN_TEXT_1
,
SUGGEST_COLUMN_PRODUCTION_YEAR
und
SUGGEST_COLUMN_DURATION
-Felder, wie in
im Abschnitt Spalten identifizieren, ein
Deeplink zu einer Wiedergabeaktion für deine Inhalte wird auf dem Bildschirm „Details“ angezeigt, der beim
Der Nutzer wählt ein Suchergebnis aus:
![Deeplink auf dem Detailbildschirm](https://developer.android.google.cn/static/images/tv/deep-link.png?authuser=19&hl=de)
Wenn der Nutzer den Link für Ihre App auswählt, gekennzeichnet durch die Schaltfläche **Verfügbar auf** in der
Details angezeigt, startet das System die Aktivität, mit der die ACTION_VIEW
festlegen als
android:searchSuggestIntentAction
mit dem Wert "android.intent.action.VIEW"
in
die Datei searchable.xml
.
Sie können auch einen benutzerdefinierten Intent einrichten, um Ihre Aktivität zu starten. Dies wird in den
<ph type="x-smartling-placeholder"></ph>
Leanback-Beispiel-App
. Die Beispiel-App startet eine eigene LeanbackDetailsFragment
, um
Details zum ausgewählten Medium aufrufen in Ihren Apps starten Sie die Aktivität, mit der die Medien wiedergegeben werden.
um einen weiteren Klick für den Nutzer zu speichern.
Suchverhalten
Die Suchfunktion in Android TV ist auf dem Startbildschirm und in Ihrer App verfügbar. Suchergebnisse in diesen beiden Fällen unterschiedlich sind.
Vom Startbildschirm aus suchen
Wenn der Nutzer eine Suche auf dem Startbildschirm durchführt, wird das erste Ergebnis in einer Entitätskarte angezeigt. Wenn es Apps, die die Inhalte abspielen können, wird unten auf der Karte ein Link zu jeder App angezeigt:
![Wiedergabe von TV-Suchergebnissen](https://developer.android.google.cn/static/images/tv/tv-search-playback.png?authuser=19&hl=de)
Es ist nicht möglich, eine App programmatisch in die Entitätskarte einzufügen. Einschließlich Wiedergabeoption ausgewählt haben, müssen die Suchergebnisse einer App mit dem Titel, dem Jahr und der Dauer der durchsuchte Inhalte.
Möglicherweise sind unter der Karte weitere Suchergebnisse zu sehen. Um sie zu sehen, muss der Nutzer auf die und scrollen Sie nach unten. Die Ergebnisse für jede Anwendung werden in einer separaten Zeile angezeigt. Sie können die Zeilensortierung. Apps mit Unterstützung Watch Actions werden zuerst aufgeführt.
![TV-Suchergebnisse](https://developer.android.google.cn/static/images/tv/tv-search-results.gif?authuser=19&hl=de)
Über die App suchen
Nutzer können eine Suche auch in Ihrer App starten, indem sie das Mikrofon über die Fernbedienung oder Gamepad-Controller. Die Suchergebnisse werden in einer einzelnen Zeile über dem App-Inhalt angezeigt. Ihre App generiert Suchergebnisse mithilfe ihres eigenen globalen Suchanbieters.
![TV-In-App-Suchergebnisse](https://developer.android.google.cn/static/images/tv/tv-search-in-app.png?authuser=19&hl=de)
Weitere Informationen
Weitere Informationen zur Suche nach einer TV-App findest du unter Integriere Android-Suchfunktionen in deine App und Suchfunktion hinzufügen
Weitere Informationen zum Anpassen der In-App-Suche mit einem SearchFragment
findest du unter
In TV-Apps suchen.