Benutzerdefinierte Suchvorschläge hinzufügen

Du kannst Suchvorschläge auf Grundlage der letzten Suchanfragen im Android-Suchdialogfeld oder im Such-Widget geben. Wenn ein Nutzer beispielsweise nach „Welpen“ sucht, wird diese Anfrage als Vorschlag angezeigt, wenn er dieselbe Suchanfrage noch einmal eingibt. Abbildung 1 zeigt ein Beispiel für einen Suchdialog mit Vorschlägen für aktuelle Abfragen.

Bevor Sie beginnen, implementieren Sie das Suchdialogfeld oder ein Such-Widget für einfache Suchanfragen in Ihrer Anwendung. Weitere Informationen dazu finden Sie unter Suchoberfläche erstellen.

Grundlagen

Abbildung 1: Screenshot eines Suchdialogs mit aktuellen Abfragevorschlägen.

Die letzten Vorschläge für Suchanfragen sind gespeicherte Suchanfragen. Wenn der Nutzer einen Vorschlag auswählt, erhält Ihre durchsuchbare Aktivität den Intent ACTION_SEARCH mit dem Vorschlag als Suchanfrage, die von Ihrer durchsuchbaren Aktivität bereits verarbeitet wird.

So machen Sie Vorschläge für letzte Suchanfragen:

  • Implementieren Sie eine durchsuchbare Aktivität.
  • Erstellen Sie einen Contentanbieter, der SearchRecentSuggestionsProvider erweitert, und deklarieren Sie ihn in Ihrem Anwendungsmanifest.
  • Ändern Sie die durchsuchbare Konfiguration mit Informationen über den Contentanbieter, der Suchvorschläge bereitstellt.
  • Speichern Sie Anfragen bei Ihrem Contentanbieter, wenn eine Suche ausgeführt wird.

So wie das Android-System das Suchdialogfeld anzeigt, werden auch dort die Suchvorschläge unter dem Dialogfeld oder Such-Widget angezeigt. Sie geben die Quelle an, aus der das System die Vorschläge abruft.

Wenn das System erkennt, dass Ihre Aktivität suchbar ist, und Suchvorschläge ausgibt, geschieht Folgendes, wenn der Nutzer eine Anfrage eingibt:

  1. Das System nimmt den Text der Suchanfrage – egal, was der Nutzer eingibt – und führt eine Abfrage an den Inhaltsanbieter durch, der deine Vorschläge enthält.
  2. Dein Contentanbieter gibt eine Cursor zurück, die auf alle Vorschläge verweist, die mit dem Text der Suchanfrage übereinstimmen.
  3. Das System zeigt die Liste der Vorschläge an, die vom Cursor bereitgestellt wird.

Sobald die Vorschläge für die letzten Abfragen angezeigt werden, kann Folgendes passieren:

  • Gibt der Nutzer einen anderen Schlüssel ein oder ändert die Abfrage, werden die vorherigen Schritte wiederholt und die Vorschlagsliste aktualisiert.
  • Wenn der Nutzer die Suche ausführt, werden die Vorschläge ignoriert und die Suche wird mit dem normalen ACTION_SEARCH-Intent an deine durchsuchbare Aktivität übergeben.
  • Wenn der Nutzer einen Vorschlag auswählt, wird der vorgeschlagene Text als Abfrage verwendet und der Intent ACTION_SEARCH an Ihre durchsuchbare Aktivität gesendet.

Die SearchRecentSuggestionsProvider-Klasse, die Sie für Ihren Contentanbieter erweitern, übernimmt automatisch die Arbeit in den vorherigen Schritten, sodass nur wenig Code geschrieben werden muss.

Contentanbieter erstellen

Der Contentanbieter, den Sie für aktuelle Abfragevorschläge benötigen, ist eine Implementierung von SearchRecentSuggestionsProvider. In diesem Kurs wird alles für dich erledigt. Sie müssen nur einen Klassenkonstruktor schreiben, der eine Codezeile ausführt.

Hier ist beispielsweise eine vollständige Implementierung eines Inhaltsanbieters für aktuelle Abfragevorschläge:

Kotlin

class MySuggestionProvider : SearchRecentSuggestionsProvider() {
    init {
        setupSuggestions(AUTHORITY, MODE)
    }

    companion object {
        const val AUTHORITY = "com.example.MySuggestionProvider"
        const val MODE: Int = SearchRecentSuggestionsProvider.DATABASE_MODE_QUERIES
    }
}

Java

public class MySuggestionProvider extends SearchRecentSuggestionsProvider {
    public final static String AUTHORITY = "com.example.MySuggestionProvider";
    public final static int MODE = DATABASE_MODE_QUERIES;

    public MySuggestionProvider() {
        setupSuggestions(AUTHORITY, MODE);
    }
}

Mit dem Aufruf von setupSuggestions() werden der Name der Suchstelle und ein Datenbankmodus übergeben. Die Suchautorität kann ein beliebiger eindeutiger String sein. Es empfiehlt sich jedoch, einen voll qualifizierten Namen für Ihren Contentanbieter zu verwenden, z. B. den Paketnamen gefolgt vom Klassennamen des Anbieters. Beispiel: "com.example.MySuggestionProvider".

Der Datenbankmodus muss DATABASE_MODE_QUERIES und optional DATABASE_MODE_2LINES enthalten. Dadurch wird der Vorschlagstabelle eine Spalte hinzugefügt, sodass Sie für jeden Vorschlag eine zweite Textzeile angeben können. Im folgenden Beispiel können Sie in jedem Vorschlag zwei Zeilen einfügen:

Kotlin

const val MODE: Int = DATABASE_MODE_QUERIES or DATABASE_MODE_2LINES

Java

public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;

Deklarieren Sie den Contentanbieter in Ihrem Anwendungsmanifest mit demselben Autorisierungsstring, der in der SearchRecentSuggestionsProvider-Klasse und in der durchsuchbaren Konfiguration verwendet wird. Beispiel:

<application>
    <provider android:name=".MySuggestionProvider"
              android:authorities="com.example.MySuggestionProvider" />
    ...
</application>

Konfiguration für durchsuchbare Elemente ändern

Wenn Sie das System für die Verwendung Ihres Vorschlagsanbieters konfigurieren möchten, fügen Sie dem Element <searchable> in der durchsuchbaren Konfigurationsdatei die Attribute android:searchSuggestAuthority und android:searchSuggestSelection hinzu. Beispiel:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_label"
    android:hint="@string/search_hint"
    android:searchSuggestAuthority="com.example.MySuggestionProvider"
    android:searchSuggestSelection=" ?" >
</searchable>

Der Wert für android:searchSuggestAuthority muss ein voll qualifizierter Name für Ihren Contentanbieter sein, der genau mit der im Contentanbieter verwendeten Zertifizierungsstelle übereinstimmt, z. B. "com.example.MySuggestionProvider" in den vorherigen Beispielen.

Der Wert für android:searchSuggestSelection muss ein einzelnes Fragezeichen mit einem Leerzeichen sein: " ?". Dies ist ein Platzhalter für das SQLite-Auswahlargument, das automatisch durch den vom Nutzer eingegebenen Abfragetext ersetzt wird.

Abfragen speichern

Wenn Sie Ihre letzten Abfragen füllen möchten, fügen Sie jede Abfrage, die Ihre Suchaktivitäten erhalten haben, Ihrem SearchRecentSuggestionsProvider hinzu. Erstellen Sie dazu eine Instanz von SearchRecentSuggestions und rufen Sie saveRecentQuery() jedes Mal auf, wenn Ihre durchsuchbare Aktivität eine Abfrage empfängt. So können Sie beispielsweise die Abfrage während der Methode onCreate() Ihrer Aktivität speichern:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main)

    if (Intent.ACTION_SEARCH == intent.action) {
        intent.getStringExtra(SearchManager.QUERY)?.also { query ->
            SearchRecentSuggestions(this, MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE)
                    .saveRecentQuery(query, null)
        }
    }
}

Java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Intent intent  = getIntent();

    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String query = intent.getStringExtra(SearchManager.QUERY);
        SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
                MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE);
        suggestions.saveRecentQuery(query, null);
    }
}

Der Konstruktor SearchRecentSuggestionsProvider benötigt dieselbe Berechtigung und denselben Datenbankmodus, die von Ihrem Inhaltsanbieter deklariert wurden.

Die Methode saveRecentQuery() verwendet den Suchabfragestring als ersten Parameter und optional einen zweiten String, der in die zweite Zeile des Vorschlags aufgenommen werden soll, oder auf null. Der zweite Parameter wird nur verwendet, wenn Sie mit DATABASE_MODE_2LINES den zweizeiligen Modus für die Suchvorschläge aktivieren. Wenn Sie den zweizeiligen Modus aktivieren, stimmt der Abfragetext mit der zweiten Zeile überein, wenn das System nach passenden Vorschlägen sucht.

Vorschlagsdaten löschen

Bieten Sie dem Nutzer aus Datenschutzgründen immer eine Möglichkeit, die letzten Abfragevorschläge zu löschen. Rufen Sie clearHistory() auf, um den Abfrageverlauf zu löschen. Beispiele:

Kotlin

SearchRecentSuggestions(this, HelloSuggestionsProvider.AUTHORITY, HelloSuggestionsProvider.MODE)
        .clearHistory()

Java

SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
        HelloSuggestionProvider.AUTHORITY, HelloSuggestionProvider.MODE);
suggestions.clearHistory();

Diese Option kannst du über den Menüpunkt „Suchverlauf löschen“, einen Einstellungspunkt oder eine Schaltfläche deiner Wahl ausführen. Geben Sie ein Bestätigungsdialogfeld ein, um zu bestätigen, dass der Nutzer seinen Suchverlauf löschen möchte.