天天看點

android對外提供全局搜尋功能

一、本地搜尋介紹  

1. 全局搜尋(QuickSearchBox)介紹:

搜尋是Android上的核心使用者功能。使用者應該能夠搜尋他們可用的任何資料,無論内容是位于裝置還是Internet上。為了幫助使用者建立一緻的搜尋體驗,Android提供了一個搜尋架構,可幫助您實作對您的應用程式的搜尋,當使用者單擊某一個搜尋出來的結果項就會打開相應的應用程式,顯示搜尋結果的詳細資訊。

2. 全局搜尋(QuickSearchBox)技術架構:

Android系統的全局搜尋由搜尋管理器(SearchManager),全局搜尋AppWidget,全局搜尋應用,支援全局搜尋的應用程式(聯系人,音樂,浏覽器等)四大部分組成:

(1)framework層的搜尋管理器(SearchManager):主要功能是對Android系統全局搜尋提供支援,當Android系統啟動完成後會發出系統啟動完成(BOOT_COMPLETED)廣播,SearchManager接收到此廣播後會通過PackageManager搜尋系統中支援全局搜尋的應用程式(應用程式如何支援全局搜尋以後的文章會介紹),這此支援全局搜尋的應用我們稱為搜尋源,SearchManager解析搜尋源的配置資訊并将這些配置資訊封裝成對象儲存在List清單中供全局搜尋應用程式使用。

(2)搜尋架構提供兩種搜尋輸入模式:螢幕頂部的搜尋對話框或可以嵌入到活動布局中的搜尋小部件(SearchView)。無論哪種情況,Android系統将通過向執行搜尋的特定活動提供搜尋查詢來協助您的搜尋實作。您還可以啟用搜尋對話框或視窗小部件來提供使用者類型的搜尋建議。

(3)支援全局搜尋的應用程式:每一個支援全局搜尋的應用程式都需要實作一個ContentProvider,通過這個ContentProvider向外提供資料,全局搜尋應用(QuickSearchBox)會調用這些ContentProvider擷取資料。

3. 搜尋執行全過程:

Android系統啟動完成,發出系統啟動完成(BOOT_COMPLETED)廣播,搜尋管理器(SearchManager + Service)接收到此廣播後會通過PackageManager搜尋系統中支援全局搜尋的應用程式,并解析這些應用程式的配置資訊(配置資訊中包括請求支援全局搜尋應用的ContentProvider的authority及其它配置資訊,這些配置資訊由應用的開發人員配置),封裝成對象儲存到List中,當使用者單擊Launcher中的全局搜尋的AppWidget元件後打開全局搜尋應用(QuickSearchBox)的主界面,在界面中的搜尋輸入框中輸入搜尋内容,這時全局搜尋應用(QuickSearchBox)會從搜尋管理器(SearchManager + Service)中取出全部支援全局搜尋的應用程式List,并解析它們的配置資訊,根據配置資訊(authority等)組将成URI,要據URI調用支援全局搜尋應用的ContentProvider,ContentProvider的查詢方法會根據URI搜尋資料,并将搜尋到的結果以Cursor型式傳回,全局搜尋應用會解決這些資料,并以List的形式顯示到UI界面中。

二、APP配置全局搜尋資訊 :GoogleAPI:https://developer.android.com/guide/topics/search/searchable-config.html

1)應用程式支援全局搜尋,向搜尋程式提供搜尋結果,成為搜尋源,搜尋應用程式可以通過解析配置資訊組拼成URI請求應用的ContentProvider擷取搜尋結果

定義Android系統使用的所有搜尋配置,以提供輔助搜尋如下:

配置activity

<application ... >
    <activity android:name=".SearchableActivity" >
       
<!-- Receives the search request. -->
<intent-filter>
 <action android:name="android.intent.action.SEARCH" />
 <!-- No category needed, because the Intent will specify this class component-->
</intent-filter>

<!-- Points to searchable meta data. -->
<meta-data android:name="android.app.searchable"
 android:resource="@xml/searchable" />   
 </activity>
    ...
       
<!-- Points to searchable activity so the whole app can invoke search. -->
<meta-data android:name="android.app.default_searchable"
 android:value=".SearchableDictionary" /> 
</application>      

在應用程式的res目錄中建立xml目錄,在xml目錄中建立searchable.xml檔案:

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
 android:label="@string/search_label"
 android:hint="@string/search_hint"
 android:searchSettingsDescription="@string/settings_description"
 android:searchSuggestAuthority="com.example.android.searchabledict.DictionaryProvider" //和提供搜尋功能的Contentprovider:autherity一緻
 android:searchSuggestIntentAction="android.intent.action.VIEW" // String字元串,單擊搜尋結果清單中的某一項時,發出Intent對象中的Action
 /也可以在資料庫中加入SUGGEST_COLUMN_INTENT_ACTION字段綁定action。
 android:searchSuggestIntentData="content://com.example.android.searchabledict.DictionaryProvider/dictionary" // 配置的URI資訊
 android:searchSuggestSelection=" ?" // 定義搜尋時參數的占位符
 android:searchSuggestThreshold="1" // int值,輸入多少個字元後開始搜尋
 android:includeInGlobalSearch="true" // 是否将内容加入android的全局搜尋。true,加入
 >
 </searchable>      

Android:label 标簽詳解:您的應用程式的名稱。它應該與應用于您的<activity>或<application> manifest元素的android:label屬性的名稱相同。當您将android:includeInGlobalSearch設定為“true”時,此标簽僅對使用者可見,在這種情況下,此标簽用于将您的應用程式辨別為系統搜尋設定中的可搜尋項目。

2)在AndroidManifest.xml檔案中配置ContentProvider:

<!-- Provides search suggestions for words and their definitions. -->
<provider android:name=".DictionaryProvider"
 android:exported="true"
 android:authorities="com.example.android.searchabledict.DictionaryProvider" // 和searchable.xml中的authority相對應
 />      

在ContentProvider的onCreate()方法中完成SQLiteOpenHelper資料庫建立和初始化資料的操作,啟動異步線程加載本地資料到資料庫中。

在QuickSearchBox中通過ContentResolver調用内容提供者的query()方法進行資訊搜尋,應用程式必須實

現這個方法并且傳回搜尋到的Cursor對象。

@Override

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,

 String sortOrder)

第一個參數(uri):

content://authority/suggestion.path/search_suggest_query/queryStr?limit=50

content://:标準字首,用來說明一個Content Provider控制這些資料;

authority:對應searchable.xml檔案中的android:searchSuggestAuthority屬性,用于唯一辨別這個ContentProvider,外部調用者可以根據這個辨別來找到它。對于第三方應用程式,為了保證URI辨別的唯一性,它必須是一個完整的、小寫的類名。這個辨別在元素的authorities屬性中說明,一般是定義該ContentProvider的包.類的名稱

suggestion.path:對應searchable.xml檔案中的android:searchSuggestPath屬性,就是你要操作的資料庫中表的名字,或者你也可以自己定義,記得在使用的時候保持一緻就可以了;

search_suggest_query : 固定字元串。

queryStr: 查詢字元串。

limit :  查詢條數。

第二個參數 projection:要放入光标列的清單,Null表示所有所有列

第三個參數:selection:過濾行時應用的選擇條件,對應searchable.xml檔案中android:searchSuggestSelection屬性,ContentProvider的query方法将會調用SQLite資料,組成SQL語句中where後面的條件

第四個參數:您可以包含選擇"?s"來替代來自selectionArgs的值,以便它們出現在選擇中。 這些值将被綁定為字元串。多個判斷條件。

第五個參數:sortOrder:遊标中的行應如何排序,Null則提供者可以自由定義排序順序

API提供的資料庫關鍵字SearchManager類中:https://developer.android.com/reference/android/app/SearchManager.html

String

SUGGEST_COLUMN_AUDIO_CHANNEL_CONFIG

建議光标的列名。 可選的。 如果您的内容包含音頻,則應提供此列指定音頻通道配置。 列中的資料是格式如“channels.subchannels”(如“1.0”或“5.1”)的字元串。

String

SUGGEST_COLUMN_CONTENT_TYPE

建議光标的列名。 可選的。 如果您的内容是媒體類型,您應該提供此列,以便搜尋應用可以了解有關您的内容的更多資訊。 列中的資料必須指定内容的MIME類型。

String

SUGGEST_COLUMN_DURATION

建議光标的列名。 可選的。 如果您的内容是視訊或音頻,則應提供此列以毫秒為機關指定内容的持續時間。 列中的資料是長類型的。

String

SUGGEST_COLUMN_FLAGS

建議光标的列名。 可選的。 此列用于指定每個項目的附加标志。 可以指定多個标志。

必須是FLAG_QUERY_REFINEMENT中的一個或0表示沒有标志。

String

SUGGEST_COLUMN_FORMAT

建議光标的列名。 未使用 - 可以為null或列可以省略

String

SUGGEST_COLUMN_ICON_1

建議光标的列名。 可選的。 如果您的光标包含此列,則所有建議将以包含兩個小圖示的空間的格式提供,其中一個位于左側,另一個在每個建議的右側。 列中的資料必須是可繪制的資源ID,或以下列格式之一的URI:

String

SUGGEST_COLUMN_ICON_2

建議光标的列名。 可選的。 如果您的光标包含此列,則所有建議将以包含兩個小圖示的空間的格式提供,其中一個位于左側,另一個在每個建議的右側。 列中的資料必須是可繪制的資源ID,或以下列格式之一的URI:

String

SUGGEST_COLUMN_INTENT_ACTION

建議光标的列名。 可選的。 如果此列存在,并且此元素存在于給定行,則這是在形成建議意圖時将使用的操作。 如果未提供該元素,則該操作将從您的XML中繼資料中的android:searchSuggestIntentAction字段擷取。 這些建議中至少有一個必須存在以産生意圖。 注意:如果您的操作對于所有建議相同,則使用XML中繼資料指定它并從光标中省略更為有效。

String

SUGGEST_COLUMN_INTENT_DATA

建議光标的列名。 可選的。 如果此列存在,并且此元素存在于給定行,則這是在形成建議意圖時将使用的資料。 如果未提供元素,則資料将從您的XML中繼資料中的android:searchSuggestIntentData字段中擷取。 如果沒有提供任何源,則Intent的資料字段将為空。 注意:如果您的資料對于所有建議相同,或者可以使用常量部分和特定ID進行描述,則使用XML中繼資料指定它并從光标中省略更為有效。

String

SUGGEST_COLUMN_INTENT_DATA_ID

建議光标的列名。 可選的。 如果此列存在且該元素存在于給定行,則“/”将該值附加到Intent中的資料字段中。 隻有當資料字段已經被設定為适當的基本字元串時,才應該使用。

String

SUGGEST_COLUMN_INTENT_EXTRA_DATA

建議光标的列名。 可選的。 如果此列存在,并且此元素存在于給定行,則這是在形成建議意圖時将使用的資料。 如果沒有提供,則意圖的額外資料字段将為空。 這個列允許提供額外的任意資料的建議,這些資料将作為EXTRA_DATA_KEY的關鍵字額外提供。

String

SUGGEST_COLUMN_IS_LIVE

建議光标的列名。 可選的。 如果您的内容是媒體類型,您應該提供此列,以指定您的内容是否是實況媒體,如直播視訊或現場音頻。 列中的值為整型,值為0表示非實時内容,或1表示實時内容。

String

SUGGEST_COLUMN_LAST_ACCESS_HINT

建議光标的列名。 可選的。 當在結果提供應用程式中上次通路項目時,此列可用于指定System.currentTImeMillis()(UTC的停留時間)中的時間。 如果設定,這可以用于顯示最近使用的項目。

String

SUGGEST_COLUMN_PRODUCTION_YEAR

建議光标的列名。 可選的。 如果您的内容是視訊或音頻,并且具有已知的制作年份,則應提供此列以指定内容的制作年份。 列中的資料是整數類型。

String

SUGGEST_COLUMN_PURCHASE_PRICE

建議光标的列名。 可選的。 如果您的内容是可購買的,您應該提供此列以指定您的内容的購買價格的可顯示字元串表示,包括貨币和金額。 如果它是免費的,你應該提供本地化的字元串來指定它是免費的。 如果内容不适用于購買,則可以省略此列。

String

SUGGEST_COLUMN_QUERY

建議光标的列名。 如果操作為ACTION_SEARCH,則為必需,否則為可選項。 如果此列存在,并且此元素存在于給定行,則這是在形成建議的查詢時将使用的資料。

String

SUGGEST_COLUMN_RATING_SCORE

建議光标的列名。 可選的。 如果您的内容有評分,您應該提供此列來指定内容的評分。 列中的資料為浮動類型。 檢視每個評分風格的有效評分分數。

String

SUGGEST_COLUMN_RATING_STYLE

建議光标的列名。 可選的。 如果您的内容有評分,您應該提供此列以指定内容的評分風格。 列中的資料必須是“評級”中指定的常量值之一

String

SUGGEST_COLUMN_RENTAL_PRICE

建議光标的列名。 可選的。 如果您的内容可以租用,您應該提供此列,以指定您的内容的租金價格的可顯示字元串表示,包括貨币和金額。 如果它是免費的,你應該提供本地化的字元串來指定它是免費的。 如果内容不适用于租金,則可以省略此列。

String

SUGGEST_COLUMN_RESULT_CARD_IMAGE

建議光标的列名。 可選的。 如果您的光标包含此列,則在形成建議時将顯示圖像。 圖像的建議尺寸為肖像模式為270x400像素,橫向模式為400x225像素。 列中的資料必須是可繪制的資源ID,或以下列格式之一的URI:

String

SUGGEST_COLUMN_SHORTCUT_ID

建議光标的列名。 可選的。 該列用于訓示搜尋建議是否應作為快捷方式存儲,以及是否應該重新整理。 如果缺少,結果将被存儲為快捷方式,從不驗證。 如果設定為SUGGEST_NEVER_MAKE_SHORTCUT,則不會将結果存儲為快捷方式。 否則,快捷方式ID将用于使用SUGGEST_URI_PATH_SHORTCUT來檢查最新的建議。

String

SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING

建議光标的列名。 可選的。 此列用于指定在重新整理此建議的快捷方式時,顯示微調框代替圖示2。

String

SUGGEST_COLUMN_TEXT_1

建議光标的列名。 需要。 這是送出給使用者的主要文本行。

String

SUGGEST_COLUMN_TEXT_2

建議光标的列名。 可選的。 如果您的光标包含此列,則所有建議将以兩行格式提供。 第二行文字的外觀要小得多。

String

SUGGEST_COLUMN_TEXT_2_URL

建議光标的列名。 可選的。 這是一個顯示為第二行文字而不是SUGGEST_COLUMN_TEXT_2的網址。 這是一個單獨的列,以便搜尋UI知道将文本顯示為URL,例如。 通過使用不同的顔色。 如果此列不存在,或者值為null,則使用SUGGEST_COLUMN_TEXT_2。

String

SUGGEST_COLUMN_VIDEO_HEIGHT

建議光标的列名。 可選的。 如果您的内容是視訊,則應提供此列以指定水準線數。 列中的資料是整數類型。

String

SUGGEST_COLUMN_VIDEO_WIDTH

建議光标的列名。 可選的。 如果您的内容是視訊,則應提供此列以指定垂直線數。 列中的資料是整數類型。

常用關鍵字:

SUGGEST_COLUMN_TEXT_1

SUGGEST_COLUMN_TEXT_2

SUGGEST_COLUMN_ICON_1

SUGGEST_COLUMN_ICON_2

SUGGEST_COLUMN_TEXT_2_URL,

驗證中。。

SUGGEST_COLUMN_RESULT_CARD_IMAGE 顯示建議為image

SUGGEST_COLUMN_IS_LIVE 顯示建議為媒體類型(視訊/音頻)

android對外提供全局搜尋功能

SUGGEST_COLUMN_INTENT_ACTION

:建議光标的列名。可選的。如果此列存在,并且此元素存在于給定行,則這是在形成建議意圖時将使用的操作。如果未提供該元素,則該操作将從您的XML中繼資料中的android:searchSuggestIntentAction字段擷取。這些建議中至少有一個必須存在以産生意圖。注意:如果您的操作對于所有建議相同,則使用XML中繼資料指定它并從光标中省略更為有效。

CURSOR_EXTRA_KEY_IN_PROGRESS

:建議提供者在getExtras()中傳回的Boolean額外資料鍵,表示搜尋尚未完成。 搜尋使用者界面可以使用它來訓示正在進行搜尋。 建議提供者可以通過這種方式傳回部分結果,并在更多結果可用時向遊标發送更改通知。

QUERY

:意圖額外的資料密鑰:使用此鍵與content.Intent.getStringExtra()從Intent.ACTION_SEARCH擷取查詢字元串。