Ajouter des suggestions de recherche personnalisées

Essayez la méthode Compose
Jetpack Compose est le kit d'outils d'interface utilisateur recommandé pour Android. Découvrez comment ajouter une fonctionnalité de recherche dans Compose.

Vous pouvez fournir des suggestions de recherche basées sur les requêtes de recherche récentes dans la boîte de dialogue de recherche Android ou le widget de recherche. Par exemple, si un utilisateur recherche "chiots", la requête apparaît comme suggestion lorsqu'il la saisit à nouveau. La figure 1 montre un exemple de boîte de dialogue de recherche avec des suggestions de requêtes récentes.

Avant de commencer, implémentez la boîte de dialogue de recherche ou un widget de recherche pour les recherches de base dans votre application. Pour savoir comment procéder, consultez Créer une interface de recherche.

Principes de base

Figure 1. Capture d'écran d'une boîte de dialogue de recherche avec des suggestions de requêtes récentes.

Les suggestions de requêtes récentes sont des recherches enregistrées. Lorsque l'utilisateur sélectionne une suggestion, votre activité indexable reçoit un intent ACTION_SEARCH avec la suggestion comme requête de recherche que votre activité indexable gère déjà.

Pour fournir des suggestions de requêtes récentes, vous devez procéder comme suit :

  • Implémenter une activité indexable.
  • Créer un fournisseur de contenu qui étend SearchRecentSuggestionsProvider et le déclarer dans le fichier manifeste de votre application.
  • Modifier la configuration indexable avec des informations sur le fournisseur de contenu qui fournit des suggestions de recherche.
  • Enregistrer les requêtes dans votre fournisseur de contenu chaque fois qu'une recherche est exécutée.

Tout comme le système Android affiche la boîte de dialogue de recherche, il affiche les suggestions de recherche sous la boîte de dialogue ou le widget de recherche. Vous fournissez la source à partir de laquelle le système récupère les suggestions.

Lorsque le système identifie que votre activité est indexable et fournit des suggestions de recherche, voici ce qui se passe lorsque l'utilisateur saisit une requête :

  1. Le système prend le texte de la requête de recherche (tout ce que l'utilisateur commence à saisir) et effectue une requête auprès du fournisseur de contenu qui contient vos suggestions.
  2. Votre fournisseur de contenu renvoie un Cursor qui pointe vers toutes les suggestions correspondant au texte de la requête de recherche.
  3. Le système affiche la liste des suggestions fournies par le Cursor.

Une fois les suggestions de requêtes récentes affichées, les événements suivants peuvent se produire :

  • Si l'utilisateur appuie sur une autre touche ou modifie la requête de quelque manière que ce soit, les étapes précédentes sont répétées et la liste de suggestions est mise à jour.
  • Si l'utilisateur exécute la recherche, les suggestions sont ignorées et la recherche est transmise à votre activité indexable à l'aide de l'intent ACTION_SEARCH normal.
  • Si l'utilisateur sélectionne une suggestion, un ACTION_SEARCH intent est transmis à votre activité indexable à l'aide du texte suggéré comme requête.

La classe SearchRecentSuggestionsProvider que vous étendez pour votre fournisseur de contenu effectue automatiquement le travail décrit dans les étapes précédentes. Vous n'avez donc que peu de code à écrire.

Créer un fournisseur de contenu

Le fournisseur de contenu dont vous avez besoin pour les suggestions de requêtes récentes est une implémentation de SearchRecentSuggestionsProvider. Cette classe fait tout pour vous. Il vous suffit d'écrire un constructeur de classe qui exécute une ligne de code.

Par exemple, voici une implémentation complète d'un fournisseur de contenu pour les suggestions de requêtes récentes :

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

L'appel à setupSuggestions() transmet le nom de l'autorité de recherche et un mode de base de données. L'autorité de recherche peut être n'importe quelle chaîne unique, mais la bonne pratique consiste à utiliser un nom complet pour votre fournisseur de contenu, tel que le nom du package suivi du nom de la classe du fournisseur. Par exemple, "com.example.MySuggestionProvider".

Le mode de base de données doit inclure DATABASE_MODE_QUERIES et peut éventuellement inclure DATABASE_MODE_2LINES, qui ajoute une colonne au tableau de suggestions afin que vous puissiez fournir une deuxième ligne de texte avec chaque suggestion. Si vous souhaitez fournir deux lignes dans chaque suggestion, consultez l'exemple suivant :

Kotlin

const val MODE: Int = DATABASE_MODE_QUERIES or DATABASE_MODE_2LINES

Java

public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;

Déclarez le fournisseur de contenu dans le fichier manifeste de votre application avec la même chaîne d'autorité que celle utilisée dans votre classe SearchRecentSuggestionsProvider et dans la configuration indexable. Exemple :

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

Modifier la configuration indexable

Pour configurer le système afin qu'il utilise votre fournisseur de suggestions, ajoutez les android:searchSuggestAuthority et android:searchSuggestSelection attributs à l'élément <searchable> dans votre fichier de configuration indexable. Exemple :

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

La valeur de android:searchSuggestAuthority doit être un nom complet pour votre fournisseur de contenu qui correspond exactement à l'autorité utilisée dans le fournisseur de contenu, comme "com.example.MySuggestionProvider" dans les exemples précédents.

La valeur de android:searchSuggestSelection doit être un seul point d'interrogation précédé d'un espace : " ?". Il s'agit d'un espace réservé pour l'argument de sélection SQLite, qui est automatiquement remplacé par le texte de la requête saisi par l'utilisateur.

Enregistrer les requêtes

Pour remplir votre collection de requêtes récentes, ajoutez chaque requête reçue par votre activité indexable à votre SearchRecentSuggestionsProvider. Pour ce faire, créez une instance de SearchRecentSuggestions et appelez saveRecentQuery() chaque fois que votre activité indexable reçoit une requête. Par exemple, voici comment enregistrer la requête lors de la méthode onCreate() de votre activité :

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

Le constructeur SearchRecentSuggestionsProvider nécessite la même autorité et le même mode de base de données que ceux déclarés par votre fournisseur de contenu.

La méthode saveRecentQuery() prend la chaîne de requête de recherche comme premier paramètre et, éventuellement, une deuxième chaîne à inclure comme deuxième ligne de la suggestion ou comme valeur nulle. Le deuxième paramètre n'est utilisé que si vous activez le mode à deux lignes pour les suggestions de recherche avec DATABASE_MODE_2LINES. Si vous activez le mode à deux lignes, le texte de la requête correspond à la deuxième ligne lorsque le système recherche des suggestions correspondantes.

Effacer les données de suggestion

Pour protéger la confidentialité de l'utilisateur, fournissez toujours un moyen à l'utilisateur d'effacer les suggestions de requêtes récentes. Pour effacer l'historique des requêtes, appelez clearHistory(). Exemple :

Kotlin

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

Java

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

Exécutez cette opération à partir d'un élément de menu, d'un élément de préférence ou d'un bouton "Effacer l'historique des recherches". Fournissez une boîte de dialogue de confirmation pour vérifier que l'utilisateur souhaite supprimer son historique de recherche.