Ajouter des suggestions de recherche personnalisées

Essayer Compose
Jetpack Compose est le kit d'outils d'UI 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 ou le widget de recherche Android. Par exemple, si un utilisateur recherche "chiots", la requête apparaît comme suggestion lorsqu'il saisit à nouveau la même requête. 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 en savoir plus, 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é pouvant faire l'objet d'une recherche reçoit une intention ACTION_SEARCH avec la suggestion comme requête de recherche que votre activité pouvant faire l'objet d'une recherche gère déjà.

Pour fournir des suggestions de requêtes récentes, vous devez :

  • Implémentez une activité pouvant faire l'objet d'une recherche.
  • Créez un fournisseur de contenu qui étend SearchRecentSuggestionsProvider et déclarez-le dans le fichier manifeste de votre application.
  • Modifiez la configuration de recherche avec des informations sur le fournisseur de contenu qui fournit des suggestions de recherche.
  • Enregistrez les requêtes auprès de votre fournisseur de contenu chaque fois qu'une recherche est effectué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 consultable et fournit des suggestions de recherche, les événements suivants se produisent 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 Cursor.

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

  • Si l'utilisateur saisit 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 envoyée à votre activité pouvant faire l'objet d'une recherche à l'aide de l'intention ACTION_SEARCH normale.
  • Si l'utilisateur sélectionne une suggestion, un intent ACTION_SEARCH est envoyé à votre activité pouvant faire l'objet d'une recherche, en utilisant le texte suggéré comme requête.

La classe SearchRecentSuggestionsProvider que vous étendez pour votre fournisseur de contenu effectue automatiquement les étapes précédentes. Il y a donc 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 il est recommandé d'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 base de données doit inclure DATABASE_MODE_QUERIES et peut éventuellement inclure DATABASE_MODE_2LINES, ce qui ajoute une colonne au tableau des suggestions afin que vous puissiez fournir une deuxième ligne de texte pour 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 de recherche. 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 attributs android:searchSuggestAuthority et android:searchSuggestSelection à l'élément <searchable> de votre fichier de configuration pouvant faire l'objet d'une recherche. 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 point d'interrogation unique précédé d'un espace : " ?". Il s'agit d'un espace réservé pour l'argument de sélection SQLite. Il est automatiquement remplacé par le texte de la requête saisie par l'utilisateur.

Enregistrer des requêtes

Pour remplir votre collection de requêtes récentes, ajoutez chaque requête reçue par votre activité pouvant faire l'objet d'une recherche à votre SearchRecentSuggestionsProvider. Pour ce faire, créez une instance de SearchRecentSuggestions et appelez saveRecentQuery() chaque fois que votre activité de recherche reçoit une requête. Par exemple, voici comment enregistrer la requête pendant 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 null. 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, prévoyez toujours un moyen pour lui 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 action à partir de l'élément de menu, de préférence ou du bouton "Effacer l'historique des recherches" de votre choix. Affichez une boîte de dialogue de confirmation pour vérifier que l'utilisateur souhaite supprimer son historique des recherches.