カスタムの検索候補を追加する

Compose をお試しください
Jetpack Compose は、Android で推奨される UI ツールキットです。Compose で検索機能を追加する方法について説明します。

Android の検索ダイアログまたは検索ウィジェットを使用すると、アプリのデータから作成されたカスタム検索候補を表示できます。たとえば、アプリが辞書の場合、ユーザーがクエリの入力を完了する前に、検索フィールドに入力されたテキストに一致する辞書の単語を候補として表示できます。これは極めて有用な候補です。ユーザーが求めている結果を効果的に予測して、それに即座にアクセスできるようにすることが可能です。図 1 に、カスタム候補が表示された検索ダイアログの例を示します。

作成したカスタム候補をシステム全体のクイック検索ボックスでも利用できるようにすることで、アプリ外からコンテンツにアクセスできるようになります。

カスタム候補を追加する前に、Android の検索ダイアログまたは検索ウィジェットを実装して、アプリで検索を実行できるようにします。検索インターフェースを作成するコンテンツ プロバイダをご覧ください。

基本情報

図 1. カスタム検索候補が表示された検索ダイアログのスクリーンショット

ユーザーがカスタム候補を選択すると、システムによって Intent が検索可能アクティビティに送信されます。通常の検索クエリが ACTION_SEARCH アクションを含むインテントを送信するのに対し、カスタム候補を定義すると、ACTION_VIEW(または他の任意のインテント アクション)を使用できるほか、選択した候補に関連するデータを含めることもできます。辞書の例では、ユーザーが候補を選択すると、辞書で一致する単語を検索する代わりに、その単語の定義をアプリですぐに開くことができます。

カスタム候補を表示するには、次の手順を行います。

  • 検索インターフェースを作成するの説明に沿って、検索可能アクティビティを実装します。
  • カスタム候補を提供するコンテンツ プロバイダに関する情報を使用して検索可能構成を変更します。
  • 候補テーブルを(SQLiteDatabase などで)作成し、必須の列でテーブルをフォーマットします。
  • 候補テーブルにアクセス可能なコンテンツ プロバイダを作成し、マニフェストでそのプロバイダを宣言します。
  • ユーザーが候補(カスタム アクションとカスタムデータを含む)を選択したときに送信する Intent のタイプを宣言します。

Android システムは、検索ダイアログを表示するのと同じように、検索候補も表示します。必要なものは、システムが候補を取得できるコンテンツ プロバイダです。コンテンツ プロバイダの作成方法については、コンテンツ プロバイダをご覧ください。

アクティビティが検索可能であり、検索候補を表示できることがシステムで確認されると、ユーザーがクエリを入力したときに次の手順が行われます。

  1. システムが検索クエリのテキスト(その時点で入力されているすべてのテキスト)を取得し、候補を管理するコンテンツ プロバイダに対してクエリを実行します。
  2. コンテンツ プロバイダが、検索クエリのテキストに関連するすべての候補を指す Cursor を返します。
  3. Cursor から提供された候補のリストが表示されます。

カスタム候補が表示された後、以下の処理が行われることがあります。

  • ユーザーが別の文字を入力するか、なんらかの方法でクエリを変更した場合、上記の手順が再実行され、候補のリストが更新されます。
  • ユーザーが検索を実行した場合、候補が無視され、通常の ACTION_SEARCH インテントを使用して検索クエリが検索可能アクティビティに渡されます。
  • ユーザーが候補を選択した場合、インテントが検索可能アクティビティに送信され、カスタム アクションとカスタムデータが伝達されます。これにより、アプリで候補のコンテンツを開くことができるようになります。

検索可能構成を変更する

カスタム候補に対するサポートを追加するには、次の例に示すように、検索可能構成ファイルで android:searchSuggestAuthority 属性を <searchable> 要素に追加します。

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

各候補に関連付けるインテントのタイプや、コンテンツ プロバイダへのクエリのフォーマット方法によっては、追加の属性が必要になることがあります。その他のオプションの属性については、以下のセクションで説明します。

コンテンツ プロバイダを作成する

カスタム候補用のコンテンツ プロバイダを作成するには、まず コンテンツ プロバイダでコンテンツ プロバイダの作成方法を確認してください。カスタム候補用のコンテンツ プロバイダは、他のコンテンツ プロバイダと似ています。ただし、表示する各候補では、Cursor のそれぞれの行に特定の列を含める必要があります。システムはこの列を理解および使用することで候補をフォーマットします。

ユーザーが検索ダイアログまたは検索ウィジェットにテキストを入力すると、システムは、文字が入力されるたびに query() を呼び出して、コンテンツ プロバイダに対して候補のクエリを実行します。query() の実装では、コンテンツ プロバイダが候補データを検索して、適切な候補と判断した行を指す Cursor を返す必要があります。

カスタム候補用のコンテンツ プロバイダの作成方法について詳しくは、次の 2 つのセクションをご覧ください。

候補のクエリを処理する
システムからコンテンツ プロバイダにリクエストを送信する方法とリクエストの処理方法。
候補テーブルを作成する
各クエリで返される Cursor にシステムが求める列を定義する方法。

候補のクエリを処理する

システムは、コンテンツ プロバイダに候補をリクエストするときに、コンテンツ プロバイダの query() メソッドを呼び出します。このメソッドを実装して、候補データを検索し、適切と思われる候補を指す Cursor を返します。

システムが query() メソッドに渡すパラメータの概要を以下に示します(渡す順に記載)。

  1. uri

    常に次の形式のコンテンツ Uri です。

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

    デフォルトの動作では、システムがこの URI を渡し、それにクエリテキストを付加します。

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

    最後のクエリテキストは URI エンコード ルールを使用してエンコードされるため、検索を実行する前にデコードが必要になる場合があります。

    optional.suggest.path の部分は、検索可能構成ファイルで android:searchSuggestPath 属性を使用してこのようなパスを設定した場合にのみ URI に含めます。これは、複数の検索可能アクティビティで同じコンテンツ プロバイダを使用している場合にのみ必要です。その場合、候補クエリのソースの曖昧さを解消します。

  2. projection
    常に null。
  3. selection
    検索可能構成ファイルの android:searchSuggestSelection 属性に指定されている値です。android:searchSuggestSelection 属性を宣言していない場合は null です。これについては、次のセクションで詳しく説明します。
  4. selectionArgs
    検索可能構成で android:searchSuggestSelection 属性を宣言した場合、配列の最初の(唯一の)要素として検索クエリが含まれます。android:searchSuggestSelection を宣言していない場合、このパラメータは null になります。これについては、次のセクションで詳しく説明します。
  5. sortOrder
    常に null。

システムは検索クエリのテキストを 2 つの方法で送信できます。デフォルトの方法は、uri パラメータで渡されるコンテンツ URI の最後のパスとしてクエリテキストを含める方法です。一方、検索可能構成の android:searchSuggestSelection 属性に選択値を含めると、selectionArgs 文字列配列の最初の要素としてクエリテキストが渡されます。これらの 2 つのオプションについては、次のセクションで説明します。

URI でクエリを取得する

デフォルトでは、クエリが uri パラメータ(Uri オブジェクト)の最後のセグメントとして付加されます。この場合、クエリテキストを取得するには、次の例に示すように getLastPathSegment() を使用します。

Kotlin

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

Java

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

これにより、Uri の最後のセグメント(ユーザーが入力したクエリテキスト)が返されます。

選択引数でクエリを取得する

URI を使用する代わりに、query() メソッドで検索の実行に必要な要素をすべて受け取り、selection パラメータと selectionArgs パラメータで適切な値を伝達する方が合理的な場合もあります。この場合は、SQLite 選択文字列が設定された android:searchSuggestSelection 属性を検索可能構成に追加します。選択文字列には、実際の検索クエリのプレースホルダとして疑問符(?)を含めます。システムは、selection パラメータとして選択文字列を、selectionArgs 配列の最初の要素として検索クエリを使用して query() を呼び出します。

以下に、android:searchSuggestSelection 属性を設定して全文検索ステートメントを作成する方法の例を示します。

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

query() メソッドはこの構成を使用して、"word MATCH ?" として selection パラメータを、検索クエリとして selectionArgs パラメータを渡します。これらは、SQLite の query() メソッドにそれぞれの引数として渡すときに合成されます。つまり、疑問符がクエリテキストで置き換えられます。候補クエリをこの方法で受け取るように選択し、ワイルドカードをクエリテキストに追加する必要がある場合は、selectionArgs パラメータの前または後ろ(あるいはその両方)に付加します。これは、この値が引用符で囲まれ、疑問符の箇所に挿入されるためです。

上の例のもう 1 つの属性が android:searchSuggestIntentAction です。この属性では、ユーザーが候補を選択したときに各インテントで送信されるインテント アクションを定義します。これについては、候補用のインテントの宣言で詳しく説明します。

候補テーブルを作成する

Cursor でシステムに候補を返す場合、システムは各行に特定の列が含まれていることを期待します。候補データの保存先がデバイス上の SQLite データベースか、ウェブサーバー上のデータベースか、デバイスまたはウェブ上の別の形式かに関係なく、テーブルの行として候補をフォーマットし、Cursor を使用してそれらを表示します。

システムは複数の列を認識しますが、必要なのはそのうちの次の 2 つだけです。

_ID
各候補の一意の行 ID(整数)。ListView に候補を表示するには、システムでこの ID が必要になります。
SUGGEST_COLUMN_TEXT_1
候補として表示される文字列。

次の列はすべて省略可能です。ほとんどのトピックについては、以降のセクションで詳しく説明します。

SUGGEST_COLUMN_TEXT_2
文字列。Cursor にこの列が含まれている場合、すべての候補が 2 行の形式で表示されます。この列の文字列は、第二の小さい文字のテキスト行として第一の候補テキストの下に表示されます。第二のテキストを表示しない場合は、null を指定するか、空にします。
SUGGEST_COLUMN_ICON_1
ドローアブル リソース、コンテンツ、またはファイル URI の文字列。Cursor にこの列が含まれている場合、すべての候補がアイコンとテキストの形式で表示されます(ドローアブル アイコンが左側に表示されます)。アイコンを表示しない場合は、この行に null またはゼロを指定します。
SUGGEST_COLUMN_ICON_2
ドローアブル リソース、コンテンツ、またはファイル URI の文字列。Cursor にこの列が含まれている場合、すべての候補がアイコンとテキストの形式で表示されます(アイコンが右側に表示されます)。アイコンを表示しない場合は、この行に null またはゼロを指定します。
SUGGEST_COLUMN_INTENT_ACTION
インテント アクションの文字列。この列が存在し、所定の行に値が含まれている場合、ここで定義したアクションが候補のインテントの設定時に使用されます。この要素が指定されていない場合、検索可能構成の android:searchSuggestIntentAction フィールドからアクションが取得されます。すべてのおすすめのアクションが同じ場合、android:searchSuggestIntentAction を使用してアクションを指定し、この列を省略する方が効率的です。
SUGGEST_COLUMN_INTENT_DATA
データ URI の文字列。この列が存在し、所定の行に値が含まれている場合、候補のインテントの設定時にこのデータが使用されます。この要素が指定されていない場合、検索可能構成の android:searchSuggestIntentData フィールドからデータが取得されます。どちらのソースも指定されていない場合、インテントのデータ フィールドが null になります。すべての候補のデータが同じか、定数部分と特定の ID を使用してデータを記述できる場合は、android:searchSuggestIntentData を使用してデータを指定し、この列を省略する方が効率的です。
SUGGEST_COLUMN_INTENT_DATA_ID
URI パスの文字列。この列が存在し、所定の行に値が含まれている場合は、「/」とこの値がインテントのデータ フィールドに付加されます。この列を使用する必要があるのは、検索可能構成の android:searchSuggestIntentData 属性で指定されたデータ フィールドがすでに適切なベース文字列に設定されている場合だけです。
SUGGEST_COLUMN_INTENT_EXTRA_DATA
任意のデータ。この列が存在し、所定の行に値が含まれている場合、このエクストラ データが候補のインテントの設定時に使用されます。指定されていない場合、インテントのエクストラ データ フィールドが null になります。この列を使用すると、インテントの EXTRA_DATA_KEY キーにエクストラとして含まれる追加データを候補で指定できます。
SUGGEST_COLUMN_QUERY
この列が存在し、所定の行にこの要素が存在する場合、このデータが候補のクエリの設定時に使用され、インテントの QUERY キーにエクストラとして含まれます。候補のアクションが ACTION_SEARCH の場合は必須ですが、それ以外の場合は省略可能です。
SUGGEST_COLUMN_SHORTCUT_ID
クイック検索ボックスで候補を表示する場合にのみ使用します。この列は、検索候補をショートカットとして保存する必要があるかどうか、および検索候補を検証する必要があるかどうかを示します。ショートカットは通常、ユーザーがクイック検索ボックスで候補をタップしたときに設定されます。この列を設定しないと、結果がショートカットとして保存され、更新されなくなります。SUGGEST_NEVER_MAKE_SHORTCUT に設定すると、結果がショートカットとして保存されません。その他の場合は、SUGGEST_URI_PATH_SHORTCUT を使用して最新の候補を確認するためにショートカット ID が使用されます。
SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING
クイック検索ボックスで候補を表示する場合にのみ使用します。この列では、クイック検索ボックス内でこの候補のショートカットを更新している間、SUGGEST_COLUMN_ICON_2 のアイコンの代わりにスピナーを表示することを指定します。

これらの列のほとんどについては、以降のセクションで詳しく説明します。

候補用のインテントを宣言する

ユーザーが検索ダイアログまたは検索ウィジェットの下に表示されるリストから候補を選択すると、システムによってカスタムの Intent が検索可能アクティビティに送信されます。インテントのアクションとデータはデベロッパーが定義する必要があります。

インテント アクションを宣言する

カスタム候補の最も一般的なインテント アクションは ACTION_VIEW です。このアクションは、単語の定義、ユーザーの連絡先情報、ウェブページなど、何かを開きたい場合に適しています。ただし、インテント アクションは他のアクションにすることもでき、候補ごとに異なるアクションを指定することも可能です。

すべての候補で同じインテント アクションを使用するかどうかに応じて、次の 2 つの方法でアクションを定義できます。

  • 次の例に示すように、検索可能構成ファイルの android:searchSuggestIntentAction 属性を使用して、すべての候補のアクションを定義します。
    <?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>
  • 個々の候補のアクションを定義するには、SUGGEST_COLUMN_INTENT_ACTION 列を使用します。そのためには、SUGGEST_COLUMN_INTENT_ACTION 列を候補テーブルに追加し、各候補で使用するアクション("android.intent.action.VIEW" など)を設定します。

この 2 つの方法を組み合わせることも可能です。たとえば、すべての候補で使用するアクションが指定された android:searchSuggestIntentAction 属性をデフォルトで含めて、その後、SUGGEST_COLUMN_INTENT_ACTION 列で別のアクションを宣言することで、一部の候補のアクションをオーバーライドできます。SUGGEST_COLUMN_INTENT_ACTION 列に値を含めないと、android:searchSuggestIntentAction 属性で指定されているインテントが使用されます。

インテント データを宣言する

ユーザーが候補を選択すると、前のセクションで説明したとおり、定義したアクションを含むインテントが検索可能アクティビティに送信されます。ただし、どの候補が選択されたかをアクティビティで特定するためには、インテントでデータも渡す必要があります。厳密に言えば、データは候補ごとに一意なものである必要があります(SQLite テーブルの候補の行 ID など)。インテントを受け取った後、添付されているデータを取得するには、getData() または getDataString() を使用します。

インテントに含めるデータは、次の 2 つの方法で定義できます。

  • 候補テーブルの SUGGEST_COLUMN_INTENT_DATA 列内で候補ごとにデータを定義します。

    SUGGEST_COLUMN_INTENT_DATA 列を追加し、各行に一意のデータを設定することで、候補テーブルの各インテントに必要なすべてのデータ情報を指定します。この列のデータは、この列で定義したとおりにインテントに添付されます。これで、getData() または getDataString() を使用してデータを取得できます。

  • データ URI を 2 つの部分(すべての候補に共通の部分と、候補ごとに固有の部分)に分けます。これらをそれぞれ、検索可能構成の android:searchSuggestintentData 属性と、候補テーブルの SUGGEST_COLUMN_INTENT_DATA_ID 列に設定します。

    次の例は、検索可能構成の android:searchSuggestIntentData 属性で、すべての候補に共通の URI の部分を宣言する方法を示しています。

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

    候補テーブルの SUGGEST_COLUMN_INTENT_DATA_ID 列に各候補の最終パス(固有の部分)を含めます。ユーザーが候補を選択すると、システムが android:searchSuggestIntentData から文字列を取得してスラッシュ(/)を付加し、SUGGEST_COLUMN_INTENT_DATA_ID 列のそれぞれの値を追加して完全なコンテンツ URI を構成します。これで、getData() を使用して Uri を取得できます。

データの追加

インテントでさらに多くの情報を表現する必要がある場合、テーブル列 SUGGEST_COLUMN_INTENT_EXTRA_DATA などを追加できます。この列に、候補に関する追加情報を保存できます。この列に保存されたデータは、インテントのエクストラ Bundle の EXTRA_DATA_KEY に配置されます。

インテントを処理する

カスタム検索候補にカスタム インテントを提供したので、次に、ユーザーが候補を選択したときに、検索可能アクティビティでこれらのインテントを処理する必要があります。これは、検索可能アクティビティですでに行っている ACTION_SEARCH インテントの処理とは別のものです。以下に、アクティビティの onCreate() コールバックでインテントを処理する方法の例を示します。

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

この例のインテント アクションは ACTION_VIEW で、候補のアイテムを指す、android:searchSuggestIntentData 文字列と SUGGEST_COLUMN_INTENT_DATA_ID 列が合成された完全な URI がデータによって渡されます。その後、URI がローカルの showResult() メソッドに渡されます。このメソッドはコンテンツ プロバイダに対し、URI で指定されたアイテムを照会します。

クエリテキストを書き換える

デフォルトでは、ユーザーが方向コントロール(トラックボールや D-pad など)を使用して候補リストをスクロールした場合、クエリテキストは更新されません。ただし、ユーザーのクエリテキストが、フォーカスされている候補と一致するクエリとともにテキスト ボックスに表示されている場合、一時的に書き換えることができます。これにより、ユーザーは候補になっているクエリを確認し、検索ボックスを選択して、クエリを検索としてディスパッチする前に編集できます。

クエリテキストは以下の方法で書き換えることができます。

  • "queryRewriteFromText" 値が設定された android:searchMode 属性を検索可能構成に追加します。この場合、候補の SUGGEST_COLUMN_TEXT_1 列の内容がクエリテキストの書き換えに使用されます。
  • "queryRewriteFromData" 値が設定された android:searchMode 属性を検索可能構成に追加します。この場合、候補の SUGGEST_COLUMN_INTENT_DATA 列の内容がクエリテキストの書き換えに使用されます。これは、ユーザーに表示することを目的とした URI やその他のデータ形式(HTTP URL など)でのみ使用してください。この方法では、クエリの書き換えに内部 URI スキームを使用しないでください。
  • 候補テーブルの SUGGEST_COLUMN_QUERY 列で、一意のクエリテキスト文字列を指定します。この列が存在し、現在の候補の値が設定されている場合、クエリテキストの書き換えと以前の実装のいずれかのオーバーライドに使用されます。

クイック検索ボックスに検索候補を公開する

カスタム検索候補を表示するようにアプリを設定すると、グローバルにアクセス可能なクイック検索ボックスでそれらの候補を表示できるようになります。この操作は、検索可能構成に android:includeInGlobalSearch を追加して "true" に設定するだけです。

追加の作業が必要なシナリオは、コンテンツ プロバイダが読み取り権限を必要とする場合だけです。このシナリオでは、次の例に示すように、プロバイダ用の <path-permission> 要素を追加して、コンテンツ プロバイダに対する読み取りアクセス権をクイック検索ボックスに付与する必要があります。

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

この例では、プロバイダがコンテンツに対する読み取りおよび書き込みアクセス権を制限しています。<path-permission> 要素は、"android.permission.GLOBAL_SEARCH" 権限が存在する場合に "/search_suggest_query" パス プレフィックス内のコンテンツに対する読み取りアクセス権を付与することで、制限を修正しています。これにより、クイック検索ボックスにアクセス権が付与され、コンテンツ プロバイダに対して候補を照会できるようになります。

コンテンツ プロバイダに読み取り権限が適用されていなくても、クイック検索ボックスはデフォルトでコンテンツ プロバイダを読み取ることができます。

デバイスで候補を有効にする

デフォルトでは、アプリがクイック検索ボックスに候補を表示するように設定されていても、実際には候補を表示することはできません。アプリの候補をクイック検索ボックスに含めるかどうかは、ユーザーが [検索対象]([設定] > [検索])を開いて、アプリを検索対象として有効にすることで選択します。

クイック検索ボックスで使用できる各アプリには、[検索対象] 設定ページにエントリがあります。このエントリには、アプリの名前と、アプリから検索でき、クイック検索ボックス内の候補で使用できるコンテンツの簡単な説明が含まれます。検索可能なアプリの説明のテキストを定義するには、次の例に示すように、android:searchSettingsDescription 属性を検索可能構成に追加します。

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

android:searchSettingsDescription の文字列はできるだけ簡潔にし、検索可能なコンテンツについて記述します。たとえば、音楽アプリの場合は「アーティスト、アルバム、トラック」、メモ帳アプリの場合は「保存したメモ」といった具合です。ユーザーはこの説明からどのような候補が表示されているかを理解できるため、この説明は重要です。android:includeInGlobalSearch が true の場合は、この属性を常に含めます。

ユーザーは、設定メニューにアクセスしてアプリの検索候補を有効にする必要があります。そのため、検索がアプリの重要な要素である場合は、そのことをユーザーに伝える方法について検討してください。たとえば、ユーザーがアプリを初めて起動したときに、クイック検索ボックスの検索候補を有効にする方法を説明するメモを表示できます。

クイック検索ボックスの候補ショートカットを管理する

ユーザーがクイック検索ボックスで選択した候補を自動的にショートカットにすることができます。これらはシステムがコンテンツ プロバイダからコピーした候補であるため、候補にすばやくアクセスできます。コンテンツ プロバイダを再照会する必要もありません。

デフォルトでは、この機能はクイック検索ボックスで取得したすべての候補に対して有効になっていますが、候補データが経時的に変化する場合は、ショートカットを更新するようリクエストできます。たとえば、候補が動的なデータ(連絡先のプレゼンス状態など)を参照する場合、候補ショートカットをユーザーに表示するときに更新するようリクエストします。そのためには、候補テーブルに SUGGEST_COLUMN_SHORTCUT_ID を含めます。この列を使用して、次のいずれかの方法で各候補のショートカットの動作を設定できます。

  • クイック検索ボックスで、コンテンツ プロバイダに対して候補ショートカットの最新バージョンを再照会します。

    ショートカットが表示されるたびに、候補に対して最新バージョンが再照会されるように、SUGGEST_COLUMN_SHORTCUT_ID 列で値を指定します。更新クエリが返ってくるまでは、最近使用可能になったデータでショートカットが即座に表示され、更新クエリが返ってくると、候補が新しい情報で更新されます。更新クエリは、(SUGGEST_URI_PATH_QUERY ではなく)SUGGEST_URI_PATH_SHORTCUT の URI パスを使用してコンテンツ プロバイダに送信されます。

    返す Cursor には、元の候補と同じ列を使用した候補を 1 つ含める必要があります。あるいは、ショートカットが有効でなくなったことを示す場合は空にする必要があります(この場合、候補が表示されなくなり、ショートカットが削除されます)。

    更新に時間がかかる可能性があるデータを候補が参照する場合(ネットワーク ベースの更新など)、更新が完了するまで右側のアイコンの代わりに進行状況スピナーを表示するために、値が true に設定された SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING 列を候補テーブルに追加することもできます。true 以外の値が設定されている場合、進行状況スピナーは表示されません。

  • 候補がショートカットにコピーされないようにします。

    SUGGEST_COLUMN_SHORTCUT_ID 列で、SUGGEST_NEVER_MAKE_SHORTCUT という値を指定します。この場合、候補がショートカットにコピーされることはありません。この操作が必要なのは、以前にコピーした候補を絶対に表示させたくない場合だけです。列で通常の値を指定すると、更新クエリが返ってくるまでの間だけ候補ショートカットが表示されます。

  • デフォルトのショートカットの動作を適用できるようにします。

    変更されることがなく、ショートカットとして保存可能な候補の場合は、SUGGEST_COLUMN_SHORTCUT_ID を空のままにします。

どの候補も変更されない場合、SUGGEST_COLUMN_SHORTCUT_ID 列は必要ありません。

クイック検索ボックスの候補のランキングについて

アプリの検索候補をクイック検索ボックスで表示できるようにすると、特定のクエリに対する候補の表示方法がクイック検索ボックスのランキングによって決まります。この表示方法は、そのクエリに対する結果を保持している他のアプリの数や、ユーザーが結果を選択した頻度(他のアプリとの比較)によって異なる場合があります。候補がどのようにランク付けされるかや、特定のクエリに対してアプリの候補が表示されるかどうかについての保証はありません。一般に、結果の質が高い場合、アプリの候補が目立つ位置に表示される可能性が高くなり、結果の質が低いアプリでは、候補が下位にランク付けされるか、表示されない可能性が高くなります。