Mon

06

Jun

2011

How to add search functionality to your Android application


Figure 1: Screenshot of an application's search dialog

With data-intensive applications, the ability for users to search for information within an application is an essential feature. Fortunately, Android includes a search framework that helps developers to implement search in their applications and to create a consistent search experience for users. This blog post describes how to implement search functionality using this framework.

 

Enabling application search using the Android search framework involves the following three steps:

  1. Creating a searchable configuration
  2. Creating a searchable activity
  3. Implementing a search interface

 

 

Step 1: Creating a searchable configuration

The first thing that is needed is an XML file called the searchable configuration in the res/xml folder. This file configures various UI aspects of the search interface and defines the behavior of certain search features (e.g., voice search, search suggestions). A typical searchable configuration file might look as follows:

 

<?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">
</searchable>

 

The android:label attribute is the only required attribute and references a string resource denoting the name of the application, whereas the android:hint is a recommended attribute and specifies a hint text to display in the search box when no text has been entered. Fore more information about the searchable configuration file, see the Android Developers documentation for Searchable Configuration.     

 

 

Step 2: Creating a searchable activity

Next, an activity is needed to perform searches and to display the search results. Usually, this will be a ListView-based activity, but it is possible to use any other user interface. As shown below, inside the manifest's <activity> element, it's necessary to include an intent filter to accept the ACTION_SEARCH action as well as a <meta-data> element that includes an android:name attribute with the value android.app.searchable and an android:resource attribute with a reference to the searchable configuration file.

 

<application ... >
    <activity android:name=".SearchableActivity" >
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />

        </intent-filter>
        <meta-data android:name="android.app.searchable"
                   android:resource="@xml/searchable"/>
    </activity>
    ...

</application>

 

When a user performs a search from the search interface, the Android system starts the searchable activity, passing it an ACTION_SEARCH intent that includes the search query in the QUERY string extra. Then, when the searchable activity starts, the search query can be retrieved and processed as follows:

 

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search);

// Get the intent, verify the action and get the query
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
doMySearch(query);
}
}

 

The local doMySearch() method performs the search operation (e.g.,  by querying a local SQLite database or by submitting a request to a search web service) and finally presents all the search results to the user (e.g., by applying the results to a ListView).

 

Step 3: Implementing a search interface

The search interface can be implemented using either:

  • The search dialog

The search dialog (see Figure 1), which by default is always hidden, appears at the top of an activity when the user presses the device's SEARCH button (if available) or when the onSearchRequested() method is called. However, except for the searchable activity itself, either of these work only if one enables the search dialog for the activity. This is achieved by placing a <meta-data> element with the android:name attribute with a value of android.app.default_searchable and the android:value attribute with a reference to the searchable activity inside the respective activity's <activity> element. The example below shows the declaration for both a searchable activity (i.e., SearchableActivity) and another activity (i.e., OtherActivity) that uses SearchableActivity to handle search queries from its search dialog.

 

<application ... >
<!-- this is the searchable activity; it performs searches -->
<activity android:name=".SearchableActivity" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="@xml/searchable"/>
</activity>

<!-- this activity enables the search dialog to initiate searches
in the SearchableActivity -->
<activity android:name=".OtherActivity" ... >
<!-- enable the search dialog to send searches to SearchableActivity -->
<meta-data android:name="android.app.default_searchable"
android:value=".SearchableActivity" />
</activity>
...
</application>

 

In order to enable the search dialog for every activity in an Android application, one can add the above <meta-data> element inside the <application> element, instead of each <activity>.

 

  • Or, the search widget

The search widget, which is available in Android 3.0 and higher, is an instance of SearchView that can be placed anywhere in an activity layout. To configure the search widget, it suffices to call setSearchableInfo() and pass it the SearchableInfo object that represents the searchable configuration:

 

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// Get the SearchView and set the searchable configuration
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) findItemById(R.id.search_view);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default
}

 

 

Write a comment

Comments: 5

  • #1

    Aaron (Tuesday, 19 June 2012 19:58)

    Hello, I have did everything you said to do in this tutorial. I get no errors in either my manifest and searchable.xml. but when I launch my app, it successfully installs but no icon appears and the app is not launchable from my device. I am getting really frustrated trying to figure out how to add a search function in my app. PLEASE HELP!

  • #2

    matthias (Tuesday, 19 June 2012 20:25)

    Hi,
    most probably you didn't define a main activity (which functions as entry point to your application) in your AndroidManifest.xml file. Referring to the snippet in Step 3, this can be done as follows:

    ...
    <!-- this activity enables the search dialog to initiate searches in the SearchableActivity -->
    <activity android:name=".OtherActivity">
    <!-- enable the search dialog to send searches to SearchableActivity -->
    <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <meta-data android:name="android.app.default_searchable" android:value=".SearchableActivity" />
    </activity>
    ...

    This should do the trick...

  • #3

    Aaron (Wednesday, 20 June 2012 04:28)

    Hi,
    thank you for the reply. I pasted my manifest below. Maybe you can let me know where I went wrong?


    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.idevi.ccanada"
    android:versionCode="1"
    android:versionName="1.0" >


    <uses-sdk android:minSdkVersion="7" />
    <supports-screens
    android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:resizeable="true"
    android:anyDensity="true" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"

    />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"

    />
    <uses-permission

    android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"

    />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"

    />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
    <application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
    android:name=".CriminalCodeofCanadaActivity"
    android:label="@string/app_name" >

    android:configChanges="orientation|keyboardHidden"
    <activity android:name=".SearchableActivity" >
    <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <action android:name="android.intent.action.SEARCH" />

    <category android:name="android.intent.category.LAUNCHER"

    />

    </intent-filter>
    <meta-data android:name="android.app.searchable"
    android:resource="@xml/searchable" />
    </activity>
    </activity>
    </application>

    </manifest>

    and my searchable.xml file, which always comes up with errors:

    <?xml version="1.0" encoding="utf-8"?>
    <searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_label"
    android:hint="Search in your_application_name" >
    </searchable>

    Thank you!


  • #4

    matthias (Thursday, 21 June 2012 17:33)

    Having a fast look at your AndroidManifest.xml file, I see 2 errors:
    1) SearchableActivity is nested inside CriminalCodeofCanadaActivity. This should become:
    ...
    <activity
    android:name=".CriminalCodeofCanadaActivity"
    android:label="@string/app_name" android:configChanges="orientation|keyboardHidden">
    <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <meta-data android:name="android.app.default_searchable" android:value=".SearchableActivity" />
    </activity>

    <activity android:name=".SearchableActivity" >
    <intent-filter>
    <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    <meta-data android:name="android.app.searchable" android:resource="@xml/searchable"/>
    </activity>
    ...
    2) The attribute value of android:hint inside your searchable.xml file must be a string resource (i.e., defined in your strings.xml file)

  • #5

    Aaron (Thursday, 21 June 2012 23:51)

    Thank you very much! No errors and my app launches again! Couldn't have done it without you! THANK YOU! , now I just have to figure out how to launch the search in my app.

  • loading



StatCounter
About | Privacy Policy | Print Version | Sitemap | Recommend this site!
© Matthias Braunhofer. All rights reserved