Making Application Content Searchable Android

If your application is content rich, either with content created by users or with content provided by you, the developer, then integrating with the search capabilities of Android can provide many benefits and add value to the user. The application data becomes part of the overall handset experience, is more accessible, and your application may be presented to the user in more cases than just when they launch it.

Most Android devices share a set of common hardware buttons: Home ( ICON ), Menu (ICON ), Back (ICON), and Search (ICON).Applications can implement powerful search features within their applications using the Android framework. There are two ways that search capabilities are generally added to Android applications:

  • Applications implement a search framework that enables their activities to react to the user pressing the Search button and perform searches on data within that application.
  • Applications can expose their content for use in global, system-wide searches that include application and web content.

Search framework features include the ability to search for and access application data as search results, as well as the ability to provide suggestions as the user is typing search criteria. Applications can also provide an Intent to launch when a user selects specific search suggestions.

Let’s consider the African field notes application we discussed in the previous section. This application uses a simple content provider to supply information about game animals. Enabling search support within this application seems rational; it would enable the user to quickly find information about a specific animal simply by pressing the Search button. When a result is found, the application needs to be able to apply an Intent for launching the appropriate screen to view that specific field note—the perfect time to implement a simple content type handler that enables the application to handle “view field note” actions, as shown in Figure.

Enabling Searches Within Your Application

You need to make a number of changes within your application to enable searches. Although these changes might seem complex, the good news is that if you do it right, enabling global searches later is very simple. Searching content generally necessitates that your application acts as a content provider, or at the very least has some sort of underlying database that can be searched in a systematic fashion.

Handling in-application searches and search suggestions.

Handling in-application searches and search suggestions

To enable in-application searches, you need to

  • Develop an application with data, ideally exposed as a content provider.
  • Create an XML search configuration file.
  • Implement an Activity class to handle searches.
  • Configure the application’s Android manifest file for searches.

Now let’s look at each of these requirements in more detail.

Creating a Search Configuration

Creating a search configuration for your application simply means that you need to create an XML file with special search tags. This search configuration file is normally stored in the xml resource directory (for example, /res/xml/searchable.xml) and referenced in the searchable application’s Android manifest file.

Enabling Basic Searches

The following is a sample search configuration the field notes application might use, stored as an application resource file called

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

The basic attributes of the search configuration are fairly straightforward. The label field is generally set to the name of your application (the application providing the search result).The hint field is the text that shows in the EditText control of the search box when no text has been entered—a prompt. You can further customize the search dialog by customizing the search button text and input method options, if desired.

Enabling Search Suggestions

If your application acts as a content provider and you want to enable search suggestions—those results provided in a list below the search box as the user types in search criteria—then you must include several additional attributes within your search configuration. You need to specify information about the content provider used to supply the search suggestions, including its authority, path information, and the query to use to return search suggestions. You also need to provide information for the Intent to trigger when a user clicks on a specific suggestion.

Again, let’s go back to the field notes example. Here are the search configuration attributes required in order to support search suggestions that query field note titles:

android:searchSuggestAuthority =
“com.androidbook.simplesearchintegration.SimpleFieldnotesContentProvider"
android:searchSuggestPath="fieldnotes"
android:searchSuggestSelection="fieldnotes_title LIKE ?"
android:searchSuggestIntentAction="android.intent.action.VIEW"
android:searchSuggestIntentData = “content://com.androidbook.simplesearch
integration.SimpleFieldnotesContentProvider/fieldnotes"

The first attribute, searchSuggestAuthority, sets the content provider to use for the search suggestion query. The second attribute defines the path appended to the Authority and right before SearchManager.SUGGEST_URI_PATH_QUERY is appended to the Authority, as well. The third attribute supplies the SQL WHERE clause of the search query (here, only the field note titles, not their bodies, are queried to keep search suggestion performance reasonably fast). Next, an Intent action is provided for when a user clicks a search suggestion and then finally the intent, the Uri used to launch the Intent, is defined.

You can also set a threshold (android:searchSuggestThreshold) on the number of characters the user needs to type before a search suggestion query is performed. Consider setting this value to a reasonable number like 3 or 4 characters to keep queries to a minimum (the default is 0).At a value of zero, even an empty search field shows suggestions— but these are not filtered at all.

Each time the user begins to type in search criteria, the system performs a content provider query to retrieve suggestions. Therefore, the application’s content provider interface needs to be updated to handle these queries. In order to make this all work properly, you need to define a projection in order to map the content provider data columns to those that the search framework expects to use to fill the search suggestion list with content.

For example, the following code defines a project to map the field notes unique identifiers and titles to the _ID, SUGGEST_COLUMN_TEXT_1 and SUGGEST_ COLUMN_ INTENT_ DATA_ID fields for the search suggestions:

private static final HashMap<String, String>
FIELDNOTES_SEARCH_SUGGEST_PROJECTION_MAP;
static {
FIELDNOTES_SEARCH_SUGGEST_PROJECTION_MAP =
new HashMap<String, String>();
FIELDNOTES_SEARCH_SUGGEST_PROJECTION_MAP.put(_ID, _ID);
FIELDNOTES_SEARCH_SUGGEST_PROJECTION_MAP.put(
SearchManager.SUGGEST_COLUMN_TEXT_1, FIELDNOTES_TITLE + “ AS “
+ SearchManager.SUGGEST_COLUMN_TEXT_1);
FIELDNOTES_SEARCH_SUGGEST_PROJECTION_MAP.put(
SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, _ID + “ AS “
+ SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
}

Each time search suggestions need to be displayed, the system executes a query using the Uri provided as part of the search configuration. Don’t forget to define this Uri and register it in the content provider’s UriMatcher object (using the addURI() method). For example, the field notes application used the following Uri for search suggestion queries:

content:// com.androidbook.simplesearchintegration.
SimpleFieldnotesContentProvider/fieldnotes/search_suggestion_query

By providing a special search suggestion Uri for the content provider queries, you can simply update the content provider’s query() method to handle the specialized query, including building the projection, performing the appropriate query and returning the results. Let’s take a closer look at the field notes content provider query() method:

@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(SimpleFieldnotesDatabase.FIELDNOTES_TABLE);
int match = sURIMatcher.match(uri);
switch (match) {
case FIELDNOTES_SEARCH_SUGGEST:
selectionArgs = new String[] { “%" + selectionArgs[0] + “%" };
queryBuilder.setProjectionMap(
FIELDNOTES_SEARCH_SUGGEST_PROJECTION_MAP);
break;
case FIELDNOTES:
break;
case FIELDNOTE_ITEM:
String id = uri.getLastPathSegment();
queryBuilder.appendWhere(_ID + “=" + id);
break;
default:
throw new IllegalArgumentException(“Invalid URI: “ + uri);
}
SQLiteDatabase sql = database.getReadableDatabase();
Cursor cursor =
queryBuilder.query(sql, projection, selection,
selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}

This query() method implementation handles both regular content queries and special search suggestion queries (those that come in with the search suggestion Uri).When the search suggestion query occurs,we wrap the search criteria in wildcards and use the handy setProjectionMap() method of the QueryBuilder object to set and execute the query as normal. Because we want to return results quickly,we only search for titles matching the search criteria for suggestions, not the full text of the field notes.

Enabling Voice Search

You can also add voice search capabilities to your application. This enables the user to speak the search criteria instead of type it. There are several attributes you can add to your search configuration to enable voice searches. The most important attribute is voiceSearchMode, which enables voice searches and sets the appropriate mode: The showVoiceSearchButton value enables the little voice recording button to display as part of the search dialog, the launchRecognizer value tells the Android system to use voice recording activity, and the launchWebSearch value initiates the special voice web search activity.

To add simple voice support to the field notes sample application can be done simply by adding the following line to the search configuration:

android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"

Other voice search attributes you can set include the voice language model (free form or web search), the voice language, the maximum voice results, and a text prompt for the voice recognition dialog. See the Android SDK documentation regarding Searchable Configuration searchable-config.html.

Creating a Search Activity

Next, you need to implement an Activity class that actually performs the requested searches. This Activity is launched whenever your application receives an intent with the action value of ACTION_SEARCH.

The search request contains the search string in the extra field called SearchManager. QUERY. The Activity takes this value, performs the search, and then responds with the results.

Let’s look at the search Activity from our field notes example. You can implement its search activity, SimpleSearchableActivity, as follows:

public class SimpleSearchableActivity extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
checkIntent(intent);
}
@Override
protected void onNewIntent(Intent newIntent) { // update the activity launch intent setIntent(newIntent);
// handle it
checkIntent(newIntent);
}
private void checkIntent(Intent intent) { String query = ““;
String intentAction = intent.getAction();
if (Intent.ACTION_SEARCH.equals(intentAction)) {
query = intent.getStringExtra(SearchManager.QUERY);
Toast.makeText(this,
“Search received: “ + query, Toast.LENGTH_LONG)
.show();
} else if (Intent.ACTION_VIEW.equals(intentAction)) {
// pass this off to the details view activity
Uri details = intent.getData();
Intent detailsIntent =
new Intent(Intent.ACTION_VIEW, details);
startActivity(detailsIntent);
finish();
return;
}
fillList(query);
} private void fillList(String query) {
String wildcardQuery = “%" + query + “%";
Cursor cursor =
managedQuery(
SimpleFieldnotesContentProvider.CONTENT_URI,
null,
SimpleFieldnotesContentProvider.FIELDNOTES_TITLE
+ “ LIKE ? OR “
+ SimpleFieldnotesContentProvider.FIELDNOTES_BODY
+ “ LIKE ?",
new String[] { wildcardQuery, wildcardQuery }, null);
ListAdapter adapter =
new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1, cursor,
new String[] {
SimpleFieldnotesContentProvider.FIELDNOTES_TITLE },
new int[] { android.R.id.text1 });
setListAdapter(adapter);
}
@Override
protected void onListItemClick(
ListView l, View v, int position, long id) {
Uri details = Uri.withAppendedPath( SimpleFieldnotesContentProvider.CONTENT_URI, ““ + id);
Intent intent =
new Intent(Intent.ACTION_VIEW, details);
startActivity(intent);
}
}

Both the onCreate() and onNewIntent() methods are implemented because the Activity is flagged with a launchMode set to singleTop. This Activity is capable of bringing up the search dialog when the user presses the Search button, like the rest of the activities in this example. When the user performs a search, the system launches the Simple Searchable Activity—the same activity the user was already viewing. We don’t want to create a huge stack of search result activities, so we don’t let it have more than one instance on top of the stack—thus the singleTop setting.

Handling the search is fairly straightforward. We use the search term provided for us to create a query. Using the managedQuery call, the results are obtained as a Cursor object that is then used with the SimpleCursorAdapter object to fill the ListView control of the Activity class.

For list item click handling, the implementation here simply creates a new VIEW intent and, effectively, lets the system handle the item clicking. In this case, the details activity handles the displaying of the proper field note. Why do this instead of launching the class activity directly? No reason other than it’s simple and it’s well tested from other uses of this launch style.

When a user clicks on a suggestion in the list, instead of an ACTION_SEARCH, this activity receives the usual ACTION_VIEW. Instead of handling it here, though, it’s passed on to the details view Activity as that activity is already designed to handle the drawing of the details for each item—no reason to implement it twice.

Configuring the Android Manifest File for Search

Now it’s time to register your searchable Activity class within the application manifest file, including configuring the intent filter associated with the ACTION _SEARCH action. You also need to mark your application as searchable using a <meta-data> manifest file tag.

Here is the Android manifest file excerpt for the searchable activity registration:

<activity
android:name="SimpleSearchableActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" /></intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>

The main difference between this <activity> tag configuration and a typical activity is the addition of the intent filter for intents with an action type of SEARCH. In addition, some metadata is provided so that the system knows where to find the search configuration details.

Next, let’s look at an example of how to enable the Search button for all activities within the application. This <meta-data> block needs to be added to the <application> tag, outside any <activity>tags.

<meta-data
android:name="android.app.default_searchable"
android:value =
“com.androidbook.simplesearchintegration.SimpleSearchableActivity" />

This <meta-data> tag configures the default activity that handles the search results for the entire application. This way, pressing the Search button brings up the search dialog from any activity within the application. If you don’t want this functionality in every activity, you need to add this definition to each activity for which you do want the Search button enabled.

Enabling Global Search

After you have enabled your application for searches, you can make it part of the global device search features with a few extra steps. Global searches are often invoked using the Quick Search Box. In order to enable your application for global search, you need to

  • Begin with an application that already has in-application search abilities as described earlier.
  • Update the search configuration file to enable global searches.
  • Include your application in global searches by updating the Search settings of the device.

Now let’s look at these requirements in a bit more detail. Let’s assume we’re working with the same sample application—the field notes. Figure shows the global search box, as initiated from the Home screen.

Updating a Search Configuration for Global Searches

Updating an existing search configuration is very simple. All you need to do is add the includeInGlobalSearch attribute in your configuration and set it to true as follows:

android:includeInGlobalSearch="true"

At this point, you should also ensure that your application is acting as a content type handler for the results you provide as part of global searches (if you haven’t already).That way, users can select search suggestions provided by your application. Again, you probably want to leverage the content type handler functionality again, in order to launch the application when a search suggestion is chosen.

Updating Search Settings for Global Searches

However, the user has ultimate control over what applications are included as part of the global search. Your application is not included in global searches by default. The user must include your application explicitly. In order for your application’s content to show up as part of global searches, the user must adjust the device Search settings. The user makes this configuration from the Settings, Search, Searchable Items menu, as shown in Figure.

Application content is included in global search results, such as when the user presses the search button while on the Home screen.

Application content is included in global search results, such as when the user presses the search button while on the Home screen.

If your application has content that is appropriate for global searches, you might want to include a shortcut to these settings so that users can easily navigate to them without feeling like they’ve left your application. The SearchManager class has an intent called INTENT_ACTION_SEARCH_SETTINGS for this purpose:

Intent intent = new Intent(SearchManager.INTENT_ACTION_SEARCH_SETTINGS);
startActivity(intent);

This intent launches the Settings application on the Search settings screen, as shown in Figure (left).

As you can see, searches—whether they are in-application searches or global searches— allow application content to be exposed in new and interesting ways so that the user’s data is always just a few keystrokes (or spoken words) away. But wait! There’s more! Check out the Search Dev Guide on the Android developer website to learn more about the sophisticated features available as part of the Android search framework.

Configuring device search settings to include content from your application.

Configuring device search settings to include content from your application.



Face Book Twitter Google Plus Instagram Youtube Linkedin Myspace Pinterest Soundcloud Wikipedia

All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd DMCA.com Protection Status

Android Topics