Dodawanie niestandardowych sugestii wyszukiwania

Sugestie wyszukiwania przygotowane na podstawie ostatnich zapytań możesz podać w oknie wyszukiwania w Androidzie lub w widżecie wyszukiwania. Jeśli np. użytkownik wpisze to samo zapytanie ponownie, pojawi się ono jako sugestia. Rysunek 1 przedstawia przykład okna wyszukiwania z ostatnimi sugestiami zapytań.

Zanim zaczniesz, zaimplementuj okno wyszukiwania lub widżet wyszukiwania do podstawowych wyszukiwań w swojej aplikacji. Aby dowiedzieć się, jak to zrobić, przeczytaj artykuł Tworzenie interfejsu wyszukiwania.

Podstawy

Rysunek 1. Zrzut ekranu okna wyszukiwania z ostatnimi sugestiami zapytań.

Ostatnie sugestie zapytań to zapisane wyszukiwania. Gdy użytkownik wybierze sugestię, działanie dostępne do przeszukiwania otrzymuje intencję ACTION_SEARCH z sugestią jako zapytaniem, którym już się zajmuje wyszukiwanie.

Aby wyświetlić sugestie dotyczące ostatnich zapytań:

  • Zaimplementuj aktywność, którą można przeszukiwać.
  • Utwórz dostawcę treści, który rozszerza zakres SearchRecentSuggestionsProvider, i zadeklaruj to w pliku manifestu aplikacji.
  • Zmodyfikuj konfigurację możliwości wyszukiwania, korzystając z informacji o dostawcy treści, który udostępnia sugestie wyszukiwania.
  • Zapisuj zapytania w usłudze dostawcy treści po każdym wykonaniu wyszukiwania.

Tak jak system Android wyświetla okno wyszukiwania, wyświetla sugestie wyszukiwania pod oknem dialogowym lub widżetem wyszukiwania. Podaj źródło, z którego system pobiera sugestie.

Jeśli system wykryje, że aktywność jest możliwa do wyszukania, i zaproponuje sugestie wyszukiwania, po wpisaniu zapytania przez użytkownika:

  1. System pobiera tekst zapytania (ten, który użytkownik zaczyna wpisywać) i wysyła zapytanie do dostawcy treści zawierającego Twoje sugestie.
  2. Dostawca treści zwraca funkcję Cursor wskazującą wszystkie sugestie, które pasują do treści zapytania.
  3. System wyświetli listę sugestii podanych przez funkcję Cursor.

Po wyświetleniu ostatnich sugestii zapytań może wydarzyć się coś takiego:

  • Jeśli użytkownik wpisze inny klucz lub w jakikolwiek sposób zmieni zapytanie, poprzednie kroki zostaną powtórzone, a lista sugestii zostanie zaktualizowana.
  • Jeśli użytkownik wykona wyszukiwanie, sugestie zostaną zignorowane, a wyszukiwanie zostanie uwzględnione w aktywności, którą można przeszukiwać, przy użyciu zwykłej intencji ACTION_SEARCH.
  • Jeśli użytkownik wybierze sugestię, do Twojej aktywności, którą można wyszukać, zostanie wykorzystana intencja ACTION_SEARCH wykorzystująca sugerowany tekst jako zapytanie.

Klasa SearchRecentSuggestionsProvider, którą rozszerzysz na potrzeby dostawcy treści, automatycznie wykonuje zadania z poprzednich kroków, więc nie musisz pisać zbyt dużo kodu.

Utwórz dostawcę treści

Dostawca treści, którego potrzebujesz w przypadku ostatnich sugestii dotyczących zapytań, to implementacja SearchRecentSuggestionsProvider. Na tych zajęciach możesz robić wszystko za Ciebie. Wystarczy napisać konstruktor klas wykonujący 1 wiersz kodu.

Tak na przykład wygląda pełną implementację dostawcy treści w przypadku ostatnich sugestii zapytań:

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

Wywołanie setupSuggestions() przekazuje nazwę urzędu wyszukiwania i tryb bazy danych. Usługą wyszukiwania może być dowolny unikalny ciąg znaków, ale sprawdzona metoda to użycie pełnej i jednoznacznej nazwy dostawcy treści, np. nazwy pakietu, a po nim nazwy klasy dostawcy. Przykład: "com.example.MySuggestionProvider".

Tryb bazy danych musi uwzględniać właściwość DATABASE_MODE_QUERIES i opcjonalnie może zawierać element DATABASE_MODE_2LINES, który dodaje kolumnę do tabeli sugestii, dzięki czemu możesz podać drugi wiersz tekstu z każdą sugestią. Jeśli w każdej z nich chcesz umieścić 2 wiersze, skorzystaj z tego przykładu:

Kotlin

const val MODE: Int = DATABASE_MODE_QUERIES or DATABASE_MODE_2LINES

Java

public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;

Zadeklaruj dostawcę treści w manifeście aplikacji z tym samym ciągiem znaków autoryzacji, który jest używany w klasie SearchRecentSuggestionsProvider i w konfiguracji, którą można przeszukiwać. Przykład:

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

Modyfikowanie konfiguracji możliwości wyszukiwania

Aby skonfigurować system do korzystania z Twojego dostawcy sugestii, dodaj atrybuty android:searchSuggestAuthority i android:searchSuggestSelection do elementu <searchable> w pliku konfiguracji, który można przeszukiwać. Przykład:

<?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>

Wartość właściwości android:searchSuggestAuthority musi być w pełni kwalifikowaną nazwą dostawcy treści i musi być dokładnie taka sama jak nazwa użytego przez niego dostawcy treści, np. "com.example.MySuggestionProvider" we wcześniejszych przykładach.

Wartość pola android:searchSuggestSelection musi być pojedynczym znakiem zapytania poprzedzonym spacją: " ?". Jest to obiekt zastępczy argumentu wyboru SQLite. Jest on automatycznie zastępowany tekstem zapytania wpisanym przez użytkownika.

Zapisz zapytania

Aby zapełnić swoją kolekcję ostatnich zapytań, dodaj do SearchRecentSuggestionsProvider wszystkie zapytania otrzymane przez aktywność związaną z wyszukiwaniem. W tym celu utwórz instancję SearchRecentSuggestions i wywołuj saveRecentQuery() za każdym razem, gdy działanie dostępne do przeszukiwania otrzyma zapytanie. Na przykład w ten sposób możesz zapisać zapytanie podczas korzystania z metody onCreate() aktywności:

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

Konstruktor SearchRecentSuggestionsProvider wymaga tych samych uprawnień i trybu bazy danych zadeklarowanych przez dostawcę treści.

Metoda saveRecentQuery() przyjmuje ciąg zapytania jako pierwszy parametr i opcjonalnie drugi ciąg do uwzględnienia jako drugi wiersz sugestii lub wartość null. Drugi parametr jest używany tylko wtedy, gdy włączysz tryb dwuwierszowy dla sugestii wyszukiwania z parametrem DATABASE_MODE_2LINES. Po włączeniu trybu dwuwierszowego tekst zapytania jest dopasowywany do drugiego wiersza, gdy system szuka pasujących sugestii.

Wyczyść dane sugestii

Aby chronić prywatność użytkownika, zawsze umożliwiaj mu usunięcie ostatnich sugestii zapytań. Aby wyczyścić historię zapytań, wywołaj funkcję clearHistory(). Na przykład:

Kotlin

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

Java

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

Możesz to zrobić, wybierając element menu, preferencję lub przycisk „Wyczyść historię wyszukiwania”. Wyświetl okno dialogowe z potwierdzeniem, że użytkownik chce usunąć historię wyszukiwania.