顯示可瀏覽的搜尋結果

所有應用程式都必須支援語音搜尋。本頁面說明如何支援啟動無語音搜尋,以及顯示搜尋結果清單,讓使用者可以選擇其他結果,進一步提升搜尋體驗。舉例來說,如果建議結果並非最相關的內容。

媒體應用程式可在 Android Auto 和 Android Automotive OS (AAOS) 中提供情境搜尋結果。使用者啟動搜尋查詢或查看最近的搜尋結果時,就會看到這些結果。

如要啟用及提供這些搜尋結果,請按照下列步驟操作:

  • 在服務的 onGetRoot 方法中宣告搜尋支援。

  • 覆寫媒體瀏覽器服務中的 onSearch 方法,處理使用者搜尋字詞。

  • 使用標題項目整理搜尋結果,讓內容更容易瀏覽。

您的應用程式可以在使用者啟動搜尋查詢時,顯示相關內容搜尋結果。Android Auto 和 AAOS 會透過搜尋查詢介面或工作階段中較早進行查詢的預設用途,顯示這些結果。詳情請參閱「支援語音指令」。

播放檢視畫面內含「搜尋結果」選項,用於查看與使用者的語音搜尋相關的媒體項目

圖 1. 播放檢視畫面內含「搜尋結果」選項,用於查看與使用者語音搜尋相關的媒體項目。

如要指出應用程式支援顯示搜尋結果,請在服務 onGetRoot 方法傳回的額外套件中加入常數索引鍵 BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED,該索引鍵會對應至布林值 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);
}

如要提供搜尋結果,請覆寫媒體瀏覽器服務的 onSearch 方法。使用者叫用搜尋查詢介面或「搜尋結果」預設用途時,Android Auto 和 AAOS 會將使用者的搜尋字詞轉送至此方法。

您可以使用標題項目,讓搜尋結果更容易瀏覽。舉例來說,如果您的應用程式會播放音樂,您可以按照「專輯」、「演出者」和「歌曲」來編排搜尋結果。以下程式碼片段顯示 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.
}