English | Site Directory

Android - An Open Handset Alliance Project

android.app
public class

android.app.SearchManager

java.lang.Object
android.app.SearchManager

This class provides access to the system search services. This documentation is provided as part of an early-look SDK release. All information provided is undergoing active development and may change in upcoming releases.

In practice, you won't interact with this class directly, as search services are provided through methods in Activity methods and the the SEARCH_ACTION Intent. This class does provide a basic overview of search services and how to integrate them with your activities. If you do require direct access to the Search Manager, do not instantiate this class directly; instead, retrieve it through context.getSystemService(ApplicationContext.SEARCH_SERVICE).

Topics covered here:

  1. Developer Guide
  2. How Search Is Invoked
  3. Query-Search Applications
  4. Filter-Search Applications
  5. Searchability Metadata
  6. Passing Search Context

Developer Guide

The ability to search for user, system, or network based data is considered to be a core user-level feature of the android platform. At any time, the user should be able to use a familiar command, button, or keystroke to invoke search, and the user should be able to search any data which is available to them. The goal is to make search appear to the user as a seamless, system-wide feature.

In terms of implementation, there are three broad classes of Applications:

  1. Applications that are not inherently searchable
  2. Query-Search Applications
  3. Filter-Search Applications

These categories, as well as related topics, are discussed in the sections below.

Even if your application is not searchable, it should support the invocation of search. Please review the section How Search Is Invoked for more information on how to support this.

Many applications are searchable. These are the applications which can convert a query string into a list of results. Within this subset, applications can be grouped loosely into two families:

  • Query Search applications perform batch-mode searches - each query string is converted to a list of results.
  • Filter Search applications provide live filter-as-you-type searches.

Generally speaking, you would use query search for network-based data, and filter search for local data, but this is not a hard requirement and applications are free to use the model that fits them best (or invent a new model).

It should be clear that the search implementation decouples "search invocation" from "searchable". This satisfies the goal of making search appear to be "universal". The user should be able to launch any search from almost any context.

How Search Is Invoked

Unless impossible or truly inapplicable, all applications should support invoking the search UI. This means that when the user invokes the search command, a search UI will be presented to them. The search command is currently defined as menu+S, but policy and localization issues are undergoing further design and review. You should expect this to change in an upcoming release.

In general this is implemented by your activity, or the Activity base class, which captures the search command and invokes the Search Manager to display and operate the search UI. You can also cause the search UI to be presented in response to user keystrokes in your activity (for example, to instantly start filter searching while viewing a list and typing any key).

The search UI is presented as a floating window and does not cause any change in the activity stack. If the user cancels search, the previous activity re-emerges. If the user launches a search, this will be done by sending a search Intent (see below), and the normal intent-handling sequence will take place (your activity will pause, etc.)

What you need to do: First, you should consider the way in which you want to handle invoking search. There are four broad (and partially overlapping) categories for you to choose from.

  • You can do nothing. In this case, whenever the user invokes the search command, the Activity base class will capture it and activate the Search UI. For many applications, this is sufficient and you can stop here.
  • You can capture the search command yourself - for example, by including a search button or menu item - and invoking the search UI yourself.
  • You can provide a type-to-search feature, in which search is invoked automatically when the user enters any characters.
  • You can disable search entirely. This should only be used in very rare circumstances, as search is a system-wide feature and users will expect it to be available in all contexts.

How to invoke search directly. In order to invoke search directly, from a button or menu item, you can launch a generic search by calling onSearchRequested as shown:

 onSearchRequested();

How to implement type-to-search. While setting up your activity, call setDefaultKeyMode:

 setDefaultKeyMode(SEARCH_DEFAULT_KEYS);

How to disable search from your activity. search is a system-wide feature and users will expect it to be available in all contexts. If your UI design absolutely precludes launching search, override onSearchRequested as shown:

 @override
 public boolean onSearchRequested() {
    return false;
 }

Query-Search Applications

Query-search applications are those that take a single query (e.g. a search string) and present a set of results that may fit. Primary examples include web queries, map lookups, or email searches (with the common thread being network query dispatch). It may also be the case that certain local searches are treated this way. It's up to the application to decide.

What you need to do: The following steps are necessary in order to implement query search.

  • Implement search invocation as described above. (Strictly speaking, these are decoupled, but it would make little sense to be "searchable" but not "search-invoking".)
  • Your application should have an activity that takes a search string and converts it to a list of results. This could be your primary display activity or it could be a dedicated search results activity. This is your searchable activity and every query-search application must have one.
  • In the searchable activity, in onCreate(), you must receive and handle the SEARCH_ACTION Intent. The text to search (query string) for is provided by calling getStringExtra(SearchManager.QUERY).
  • To identify and support your searchable activity, you'll need to provide an XML file providing searchability configuration parameters, a reference to that in your searchable activity's manifest entry, and an intent-filter declaring that you can receive SEARCH_ACTION intents. This is described in more detail in the Searchability Metadata section.
  • Finally, all other (non-searchable) activities should provide a single metadata entry referencing the searchable activity. This is the "glue" that causes the search UI, when invoked from any of your activities, to link back to your search results. This is described in more detail in the Searchability Metadata section.
  • Finally, you may want to define your search results activity as with the singleTop launchMode flag. This allows the system to launch searches from/to the same activity without creating a pile of them on the activity stack. If you do this, be sure to also override onNewIntent to handle the updated intents (with new queries) as they arrive.

Code snippet showing handling of intents in your search activity:

 @Override
 protected void onCreate(Bundle icicle) {
     super.onCreate(icicle);
     
     final Intent queryIntent = getIntent();
     final String queryAction = queryIntent.getAction();
     if (Intent.SEARCH_ACTION.equals(queryAction)) {
         doSearchWithIntent(queryIntent);
     }
 }
 
 private void doSearchWithIntent(final Intent queryIntent) {
     final String queryString = queryIntent.getStringExtra(SearchManager.QUERY);
     doSearchWithQuery(queryString);
 }

Filter-Search Applications

Filter-search applications are those that use live text entry (e.g. keystrokes)) to display and continously update a list of results. Primary examples include applications that use locally-stored data.

Documentation regarding Filter-Search Applications is provided as part of an early-look SDK release. All information provided is undergoing active development and will change in upcoming releases.

What you need to do: The following steps are necessary in order to implement filter search.

  • Implement search invocation as described above. (Strictly speaking, these are decoupled, but it would make little sense to be "searchable" but not "search-invoking".)
  • Implement query-search support. Even though you will support live filtering within your own searchable activity, you will also need to support the initial query that may be sent from another context. As described above, you'll need to:
    • Provide searchable activity.
    • Handle the incoming SEARCH_ACTION Intent in onCreate().
    • Provide an XML file and manifest attributes for your searchable activity.
    • Provide manifest attributes for your other activities.
    • If appropriate, mark your searchable activity with the singleTop launchMode flag.
  • To enable filter search, add filter search attributes to your searchable activity's XML configuration file. You must define android:searchFilterMode="true", and you may also wish to define android:searchFilterModePackageQuickStart="true".
  • You will receive a new SEARCH_ACTION Intent each time the user enters or changes the search text. You must receive and handle these new intents by overriding onNewIntent.
  • The search UI will overlay the upper portion of your search results display activity. You may need to adjust your layout to allow for this.

Searchability Metadata

Every activity that is searchable must provide a small amount of additional information in order to properly configure the search system. This controls the way that your search is presented to the user, and controls for the various modalities described previously.

If your application is not searchable - it does not implement query search or filter search - then you do not need to provide any search metadata, and you can skip the rest of this section. When this search metadata cannot be found, the search manager will assume that the activity does not implement search, and default search configurations will be used.

Metadata for searchable activity. As with your search implementations described above, you must first identify which of your activities is searchable. In the manifest entry for this activity, you must provide two elements:

  • An intent-filter specifying that you can receive and process the SEARCH_ACTION Intent.
  • A reference to a small XML file (typically called "searchable.xml") which contains the remaining configuration information for how your application implements search.

Here is a snippet showing the necessary elements in the manifest entry for your searchable activity.

        <!-- Search Activity - searchable -->
        <activity android:name="MySearchActivity" 
                  android:label="Search"
                  android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <meta-data android:name="android.app.searchable" 
                       android:resource="@xml/searchable" />
        </activity>

Next, you must provide the rest of the searchability configuration in the small XML file, stored in the ../xml/ folder in your build. The XML file is a simple enumeration of the search configuration parameters for searching within this activity, application, or package. Here is a sample XML file (named searchable.xml, for use with the above manifest) for a query-search activity.

 <searchable xmlns:android="http://schemas.android.com/apk/res/android"
     android:searchLabel="My App"
     android:searchHint="My Hint" />

Elements you can place in search metadata:

  • android:searchLabel is the simple name for your application that will be presented to the user in a list of search targets. This should be fairly concise as it will need to fit in a button. Required attribute.
  • android:searchHint is the text to display in the search text field when no user text has been entered. Required attribute.
  • android:searchFilterMode if true, your activity supports filter-mode search. Optional attribute.
  • android:searchFilterModePackageQuickStart if true, your activity requests a quick-start for filter searches, and they will begin as soon as the user types the first key. Optional attribute.

Note: All user facing strings are typically implemented using @strings syntax, but that feature is not implemented in this release. The examples (and your code) are presented for using simple text.

Metadata for non-searchable activities. Activities which are part of a searchable application, but don't implement search itself, require a bit of "glue" in order to cause them to invoke search using your searchable activity as their primary context. If this is not provided, then searches from these activities will use the system default search context.

In order to specify the search context, simply add a search reference element to the activity entries in the manifest file. The value of this reference is the name of your searchable activity. It is typically prefixed by '.' to indicate that it's in the same package.

Here is a snippet showing the necessary addition to the manifest entry for your non-searchable activities.

        <!-- OtherActivity - activity that refers to the searchable activity -->
        <activity android:name="OtherActivity" 
                  android:label="Other">
            <meta-data android:name="android.app.default_searchable"
                       android:value=".MySearchActivity" />
        </activity>

Passing Search Context

In order to improve search experience, an application may wish to specify additional data along with the search, such as local history or context. For example, a maps search would be improved by including the current location. In order to simplify the structure of your activities, this can be done using the search manager.

Any data can be provided at the time the search is launched, as long as it can be stored in a Bundle object.

To pass application data into the Search Manager, you'll need to override onSearchRequested as follows:

 @override
 public boolean onSearchRequested() {
     Bundle appData = new Bundle();
     appData.add....()
     startSearch(null, appData);
     return true;
 }

To receive application data from the Search Manager, you'll extract it from the SEARCH_ACTION Intent as follows:

 final Bundle appData = queryIntent.getBundleExtra(SearchManager.APP_DATA);
 if (appData != null) {
     extractMyBundleData(appData);
 }

Summary

Constants

      Value  
String  APP_DATA  Intent extra data key: Use this key with Intent.SEARCH_ACTION and content.Intent.getStringExtra() to obtain any additional app-specific data that was inserted by the activity that launched the search.  "app_data" 
String  QUERY  Intent extra data key: Use this key with content.Intent.getStringExtra() to obtain the query string from Intent.SEARCH_ACTION.  "query" 

Public Methods

        void  startSearch(String searchText, ComponentName launchActivity, Bundle appSearchData)
Launch search UI.
        void  stopSearch()
Terminate search UI.
Methods inherited from class java.lang.Object

Details

Constants

public static final String APP_DATA

Intent extra data key: Use this key with Intent.SEARCH_ACTION and content.Intent.getStringExtra() to obtain any additional app-specific data that was inserted by the activity that launched the search.
Constant Value: "app_data"

public static final String QUERY

Intent extra data key: Use this key with content.Intent.getStringExtra() to obtain the query string from Intent.SEARCH_ACTION.
Constant Value: "query"

Public Methods

public void startSearch(String searchText, ComponentName launchActivity, Bundle appSearchData)

Launch search UI.

The search manager will open a search widget in an overlapping window, and the underlying activity may be obscured. The search entry state will remain in effect until one of the following events:

  • The user completes the search. In most cases this will launch a search intent.
  • The user uses the back, home, or other keys to exit the search.
  • The application calls the stopSearch() method, which will hide the search window and return focus to the activity from which it was launched.
  • Most applications will not us this interface to invoke search. The primary method for invoking search is to call onSearchRequested().

    Parameters

    searchText A search string can be pre-entered here, but this is typically null or empty.
    launchActivity The ComponentName of the activity that has launched this search.
    appSearchData An application can insert application-specific context here, in order to improve quality or specificity of its own searches. This data will be returned with SEARCH intent(s). Null if no extra data is required.

public void stopSearch()

Terminate search UI.

Typically the user will terminate the search UI by launching a search or by canceling. This function allows the underlying application or activity to cancel the search prematurely (for any reason).

Build m5-rc15g - 14 May 2008 12:50