Muestra resultados de búsqueda explorables

Todas las apps deben admitir búsquedas por voz. En esta página, se describe cómo mejorar aún más la experiencia de búsqueda admitiendo el inicio de búsquedas sin voz y mostrando una lista de resultados de búsqueda para que los usuarios puedan elegir otro resultado. Por ejemplo, si el resultado sugerido no es el más pertinente.

Tu app de música puede proporcionar resultados de búsqueda contextuales en Android Auto y el SO Android Automotive (AAOS). Estos resultados aparecen cuando un usuario inicia una búsqueda o ve los resultados de la búsqueda más reciente.

Para habilitar y proporcionar estos resultados de la búsqueda, haz lo siguiente:

  • Declara la compatibilidad con la búsqueda en el método onGetRoot de tu servicio.

  • Anula el método onSearch en tu servicio de navegador multimedia para controlar los términos de búsqueda del usuario.

  • Organiza los resultados de la Búsqueda con elementos de título para mejorar la capacidad de exploración.

Tu app puede proporcionar resultados de la búsqueda contextuales que aparecen cuando se inicia una búsqueda. Android Auto y AAOS muestran estos resultados a través de interfaces de búsqueda o de condiciones que cambian a partir de búsquedas realizadas con anterioridad. Para obtener más información, consulta Cómo admitir acciones de voz.

Vista de reproducción con la opción **Resultados de la búsqueda** para ver elementos multimedia relacionados con la búsqueda por voz del usuario

Figura 1: Vista de reproducción con la opción Resultados de la búsqueda para ver elementos multimedia relacionados con la búsqueda por voz del usuario

Para indicar que tu app admite la visualización de resultados de la búsqueda, incluye la clave constante BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED en el paquete de extras que devuelve el método onGetRoot de tu servicio, que se asigna al valor booleano true.

Kotlin

import androidx.media.utils.MediaConstants

@Nullable
override fun onGetRoot(
    @NonNull clientPackageName: String,
    clientUid: Int,
    @Nullable rootHints: Bundle
): BrowserRoot {
    val extras = Bundle()
    extras.putBoolean(
        MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED, true)
    return BrowserRoot(ROOT_ID, extras)
}

Java

import androidx.media.utils.MediaConstants;

@Nullable
@Override
public BrowserRoot onGetRoot(
    @NonNull String clientPackageName,
    int clientUid,
    @Nullable Bundle rootHints) {
    Bundle extras = new Bundle();
    extras.putBoolean(
        MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED, true);
    return new BrowserRoot(ROOT_ID, extras);
}

Para proporcionar resultados de la búsqueda, anula el método onSearch en el servicio de navegador multimedia. Android Auto y AAOS reenvían los términos de búsqueda del usuario a este método cuando el usuario invoca una interfaz de búsqueda o la opción Resultados de la búsqueda.

Para que los resultados de la búsqueda sean más explorables, puedes usar elementos de título. Por ejemplo, si tu app reproduce música, puedes organizar los resultados de la búsqueda por álbum, artista y canción. En este fragmento de código, se muestra una implementación del método onSearch:

Kotlin

fun onSearch(query: String, extras: Bundle) {
  // Detach from results to unblock the caller (if a search is expensive).
  result.detach()
  object:AsyncTask() {
    internal var searchResponse:ArrayList
    internal var succeeded = false
    protected fun doInBackground(vararg params:Void):Void {
      searchResponse = ArrayList()
      if (doSearch(query, extras, searchResponse))
      {
        succeeded = true
      }
      return null
    }
    protected fun onPostExecute(param:Void) {
      if (succeeded)
      {
        // Sending an empty List informs the caller that there were no results.
        result.sendResult(searchResponse)
      }
      else
      {
        // This invokes onError() on the search callback.
        result.sendResult(null)
      }
      return null
    }
  }.execute()
}
// Populates resultsToFill with search results. Returns true on success or false on error.
private fun doSearch(
    query: String,
    extras: Bundle,
    resultsToFill: ArrayList
): Boolean {
  // Implement this method.
}

Java

@Override
public void onSearch(final String query, final Bundle extras,
                        Result<List<MediaItem>> result) {

  // Detach from results to unblock the caller (if a search is expensive).
  result.detach();

  new AsyncTask<Void, Void, Void>() {
    List>MediaItem> searchResponse;
    boolean succeeded = false;
    @Override
    protected Void doInBackground(Void... params) {
      searchResponse = new ArrayList&lt;MediaItem>();
      if (doSearch(query, extras, searchResponse)) {
        succeeded = true;
      }
      return null;
    }

    @Override
    protected void onPostExecute(Void param) {
      if (succeeded) {
       // Sending an empty List informs the caller that there were no results.
       result.sendResult(searchResponse);
      } else {
        // This invokes onError() on the search callback.
        result.sendResult(null);
      }
    }
  }.execute()
}

/** Populates resultsToFill with search results. Returns true on success or false on error. */
private boolean doSearch(String query, Bundle extras, ArrayList&lt;MediaItem> resultsToFill) {
    // Implement this method.
}