📜 ⬆️ ⬇️

Use Android Search Dialog. Part 2 - Recent Query Suggestions

image

The article is recommended to read those who mastered the first part . The article explains how to modify your application so that tips on recent search queries are added to the dialog. To understand the code and theory (in addition to the one required in the first part) requires knowledge of content providers. It can be learned from the official guide .


')

A bit of theory


In fact, prompts for recent search queries are simply saved queries. When the user selects one of the prompts, the Activity that is responsible for the search receives an Search-type Intent with a prompt as the string it has already processed. Search Manager is responsible for displaying prompts, as well as for the entire dialogue, and the content provider is used for storage.

When the Search Manager defines our Activity as responsible for the search and provides hints to the search, the following sequence of actions occurs:
  1. When Search Manager receives the text of a search request, it sends its request to the content provider that provides hints.
  2. The content provider returns a cursor pointing to prompts that match the text of the search query.
  3. Search Manager displays tooltips using the cursor.

After the hint list has been displayed, the following may occur:

So, to implement the tips, we need the following:

We create content provider


All that is required of us is the content provider, which is the successor of the class SearchRecentSuggestionsProvider . This class practically does all the actions for the developer and all that is required of us is to write a constructor.

File SuggestionProvider.java
package com.example.search;

import android.content.SearchRecentSuggestionsProvider;

public class SuggestionProvider extends SearchRecentSuggestionsProvider {
public final static String AUTHORITY = "com.example.search.SuggestionProvider" ;
public final static int MODE = DATABASE_MODE_QUERIES;

public SuggestionProvider() {
setupSuggestions(AUTHORITY, MODE);
}
}


* This source code was highlighted with Source Code Highlighter .

The setupSuggestions () method is passed an authorization string and the mode of the content provider database. The authorization string can be any, the only requirement is uniqueness. However, the official documentation recommends using the full name of the content provider, including the package name. The database operation mode must include DATABASE_MODE_QUERIES , or you can optionally add DATABASE_MODE_2LINES . In the second case, a column is added to the table of hints, allowing the second line to be displayed for each hint. It will look like this in the code:
public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;

* This source code was highlighted with Source Code Highlighter .

Now do not forget that you need to declare our content provider in the manifest.

AndroidManifest.xml file
<? xml version ="1.0" encoding ="utf-8" ? >
< manifest xmlns:android ="http://schemas.android.com/apk/res/android"
package ="com.example.search"
android:versionCode ="1"
android:versionName ="1.0" >
< application android:icon ="@drawable/icon" android:label ="@string/app_name" >
< activity android:name =".Main"
android:label ="@string/app_name" >
< intent-filter >
< action android:name ="android.intent.action.MAIN" />
< category android:name ="android.intent.category.LAUNCHER" />
</ intent-filter >
< intent-filter >
< action android:name ="android.intent.action.SEARCH" />
</ intent-filter >
< meta-data
android:name ="android.app.searchable"
android:resource ="@xml/searchable"
/>
</ activity >
< provider android:name =".SuggestionProvider"
android:authorities ="com.example.search.SuggestionProvider" />
</ application >
< uses-sdk android:minSdkVersion ="5" />

</ manifest >


* This source code was highlighted with Source Code Highlighter .


Change configuration file



In order for the dialog to use our content provider for prompts, you need to add the parameters android: searchSuggestAuthority and android: searchSuggestSelection

File searchable.xml
<? 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:searchSuggestAuthority ="com.example.search.SuggestionProvider"
android:searchSuggestSelection =" ?" >
</ searchable >


* This source code was highlighted with Source Code Highlighter .

The value of the android: searchSuggestAuthority parameter must fully match the authorization string of the content provider.
The value of the parameter android: searchSuggestSelection must be a question mark, put after the space, because this is the database selection argument and the question mark is automatically replaced with the text entered by the user.

Change Activity



All we need is to save the query text, for this an instance of the SearchRecentSuggestions class is created and the saveRecentQuery () method is called . This happens every time an Intent comes to the Activity with a request to search for data. Two parameters are passed to the saveRecentQuery () method, the first is mandatory and is a search query string, the second is optional, required if you use DATABASE_MODE_2LINES to display the second line of text in the tooltip.

The official documentation recommends also providing an interface for clearing the entire table of hints. Apparently, this is necessary to ensure user's privacy. We will simply add another menu item, which, when clicked, will clear the entire query history.

Main.java file
package com.example.search;

import android.app.ListActivity;
import android.app.SearchManager;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.SearchRecentSuggestions;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SimpleCursorAdapter;

public class Main extends ListActivity {
private EditText text;
private Button add;
private RecordsDbHelper mDbHelper;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//
mDbHelper = new RecordsDbHelper( this );
//
mDbHelper.open();
// Intent
Intent intent = getIntent();
// Intent
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
//
String query = intent.getStringExtra(SearchManager.QUERY);
// SearchRecentSuggestions
SearchRecentSuggestions suggestions = new SearchRecentSuggestions( this ,
SuggestionProvider.AUTHORITY, SuggestionProvider.MODE);
//
suggestions.saveRecentQuery(query, null );
//
showResults(query);
}

add = (Button) findViewById(R.id.add);
text = (EditText) findViewById(R.id.text);
add.setOnClickListener( new View.OnClickListener() {
public void onClick(View view) {
String data = text.getText().toString();
if (!data.equals( "" )) {
saveTask(data);
text.setText( "" );
}
}
});
}

private void saveTask( String data) {
mDbHelper.createRecord(data);
}

private void showResults( String query) {
//
Cursor cursor = mDbHelper.fetchRecordsByQuery(query);
startManagingCursor(cursor);
String [] from = new String [] { RecordsDbHelper.KEY_DATA };
int [] to = new int [] { R.id.text1 };

SimpleCursorAdapter records = new SimpleCursorAdapter( this ,
R.layout.record, cursor, from , to);
//
setListAdapter(records);
}
// ( res/menu/main_menu.xml)
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true ;
}

public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.search_record:
//
onSearchRequested();
return true ;
case R.id.clear_recent_suggestions:
//
SearchRecentSuggestions suggestions = new SearchRecentSuggestions( this ,
SuggestionProvider.AUTHORITY, SuggestionProvider.MODE);
suggestions.clearHistory();
return true ;
default :
return super.onOptionsItemSelected(item);
}
}
}


* This source code was highlighted with Source Code Highlighter .


Conclusion

This article was written using developer.android.com documentation.
The whole modified project lies on code.google.com

Source: https://habr.com/ru/post/111493/


All Articles