
これは、Android検索ダイアログの使用に関する最後の記事です(前の記事は
こちらと
こちら )。 その中で、動的検索ヒントをダイアログに追加する方法、およびアプリケーションの検索をシステムのクイック検索ボックス(QSB)に統合する方法を説明します。 QSBの利点は、その助けを借りて、OSのほぼどこからでも情報を取得できることです。
理論
検索ヒントは、検索中のアプリケーションのデータを使用して作成されます。 ユーザーがそのうちの1つを選択すると、検索マネージャーは、検索を担当するアクティビティにインテントを送信します。 通常、ユーザーがダイアログの検索アイコンをクリックすると、検索タイプのインテントが送信されますが、この場合はプロンプトを選択するときに、別のタイプのインテントを定義して、インターセプトして適切なアクション(新しいダイアログの作成、アクティビティの呼び出しなど)を実行できます情報などを表示する
検索リクエストのデータは以前と同様にIntentを介して転送されますが、ここではURIを使用してコンテンツプロバイダーを介したリクエストのタイプを決定します。
繰り返しますが、ダイアログをレンダリングするためにアクションを実行する必要はありません。これはSearch Managerによって実行されます。必要なのは、構成xmlファイルを送信することだけです。
そのため、Search Managerがアクティビティを検索の責任と定義し、検索のヒントを提供すると、次の一連のアクションが発生します。
- Search Managerは、検索クエリのテキストを受信すると、ヒントを提供するコンテンツプロバイダーに要求を送信します。
- コンテンツプロバイダーは、検索クエリのテキストに一致するヒントを指すカーソルを返します。
- Search Managerはカーソルを使用してツールチップを表示します
プロンプトのリストが表示された後、次のことが発生する場合があります。
- ユーザーがリクエストのテキストを変更すると、上記のすべての手順が繰り返されます。
- ユーザーが検索を開始すると、プロンプトは無視され、検索タイプのインテントがアクティビティに送信されます。
- ユーザーがヒントを選択すると、異なるタイプのインテントがアクティビティに配信され(タイプは設定ファイルで定義されます)、URIをデータとして転送します。 URIは、選択したプロンプトに対応するテーブル内のレコードを見つけるために使用されます。
そのため、動的なツールチップが追加されるようにアプリケーション(
パート1で説明したもの)を変更し、メカニズムを動作させるために、ツールチップを選択するときに、新しいアクティビティを呼び出します。これは、要求に応じて情報を表示します。 実装には次のものが必要です。
- ダイアログ構成ファイルを変更して、コンテンツプロバイダーとヒントに使用されるインテントのタイプに関する情報を追加します。
- Search Managerがプロンプトに必要な列を提供するテーブルをSQLiteデータベースに作成します
- ヒントテーブルにアクセスできる新しいコンテンツプロバイダーを作成し、マニフェストで定義する
- プロンプトを選択するときに情報を表示するアクティビティを追加します
構成ファイルを変更する
音声検索を使用する場合など、ダイアログを表示して変更するには、構成ファイル(res / xml / searchable.xml)が必要であることを思い出します。 動的なヒントを使用するには、android:searchSuggestAuthorityパラメーターをファイルに追加する必要があります。 コンテンツプロバイダーの認証文字列と一致します。 さらに、パラメータandroid:searchMode = "queryRewriteFromText"を追加します。その値は、たとえばトラックボールを使用してプロンプトをナビゲートすると、ダイアログ内の検索文字列が上書きされることを示します。 また、選択演算子、ツールチップが選択されたときに送信されるインテントのタイプ、およびコンテンツプロバイダーを要求するために必要なダイアログ内の入力文字の最小数を指定するパラメーターを追加します。
ファイルres / xml / searchable.xml<?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/app_name" android:hint="@string/search_hint" android:searchSettingsDescription="@string/settings_description" android:searchMode="queryRewriteFromText" android:includeInGlobalSearch="true" android:searchSuggestAuthority="com.example.search.SuggestionProvider" android:searchSuggestIntentAction="android.intent.action.VIEW" android:searchSuggestIntentData="content://com.example.search.SuggestionProvider/records" android:searchSuggestThreshold="1" android:searchSuggestSelection=" ?"> </searchable>
コンテンツプロバイダーを作成する
実際、当社のコンテンツプロバイダーは他のプロバイダーと違いはありません。 ただし、プロンプトの表の各行について、検索マネージャーで必要な列が選択されていることを確認する必要があります。 コンテンツプロバイダーのquery()メソッドを使用して、プロンプトのデータを照会します。 さらに、ユーザーがダイアログで新しい文字を入力するたびに呼び出されます。 したがって、query()メソッドは、クエリに一致するテーブル内のレコードにカーソルを返す必要があり、Search Managerはプロンプトを表示できるようになります。 コードコメントのメソッドの説明を参照してください。
要求テキスト自体はURIに追加されるため、受信に問題はありません;標準のgetLastPathSegment()メソッドを使用するだけです。
ヒント表の作成
Search Managerは、レコードを指すカーソルを受け取ると、各レコードに特定の列セットが必要です。 2つは必須です。_IDは各ツールチップの一意の識別子で、SUGGEST_COLUMN_TEXT_1はツールチップテキストです。
たとえば、SUGGEST_COLUMN_ICON_1を使用して、ツールチップの左側に表示されるアイコンをレコードごとに定義できるオプションの列が多数あります(連絡先の検索などに非常に便利です)。
インテントのデータ型定義
URIを介して要求に応じてデータを送信するため、どのツールチップが選択されたかを判断するメカニズムが必要です。 2つの方法があります。 1つ目は、レコードごとに一意のデータがある個別の列SUGGEST_COLUMN_INTENT_DATAを定義することです。その後、getData()またはgetDataString()を使用してIntentからデータを取得できます。 2番目のオプションは、構成ファイル(res / xml / searchable.xml)内のすべてのインテントのデータ型を決定し、SUGGEST_COLUMN_INTENT_DATA_ID列を使用して各インテントの一意のデータをURIに追加することです。
2番目のオプションを使用します。SUGGEST_COLUMN_INTENT_DATA_IDからテーブルのrowIdへのマッピングを簡単に作成できるため、テーブルに個別の列を作成しませんでした。 SQLiteへのスポーツの関心のために、
FTS3が検索
に使用されました。つまり、PRIMARY KEYやNULL / NOT NULLなどの列(制約)に制限を課すことができない仮想テーブルを作成する必要がありました。 ただし、仮想テーブルには一意の行識別子があり、それにマッピングを設定します。 つまり、Intentのデータは次の形式になります。「/」およびテーブルの行のrowIdがURIに追加されます。
情報を表示するアクティビティを作成する
インターフェイスはres / layout / record_activity.xmlにあります。 そのアクティビティは、Intentからデータを取得し、コンテンツプロバイダーを介してカーソルを要求し、テキストフィールドにレコードを表示するだけです。
ファイルres / layout / record_activity.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="10dp"> <TextView android:id="@+id/record_header" android:textSize="25dp" android:textColor="?android:textColorPrimary" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
ここで、マニフェストにコンテンツプロバイダーと新しいアクティビティに関する情報を入力します。また、2つのアクティビティがあるため、デフォルトで検索を担当するアクティビティを示します。
AndroidManifest.xmlファイル <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.search" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".Main" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> </activity> <activity android:name=".RecordActivity" android:theme="@android:style/Theme.NoTitleBar" /> <provider android:name=".SuggestionProvider" android:authorities="com.example.search.SuggestionProvider" /> <meta-data android:name="android.app.default_searchable" android:value=".Main" /> </application> <uses-sdk android:minSdkVersion="5" /> </manifest>
検索を担当するアクティビティでインテントをインターセプトする
上記のすべてのステップの後、検索を担当するメインアクティビティでインテントを処理する必要があります。 ツールチップのインテントタイプをビューとして定義したため、チェックを追加するだけです。 条件が満たされた場合、RecordActivityはIntentを使用して起動され、そのデータには、URI + "/" +テーブルのツールチップが書き込まれます。
クイック検索ボックスの統合
カスタム提案を使用するようにアプリケーションを変更した後、システム検索に追加できます。 これを行うには、searchable.xmlファイルに2つのパラメーターを追加します。
- android:includeInGlobalSearch = "true"-QSBがアプリケーションを検索できることを示します。
- android:searchSettingsDescription = "@ string / settings_description"-アプリケーションの説明を示します。これはクイック検索ボックスの設定時に表示されます。 これらの設定は、設定->検索にあります。
これらのオプションはAndroid 1.6から利用できます。つまり、以下のバージョンでは、QSB用にアプリケーションを構成することはできません。
ソースコード
必要なすべてのクラスの完全なソースコードを示します。 Main.java-要求を見つけてコンテンツプロバイダーに送信するメインのアクティビティであるRecordActivity.java-特定のレコードのデータを含むインテントを受け取り、レコードへのリンクを受け取り、情報を表示します。 SuggestionProvider.javaは、Search Managerからプロンプトのテーブルへのリクエストを処理するコンテンツプロバイダーです。 RecordsDbHelper.java-テーブルの作成、テーブルへの入力、必要な表示の確立、およびレコードの「マッチング」自体を行います。
Main.javaファイル package com.example.search; import android.app.ListActivity; import android.app.SearchManager; import android.content.Intent; import android.database.Cursor; import android.os.Bundle; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.SimpleCursorAdapter; import android.widget.Toast; public class Main extends ListActivity { private EditText text; private Button add; private RecordsDbHelper mDbHelper; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mDbHelper = new RecordsDbHelper(this); Intent intent = getIntent(); if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
ファイルRecordActivity.java package com.example.search; import android.app.Activity; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.widget.TextView; public class RecordActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.record_activity);
ファイルSuggestionProvider.java package com.example.search; import android.app.SearchManager; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.net.Uri; import android.provider.BaseColumns; public class SuggestionProvider extends ContentProvider{ private RecordsDbHelper mDbHelper; public static String AUTHORITY = "com.example.search.SuggestionProvider"; public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/records");
ファイルRecordsDbHelper.java package com.example.search; import java.util.HashMap; import android.app.SearchManager; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteQueryBuilder; import android.provider.BaseColumns; import android.util.Log; public class RecordsDbHelper {
プロジェクト全体は
code.google.comで
取得できます。
ご清聴ありがとうございました!