Adding Search to your Android app

In the last few years, Google has helped us become very lazy. So lazy that people would rather type in CNN in the Google search box and then click the top search result link than type www.cnn.com directly in the browser. Searching for information (which was considered an art in the pre-Internet days) is now taken for granted. Considering that computers have slowly but steadily become better and faster at finding relevant information, it is no surprise that people simply let their computers 'remember' for them. This according to some scientists is 'augmented memory'.

The ability to search is therefore a common fixture in most software applications of daily use today. For the last few weeks, at Azeem Technologies, we have been developing a custom Android app for a doctor and I was recently told to implement the search feature. This would allow the doctor to easily search patients, their contact information and digitized version of their history. Initially, I was quite apprehensive about implementing search, but after reading a few online articles and devoting some thought, a skeleton solution was designed and implemented within a day. That soon? Yes, the Android framework provides a framework pattern that makes it very easy to do so.

The design process is as follows:

  1. Get the Search icon from the Android icon pack (yes, the same one that looks like a bygone era Sherlock Holmes magnifying glass) and add it to the /res/drawable folder
  2. Create a /res/xml/searchable.xml
  3. Add menu entry for search in the appropriate activities.
  4. Create a new activity that will display the search results (usually this will subclass ListActivity as the results will be returned as a list)
  5. Update the Android manifest for the search capability

The more specific instructions along with explanations are available at Android Documentation, Android training, Search using ArrayAdaptors and a Youtube video. In total however, excluding the search logic, the total number of lines of code barely exceeds 40. Here are the changes I had to make in our app.

  1. Create a searchable.xml file in res/xml folder with the contents
        <?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:inputType="textAutoCorrect|textAutoComplete"
             android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" >
        </searchable>
        
  2. Update the Android manifest file
         <application
            android:allowBackup="true"
            .....   >
            <!-- all app searches handled by same activity -->
            <meta-data android:name="android.app.default_searchable"
                       android:value=".SearchActivity" 
            />
            .....
            .....
            <activity
                android:name=".SearchActivity"
                android:label="@string/search_results"
                android:screenOrientation="portrait"
                android:launchMode="singleTop" >
            	<intent-filter>
            		<action android:name="android.intent.action.SEARCH" />
        		</intent-filter>
                <meta-data 
                    android:name="android.app.searchable"
                	android:resource="@xml/searchable" />    	            
            </activity>
          </application>
         
  3. Update the activity in which search button is to be available. You should have already updated the menu xml resource with the search item and its icon. Usually, the search icon resides on the Action Bar.
        public class PatientListActivity extends ListActivity {
           .....
           @Override
    	public boolean onCreateOptionsMenu(Menu menu) {
                super.onCreateOptionsMenu(menu);
    
                //create a MenuInflater to help use the menu that we already made in XML
    	    MenuInflater inflater = getMenuInflater();
    
                //inflate this menu with the XML resource that was created earlier	
    	    inflater.inflate(R.menu.menu_patient_list, menu);
    
    	    // Associate searchable configuration with the SearchView		
    	    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    	    SearchView searchView = (SearchView) menu.findItem(R.id.action_search_patient).getActionView();
    	    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    	    searchView.setIconifiedByDefault(false); 
    
                //allow method to be displayed
    	    return true;
    	}
      
  4. Create the search activity and implement the search logic.
         public class SearchActivity extends ListActivity {
    	private Context mContext;
    	private static final String LOG_TAG = SearchActivity.class.getSimpleName();
    
    	@Override
            public void onCreate(Bundle savedInstanceState) {
               super.onCreate(savedInstanceState);
               mContext = this;
               setContentView(R.layout.activity_search_results);
           
               // retrieve the search query from the Intent
               Intent intent = getIntent();
               String searchString;        
               if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
                  searchString = intent.getStringExtra(SearchManager.QUERY);
               }
    
               // now call the code the implements the search logic
               generateSearchResults(searchString);
            } 
    
            ....
         } // end of class
    
       
    
and that's pretty much it!

Every time, the user searches for someone or something in PatientListActivity, the Android framework takes that search term, that string and passes control to SearchActivity along with the string. Then its upto you to decide how to use that search term.