Cómo agregar sugerencias de búsqueda personalizadas

Cuando usas el diálogo o el widget de búsqueda de Android, puedes proporcionar sugerencias de búsqueda personalizadas que se crean a partir de los datos de tu app. Por ejemplo, si la app es un diccionario, puedes sugerir palabras del diccionario que coincidan con el texto ingresado en el campo de búsqueda antes de que el usuario termine de ingresar su consulta. Estas sugerencias son valiosas porque pueden predecir con eficacia lo que el usuario quiere y proporcionar acceso instantáneo a él. En la Figura 1, se muestra un ejemplo de un diálogo de búsqueda con sugerencias personalizadas.

Una vez que proporciones sugerencias personalizadas, también podrás hacer que estén disponibles en el cuadro de búsqueda rápida de todo el sistema, lo que brinda acceso al contenido desde fuera de la app.

Antes de agregar sugerencias personalizadas, implementa el diálogo de búsqueda de Android o un widget de búsqueda para las búsquedas en tu app. Consulta Cómo crear una interfaz de búsqueda y Proveedores de contenido.

Conceptos básicos

Figura 1: Captura de pantalla de un diálogo de búsqueda con sugerencias de búsqueda personalizadas.

Cuando el usuario selecciona una sugerencia personalizada, el sistema envía un Intent a la actividad de búsqueda. A diferencia de una búsqueda normal que envía un intent con la acción ACTION_SEARCH, puedes definir tus sugerencias personalizadas para usar ACTION_VIEW (o cualquier otra acción de intent) y también incluir datos relevantes para la sugerencia seleccionada. En el ejemplo del diccionario, cuando el usuario selecciona una sugerencia, la app puede abrir inmediatamente la definición de esa palabra en lugar de buscar coincidencias en el diccionario.

Para proporcionar sugerencias personalizadas, sigue estos pasos:

  • Implementa una actividad básica de búsqueda, como se describe en Cómo crear una interfaz de búsqueda.
  • Modifica la configuración de búsqueda con información sobre el proveedor de contenido que proporciona sugerencias personalizadas.
  • Crea una tabla, por ejemplo, en una SQLiteDatabase, para las sugerencias y formatea la tabla con las columnas obligatorias.
  • Crea un proveedor de contenido que tenga acceso a tu tabla de sugerencias y declara al proveedor en tu manifiesto.
  • Declara el tipo de Intent que se enviará cuando el usuario seleccione una sugerencia, lo que incluye una acción personalizada y datos personalizados.

Así como el sistema Android muestra el diálogo de búsqueda, también muestra tus sugerencias de búsqueda. Necesitas un proveedor de contenido desde el cual el sistema pueda recuperar tus sugerencias. Consulta Proveedores de contenido para obtener información sobre cómo crear un proveedor de contenido.

Si el sistema identifica que tu actividad se puede buscar y proporciona sugerencias de búsqueda, se lleva a cabo el siguiente procedimiento cuando el usuario ingresa una consulta:

  1. El sistema toma el texto de la búsqueda (es decir, lo que se ingresó hasta el momento) y realiza una consulta al proveedor de contenido que administra las sugerencias.
  2. Tu proveedor de contenido muestra un Cursor que apunta a todas las sugerencias relevantes para el texto de la búsqueda.
  3. El sistema muestra la lista de sugerencias proporcionadas por Cursor.

Una vez que se muestran las sugerencias personalizadas, puede ocurrir lo siguiente:

  • Si el usuario ingresa otra letra o cambia la consulta de alguna manera, los pasos anteriores se repiten y la lista de sugerencias se actualiza en consecuencia.
  • Si el usuario ejecuta la búsqueda, se ignoran las sugerencias y se entrega la búsqueda a la actividad de búsqueda con el intent ACTION_SEARCH normal.
  • Si el usuario selecciona una sugerencia, se envía un intent a tu actividad de búsqueda, que contiene una acción personalizada y datos personalizados para que tu app pueda abrir el contenido sugerido.

Modifica la configuración de búsqueda

Para admitir sugerencias personalizadas, agrega el atributo android:searchSuggestAuthority al elemento <searchable> en el archivo de configuración de búsqueda, como se muestra en el siguiente ejemplo:

<?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.MyCustomSuggestionProvider">
</searchable>

Es posible que necesites atributos adicionales, según el tipo de intent que adjuntes a cada sugerencia y el modo en que quieras formatear las consultas para tu proveedor de contenido. Los otros atributos opcionales se analizan en las siguientes secciones.

Cómo crear un proveedor de contenido

Si quieres crear un proveedor de contenido para sugerencias personalizadas, primero consulta Proveedores de contenido a fin de aprender a crear un proveedor de contenido. Un proveedor de contenido para sugerencias personalizadas es similar a cualquier otro proveedor de contenido. Sin embargo, para cada sugerencia que proporciones, la fila respectiva en Cursor debe incluir columnas específicas que el sistema comprende y usa para formatear las sugerencias.

Cuando el usuario ingresa texto en el diálogo o el widget de búsqueda, el sistema consulta a tu proveedor de contenido para obtener sugerencias llamando a query() cada vez que se ingresa una letra. En la implementación de query(), el proveedor de contenido debe buscar los datos de sugerencias y mostrar un Cursor que apunte a las filas que considere buenas sugerencias.

Los detalles sobre la creación de un proveedor de contenido para sugerencias personalizadas se analizan en las siguientes dos secciones:

Cómo controlar la consulta de sugerencias
Cómo envía el sistema solicitudes a tu proveedor de contenido y cómo procesarlas.
Cómo crear una tabla de sugerencias
Cómo definir las columnas que el sistema espera en el Cursor que se muestra con cada consulta.

Cómo controlar la consulta de sugerencias

Cuando el sistema solicita sugerencias de tu proveedor de contenido, llama al método query() de tu proveedor de contenido. Implementa este método para buscar los datos de tus sugerencias y mostrar un Cursor que apunte a las sugerencias que consideres relevantes.

A continuación, se incluye un resumen de los parámetros que el sistema pasa a tu método query(), ordenados en los siguientes elementos:

  1. uri

    Siempre es un contenido Uri, con el siguiente formato:

    content://your.authority/optional.suggest.path/SUGGEST_URI_PATH_QUERY
    

    El comportamiento predeterminado es que el sistema pase este URI y le agregue el texto de la consulta:

    content://your.authority/optional.suggest.path/SUGGEST_URI_PATH_QUERY/puppies
    

    El texto de la consulta al final está codificado mediante reglas de codificación de URI, por lo que es posible que debas decodificarlo antes de realizar una búsqueda.

    La parte optional.suggest.path solo se incluye en el URI si configuras esa ruta de acceso en el archivo de configuración de búsqueda con el atributo android:searchSuggestPath. Solo es necesaria si usas el mismo proveedor de contenido para varias actividades de búsqueda. Si este es el caso, desambigua la fuente de la consulta de sugerencias.

  2. projection
    Siempre es nulo.
  3. selection
    Es el valor proporcionado en el atributo android:searchSuggestSelection del archivo de configuración de búsqueda, o nulo si no declaras el atributo android:searchSuggestSelection. En la siguiente sección, se explica este tema con más detalle.
  4. selectionArgs
    Contiene la búsqueda como el primer y único elemento del array si declaras el atributo android:searchSuggestSelection en tu configuración de búsqueda. Si no declaras android:searchSuggestSelection, este parámetro es nulo. Esto se analiza en más detalle en la siguiente sección.
  5. sortOrder
    Siempre es nulo.

El sistema puede enviar el texto de la búsqueda de dos maneras. La forma predeterminada es que el texto de la consulta se incluya como la última ruta del URI de contenido que se pasa en el parámetro uri. Sin embargo, si incluyes un valor de selección en el atributo android:searchSuggestSelection de la configuración de búsqueda, el texto de la consulta se pasará como el primer elemento del array de cadenas selectionArgs. Estas dos opciones se describen a continuación.

Obtén la consulta en el URI

De forma predeterminada, la consulta se agrega como el último segmento del parámetro uri: un objeto Uri. Para recuperar el texto de la consulta en este caso, usa getLastPathSegment(), como se muestra en el siguiente ejemplo:

Kotlin

val query: String = uri.lastPathSegment.toLowerCase()

Java

String query = uri.getLastPathSegment().toLowerCase();

Esto muestra el último segmento de Uri, que es el texto de consulta que ingresa el usuario.

Obtén la consulta en los argumentos de selección

En lugar de usar el URI, podría tener más sentido que tu método query() reciba todo lo que necesita para realizar la búsqueda, y es posible que desees que los parámetros selection y selectionArgs lleven los valores adecuados. En este caso, agrega el atributo android:searchSuggestSelection a la configuración de búsqueda con tu string de selección de SQLite. En la string de selección, incluye un signo de interrogación (?) como marcador de posición para la búsqueda real. El sistema llama a query() con la string de selección como el parámetro selection y la búsqueda como el primer elemento del array selectionArgs.

Por ejemplo, así es como puedes formar el atributo android:searchSuggestSelection para crear una instrucción de búsqueda en el texto completo:

<?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.MyCustomSuggestionProvider"
    android:searchSuggestIntentAction="android.intent.action.VIEW"
    android:searchSuggestSelection="word MATCH ?">
</searchable>

Con esta configuración, el método query() entrega el parámetro selection como "word MATCH ?" y el parámetro selectionArgs como la búsqueda. Cuando pasas estos elementos a un método query() de SQLite, como sus respectivos argumentos, se sintetizan juntos, es decir, el signo de interrogación se reemplaza por el texto de la consulta. Si recibes consultas de sugerencias de esta manera y necesitas agregar comodines al texto de la consulta, agrégalos o agrégalos como prefijos al parámetro selectionArgs, ya que este valor se encierra entre comillas y se inserta en lugar del signo de interrogación.

Otro atributo del ejemplo anterior es android:searchSuggestIntentAction, que define la acción de intent que se envía con cada intent cuando el usuario selecciona una sugerencia. Este tema se analiza más a fondo en la sección Cómo declarar un intent para sugerencias.

Cómo crear una tabla de sugerencias

Cuando muestras sugerencias al sistema con un Cursor, el sistema espera columnas específicas en cada fila. Independientemente de si almacenas los datos de sugerencias en una base de datos SQLite en el dispositivo, una base de datos en un servidor web o algún otro formato en el dispositivo o la Web, formatea las sugerencias como filas en una tabla y preséntalas con un Cursor.

El sistema comprende varias columnas, pero solo se requieren dos de ellas:

_ID
Un ID de fila de número entero único para cada sugerencia. El sistema requiere esto para presentar sugerencias en un ListView.
SUGGEST_COLUMN_TEXT_1
La string que se presenta como una sugerencia.

Las siguientes columnas son opcionales. La mayoría se analiza con más detalle en las siguientes secciones.

SUGGEST_COLUMN_TEXT_2
Una string. Si tu Cursor incluye esta columna, todas las sugerencias se proporcionan en un formato de dos líneas. La string en esta columna se muestra como una segunda línea de texto más pequeña debajo del texto de sugerencia principal. Puede ser nula o vacía para indicar que no hay texto secundario.
SUGGEST_COLUMN_ICON_1
Una string de URI de elemento de diseño de recurso, contenido o archivo. Si tu Cursor incluye esta columna, todas las sugerencias se proporcionan en un formato de ícono más texto con el ícono de elemento de diseño en el lado izquierdo. Puede ser nulo o cero para indicar que no hay ícono en esta fila.
SUGGEST_COLUMN_ICON_2
Una string de URI de elemento de diseño de recurso, contenido o archivo. Si tu Cursor incluye esta columna, todas las sugerencias se proporcionan en un formato de ícono más texto con el ícono en el lado derecho. Puede ser nulo o cero para indicar que no hay ícono en esta fila.
SUGGEST_COLUMN_INTENT_ACTION
Una string de acción de intent. Si esta columna existe y contiene un valor en la fila dada, la acción definida aquí se usa cuando se forma el intent de la sugerencia. Si no se proporciona el elemento, la acción se toma del campo android:searchSuggestIntentAction de la configuración de búsqueda. Si la acción es la misma para todas las sugerencias, es más eficiente especificar la acción mediante android:searchSuggestIntentAction y omitir esta columna.
SUGGEST_COLUMN_INTENT_DATA
Una string de URI de datos. Si esta columna existe y contiene un valor en la fila dada, estos datos se usan cuando se forma el intent de la sugerencia. Si no se proporciona el elemento, los datos se toman del campo android:searchSuggestIntentData en la configuración de búsqueda. Si no se proporciona ninguna de las fuentes, el campo de datos del intent es nulo. Si tus datos son iguales para todas las sugerencias o se pueden describir con una parte constante y un ID específico, es más eficiente especificarlos con android:searchSuggestIntentData y omitir esta columna.
SUGGEST_COLUMN_INTENT_DATA_ID
Una string de ruta de URI. Si esta columna existe y contiene un valor en la fila dada, "/" y este valor se agregan al campo de datos en el intent. Usa esta opción solo si el campo de datos especificado por el atributo android:searchSuggestIntentData en la configuración de búsqueda ya está establecido en una string base adecuada.
SUGGEST_COLUMN_INTENT_EXTRA_DATA
Datos arbitrarios. Si esta columna existe y contiene un valor en una fila dada, estos son los datos adicionales que se usaron para formar el intent de la sugerencia. Si no se proporciona, el campo de datos adicionales del intent es nulo. Esta columna permite que las sugerencias proporcionen datos adicionales que se incluyen como un valor adicional en la clave EXTRA_DATA_KEY del intent.
SUGGEST_COLUMN_QUERY
Si esta columna existe y este elemento existe en la fila dada, estos son los datos que se usan para formar la consulta de la sugerencia, incluidos como un valor adicional en la clave QUERY del intent. Es obligatoria si la acción de la sugerencia es ACTION_SEARCH, pero es opcional en los demás casos.
SUGGEST_COLUMN_SHORTCUT_ID
Solo se utiliza cuando se proporcionan sugerencias para el cuadro de búsqueda rápida. Esta columna indica si una sugerencia de búsqueda debe almacenarse como un acceso directo y si se debe validar. Por lo general, los accesos directos se forman cuando el usuario presiona una sugerencia del cuadro de búsqueda rápida. Si falta, el resultado se almacena como un acceso directo y nunca se actualiza. Si se configura en SUGGEST_NEVER_MAKE_SHORTCUT, el resultado no se almacena como un acceso directo. De lo contrario, el ID de acceso directo se usa para comprobar si hay una sugerencia actualizada mediante SUGGEST_URI_PATH_SHORTCUT.
SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING
Solo se utiliza cuando se proporcionan sugerencias para el cuadro de búsqueda rápida. En esta columna, se especifica que se debe mostrar un ícono giratorio en lugar de un ícono de SUGGEST_COLUMN_ICON_2 mientras el acceso directo de esta sugerencia se actualiza en el cuadro de búsqueda rápida.

La mayoría de estas columnas se analizan con más detalle en las siguientes secciones.

Cómo declarar un intent para recibir sugerencias

Cuando el usuario selecciona una sugerencia de la lista que aparece debajo del diálogo o widget de búsqueda, el sistema envía un Intent personalizado a la actividad de búsqueda. Debes definir la acción y los datos para el intent.

Cómo declarar la acción del intent

La acción de intent más común para una sugerencia personalizada es ACTION_VIEW, que resulta apropiada cuando deseas abrir algo, como la definición de una palabra, la información de contacto de una persona o una página web. Sin embargo, la acción de intent puede ser cualquier otra acción y puede ser diferente para cada sugerencia.

En función de si deseas que todas las sugerencias usen la misma acción de intent, puedes definir la acción de dos maneras:

  • Usa el atributo android:searchSuggestIntentAction del archivo de configuración de búsqueda a fin de definir la acción para todas las sugerencias, como se muestra en el siguiente ejemplo:
    <?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.MyCustomSuggestionProvider"
        android:searchSuggestIntentAction="android.intent.action.VIEW" >
    </searchable>
    
  • Usa la columna SUGGEST_COLUMN_INTENT_ACTION para definir la acción de las sugerencias individuales. Para ello, agrega la columna SUGGEST_COLUMN_INTENT_ACTION a tu tabla de sugerencias y, para cada sugerencia, coloca en ella la acción que deseas usar, como "android.intent.action.VIEW".

También puedes combinar estas dos técnicas. Por ejemplo, puedes incluir el atributo android:searchSuggestIntentAction con una acción que se utilizará con todas las sugerencias de forma predeterminada y, luego, anular esta acción para algunas sugerencias declarando una acción diferente en la columna SUGGEST_COLUMN_INTENT_ACTION. Si no incluyes un valor en la columna SUGGEST_COLUMN_INTENT_ACTION, se usará el intent proporcionado en el atributo android:searchSuggestIntentAction.

Cómo declarar datos del intent

Cuando el usuario selecciona una sugerencia, la actividad de búsqueda recibe el intent con la acción que definiste (como se explicó en la sección anterior), pero el intent también debe llevar datos para tu actividad a fin de identificar qué sugerencia se seleccionó. Específicamente, los datos deben ser únicos para cada sugerencia, como el ID de fila de la sugerencia en tu tabla de SQLite. Cuando se recibe el intent, puedes recuperar los datos adjuntos con getData() o getDataString().

Puedes definir los datos incluidos con el intent de dos maneras:

  • Define los datos para cada sugerencia dentro de la columna SUGGEST_COLUMN_INTENT_DATA de la tabla de sugerencias.

    Proporciona toda la información de datos necesaria para cada intent en la tabla de sugerencias. Para ello, incluye la columna SUGGEST_COLUMN_INTENT_DATA y, luego, propágala con datos únicos para cada fila. Los datos de esta columna se adjuntan al intent exactamente como lo defines en esta columna. Luego, puedes recuperarlo con getData() o getDataString().

  • Fragmenta un URI de datos en dos partes: la parte común a todas las sugerencias y la parte única de cada sugerencia. Coloca estas partes en el atributo android:searchSuggestintentData de la configuración de búsqueda y en la columna SUGGEST_COLUMN_INTENT_DATA_ID de la tabla de sugerencias, respectivamente.

    En el siguiente ejemplo, se muestra cómo declarar la parte del URI que es común a todas las sugerencias del atributo android:searchSuggestIntentData de tu configuración de búsqueda:

      <?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.MyCustomSuggestionProvider"
          android:searchSuggestIntentAction="android.intent.action.VIEW"
          android:searchSuggestIntentData="content://com.example/datatable" >
      </searchable>
      

    Incluye la ruta final para cada sugerencia (la parte única) en la columna SUGGEST_COLUMN_INTENT_DATA_ID de la tabla de sugerencias. Cuando el usuario selecciona una sugerencia, el sistema toma la string de android:searchSuggestIntentData, agrega una barra (/) y, luego, agrega el valor correspondiente de la columna SUGGEST_COLUMN_INTENT_DATA_ID para formar un URI de contenido completo. Luego, puedes recuperar el objeto Uri con getData().

Agrega más datos

Si necesitas expresar más información con tu intent, puedes agregar otra columna de tabla, como SUGGEST_COLUMN_INTENT_EXTRA_DATA, que puede almacenar información adicional sobre la sugerencia. Los datos guardados en esta columna se colocan en el EXTRA_DATA_KEY del paquete adicional del intent.

Cómo controlar el intent

Después de proporcionar sugerencias de búsqueda personalizadas con intents personalizados, necesitas que la actividad de búsqueda maneje estos intents cuando el usuario seleccione una sugerencia. Esto se suma a controlar el intent ACTION_SEARCH, algo que la actividad de búsqueda ya hace. Este es un ejemplo de cómo puedes controlar los intents durante la devolución de llamada a onCreate() de tu actividad:

Kotlin

when(intent.action) {
    Intent.ACTION_SEARCH -> {
        // Handle the normal search query case.
        intent.getStringExtra(SearchManager.QUERY)?.also { query ->
            doSearch(query)
        }
    }
    Intent.ACTION_VIEW -> {
        // Handle a suggestions click, because the suggestions all use ACTION_VIEW.
        showResult(intent.data)
    }
}

Java

Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
    // Handle the normal search query case.
    String query = intent.getStringExtra(SearchManager.QUERY);
    doSearch(query);
} else if (Intent.ACTION_VIEW.equals(intent.getAction())) {
    // Handle a suggestions click, because the suggestions all use ACTION_VIEW.
    Uri data = intent.getData();
    showResult(data);
}

En este ejemplo, la acción de intent es ACTION_VIEW, y los datos llevan un URI completo que apunta al elemento sugerido, como sintetizan la cadena android:searchSuggestIntentData y la columna SUGGEST_COLUMN_INTENT_DATA_ID. Luego, el URI se pasa al método showResult() local que consulta al proveedor de contenido por el elemento que especifica el URI.

Vuelve a escribir el texto de la consulta

De forma predeterminada, si el usuario navega por la lista de sugerencias con controles de dirección, como una bola de seguimiento o un pad direccional, el texto de consulta no se actualiza. Sin embargo, puedes reescribir de forma temporal el texto de consulta del usuario como aparece en el cuadro de texto con una consulta que coincida con la sugerencia enfocada. Esto permite que el usuario vea la consulta que se sugiere, puede seleccionar el cuadro de búsqueda y editar la consulta antes de enviarla como búsqueda.

Puedes reescribir el texto de la consulta de las siguientes maneras:

  • Agrega el atributo android:searchMode a la configuración de búsqueda con el valor "queryRewriteFromText". En este caso, el contenido de la columna SUGGEST_COLUMN_TEXT_1 de la sugerencia se usa para reescribir el texto de la consulta.
  • Agrega el atributo android:searchMode a la configuración de búsqueda con el valor "queryRewriteFromData". En este caso, el contenido de la columna SUGGEST_COLUMN_INTENT_DATA de la sugerencia se usa para reescribir el texto de la consulta. Usa este método solo con URIs o cualquier otro formato de datos que sea visible para el usuario, como las URLs HTTP. No uses esquemas de URI internos para reescribir la consulta de esta forma.
  • Proporciona una cadena de texto de consulta única en la columna SUGGEST_COLUMN_QUERY de la tabla de sugerencias. Si esta columna está presente y contiene un valor para la sugerencia actual, se usa para reescribir el texto de la consulta y anular cualquiera de las implementaciones anteriores.

Exponer sugerencias de búsqueda al cuadro de búsqueda rápida

Una vez que configuras tu app para que proporcione sugerencias de búsqueda personalizadas, ponerlas a disposición del cuadro de búsqueda rápida de acceso global es tan fácil como modificar la configuración de búsqueda para incluir android:includeInGlobalSearch con el valor "true".

La única situación en la que se necesita trabajo adicional es cuando tu proveedor de contenido exige un permiso de lectura. En ese caso, debes agregar un elemento <path-permission> para que el proveedor otorgue acceso de lectura del cuadro de búsqueda rápida a tu proveedor de contenido, como se muestra en el siguiente ejemplo:

<provider android:name="MySuggestionProvider"
          android:authorities="com.example.MyCustomSuggestionProvider"
          android:readPermission="com.example.provider.READ_MY_DATA"
          android:writePermission="com.example.provider.WRITE_MY_DATA">
  <path-permission android:pathPrefix="/search_suggest_query"
                   android:readPermission="android.permission.GLOBAL_SEARCH" />
</provider>

En este ejemplo, el proveedor restringe el acceso de lectura y escritura al contenido. El elemento <path-permission> modifica la restricción otorgando acceso de lectura al contenido dentro del prefijo de ruta de acceso "/search_suggest_query" cuando existe el permiso "android.permission.GLOBAL_SEARCH". Esto otorga acceso al cuadro de búsqueda rápida para que pueda consultar al proveedor de contenido en busca de sugerencias.

Si tu proveedor de contenido no aplica permisos de lectura, el cuadro de búsqueda rápida lo lee de forma predeterminada.

Habilita las sugerencias en un dispositivo

De forma predeterminada, las apps no están habilitadas para proporcionar sugerencias en el cuadro de búsqueda rápida, incluso si están configuradas para hacerlo. El usuario elige si desea incluir sugerencias de tu app en el cuadro de búsqueda rápida. Para ello, abre Elementos de búsqueda (ubicado en Configuración > Búsqueda) y habilita tu app como un elemento de búsqueda.

Cada app que está disponible para el cuadro de búsqueda rápida tiene una entrada en la página de configuración de Elementos de búsqueda. La entrada incluye el nombre de la app y una descripción breve del contenido que se puede buscar desde la app y que está disponible para las sugerencias en el cuadro de búsqueda rápida. Para definir el texto descriptivo de la app que se puede buscar, agrega el atributo android:searchSettingsDescription a la configuración de búsqueda, como se muestra en el siguiente ejemplo:

<?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.MyCustomSuggestionProvider"
    android:searchSuggestIntentAction="android.intent.action.VIEW"
    android:includeInGlobalSearch="true"
    android:searchSettingsDescription="@string/search_description" >
</searchable>

Haz que la cadena de android:searchSettingsDescription sea lo más concisa posible y especifica el contenido que se puede buscar. Por ejemplo, "Artistas, álbumes y pistas" para una app de música, o "Notas guardadas" para una app de bloc de notas. Proporcionar esta descripción es importante para que el usuario sepa qué tipo de sugerencias se proporcionan. Incluye siempre este atributo cuando android:includeInGlobalSearch sea verdadero.

Como el usuario debe visitar el menú de configuración para habilitar las sugerencias de búsqueda para la app, si la búsqueda es un aspecto importante de la app, considera cómo transmitirla a los usuarios. Por ejemplo, podrías proporcionar una nota la primera vez que un usuario inicie la app en la que se explique cómo habilitar las sugerencias de búsqueda para el cuadro de búsqueda rápida.

Administrar combinaciones de teclas para sugerencias del cuadro de búsqueda rápida

Las sugerencias que el usuario selecciona del cuadro de búsqueda rápida se pueden convertir automáticamente en accesos directos. Estas son sugerencias que el sistema copia de tu proveedor de contenido para que pueda acceder rápidamente a la sugerencia sin necesidad de volver a consultar al proveedor de contenido.

De forma predeterminada, esta opción está habilitada para todas las sugerencias que recupera el cuadro de búsqueda rápida, pero si los datos de tus sugerencias cambian con el tiempo, puedes solicitar que se actualicen los accesos directos. Por ejemplo, si tus sugerencias hacen referencia a datos dinámicos, como el estado de presencia de un contacto, solicita que se actualicen las combinaciones de sugerencias cuando se muestren al usuario. Para ello, incluye el SUGGEST_COLUMN_SHORTCUT_ID en tu tabla de sugerencias. Puedes usar esta columna para configurar el comportamiento de los atajos para cada sugerencia de una de las siguientes maneras:

  • Haz que el cuadro de búsqueda rápida vuelva a consultar tu proveedor de contenido para obtener una versión nueva del acceso directo de sugerencia.

    Proporciona un valor en la columna SUGGEST_COLUMN_SHORTCUT_ID para que la sugerencia se vuelva a consultar para obtener una versión nueva cada vez que se muestre el acceso directo. El acceso directo se muestra rápidamente con los datos que estén disponibles más recientemente hasta que se muestre la consulta de actualización. En ese momento, la sugerencia se actualiza con la información nueva. La consulta de actualización se envía a tu proveedor de contenido con una ruta de URI de SUGGEST_URI_PATH_SHORTCUT, en lugar de SUGGEST_URI_PATH_QUERY.

    Haz que el Cursor que muestres contenga una sugerencia usando las mismas columnas que la sugerencia original o que esté vacío, lo que indica que el acceso directo ya no es válido; en ese caso, la sugerencia desaparece y se quita el acceso directo.

    Si una sugerencia hace referencia a datos que pueden tardar más en actualizarse, como una actualización basada en la red, también puedes agregar la columna SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING a tu tabla de sugerencias con el valor verdadero para mostrar un ícono giratorio de progreso para el ícono de la derecha hasta que se complete la actualización. Cualquier valor que no sea verdadero no muestra el ícono giratorio de progreso.

  • Evita que la sugerencia se copie en un acceso directo.

    Proporciona un valor de SUGGEST_NEVER_MAKE_SHORTCUT en la columna SUGGEST_COLUMN_SHORTCUT_ID. En este caso, la sugerencia nunca se copia en un acceso directo. Esto solo es necesario si no quieres que aparezca la sugerencia que se copió anteriormente. Si proporcionas un valor normal para la columna, el acceso directo de sugerencias solo aparecerá hasta que se muestre la consulta de actualización.

  • Permite que se aplique el comportamiento predeterminado de los accesos directos.

    Deja el SUGGEST_COLUMN_SHORTCUT_ID vacío para cada sugerencia que no cambie y que se pueda guardar como un acceso directo.

Si ninguna de tus sugerencias cambia, no necesitas la columna SUGGEST_COLUMN_SHORTCUT_ID.

Acerca de la clasificación de sugerencias del cuadro de búsqueda rápida

Una vez que las sugerencias de búsqueda de la app están disponibles en el cuadro de búsqueda rápida, la clasificación del cuadro determina cómo se muestran las sugerencias al usuario para una consulta en particular. Esto puede depender de cuántas otras apps tengan resultados para esa consulta y con qué frecuencia el usuario seleccione tus resultados en comparación con las de otras apps. No se garantiza cómo se clasifican tus sugerencias ni si las sugerencias de tu app se muestran para una consulta determinada. En general, proporcionar resultados de calidad aumenta la probabilidad de que las sugerencias de la app se proporcionen en una posición destacada, y es más probable que las apps que proporcionan sugerencias de baja calidad tengan una clasificación inferior o no se muestren.