Implementing Search activities
Most Android phones have a search button. this button is used to search contacts,applications or anything on the phone. We can make use of the search functionality in our apps.
In this post we're going to see how to implement search functionality to search for entries stored in a databaseand display them in a ListView.
In this post we're going to see how to implement search functionality to search for entries stored in a databaseand display them in a ListView.
Creating database:
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) {
super(context, "DemoDB", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
StringBuilder builder=new StringBuilder();
// countries table
builder.append("CREATE TABLE Countries ");
builder.append("(_id INTEGER PRIMARY KEY AUTOINCREMENT,");
builder.append("NAME TEXT) ");
db.execSQL(builder.toString());
// Names table
// Virtual table for full text search
builder.setLength(0);
builder.append("CREATE VIRTUAL TABLE NAMES USING FTS3");
builder.append("(");
builder.append("name TEXT) ");
db.execSQL(builder.toString());
builder=new StringBuilder();
//dummy data
InsertData(db);
}
void InsertData(SQLiteDatabase db)
{
ContentValues cv=new ContentValues();
cv.put("NAME","USA");
db.insert("Countries", "NAME", cv);
cv.put("NAME","UK");
db.insert("Countries", "NAME", cv);
cv.put("NAME","Spain");
db.insert("Countries", "NAME", cv);
cv.put("NAME","ITALY");
db.insert("Countries", "NAME", cv);
cv.put("NAME","Germany");
db.insert("Countries", "NAME", cv);
cv=new ContentValues();
cv.put("name","John");
db.insert("NAMES", "name", cv);
cv.put("name","Jack");
db.insert("NAMES", "name", cv);
cv.put("name","Ann");
db.insert("NAMES", "name", cv);
cv.put("name","Adam");
db.insert("NAMES", "name", cv);
cv.put("name","Sarah");
db.insert("NAMES", "name", cv);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
/**
* Return all countries
* @return
*/
public ArrayListgetCountries(){
ArrayList countries=new ArrayList();
SQLiteDatabase db=this.getReadableDatabase();
Cursor c=db.rawQuery("select * from Countries", null);
while(c.moveToNext()){
String country=c.getString(1);
countries.add(country);
}
c.close();
return countries;
}
/**
* Return all names
* @return
*/
public ArrayListgetNames(){
ArrayList names=new ArrayList();
Cursor c=this.getReadableDatabase().rawQuery("select * FROM Names", null);
while(c.moveToNext()){
String name=c.getString(0);
names.add(name);
}
c.close();
return names;
}
/**
* Return all countries based on a search string
* @return
*/
public ArrayListgetCountriesSearch(String query){
ArrayList countries=new ArrayList();
SQLiteDatabase db=this.getReadableDatabase();
Cursor c=db.rawQuery("select * from Countries where NAME LIKE '%"+query+"%'", null);
while(c.moveToNext()){
String country=c.getString(1);
countries.add(country);
}
c.close();
return countries;
}
/**
* Return all names based on a search string
* we use the MATCH keyword to make use of the full text search
* @return
*/
public ArrayListgetNamesSearch(String query){
ArrayList names=new ArrayList();
Cursor c=this.getReadableDatabase().rawQuery("select * FROM Names WHERE name MATCH '"+query+"'", null);
while(c.moveToNext()){
String name=c.getString(0);
names.add(name);
}
c.close();
return names;
}
Implementing The activity:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/list"/>
</LinearLayout>
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
list=(ListView)findViewById(R.id.list);
DBHelper helper=new DBHelper(this);
ArrayList items=helper.getNames();
ArrayAdapter adapter=new ArrayAdapter(this, android.R.layout.simple_list_item_1,items);
list.setAdapter(adapter);
}
Handling the search dialog:
<?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/hint" >
</searchable>
then we need to add an Intent Filter in out app's AndroidManifest.xml file to our activity to handle the search dialog:
<activity android:name=".MainActivty"
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>
Understanding the Search process:
when you press the search button, type some text and click on search the activit's onSearchRequested() function is called, then an Intent with the action Intent.ACTION_SEARCH is created and you activity is re-created with this intent.
the search intent has you search string as a string extra with the name SearchManager.QUERY. also it can carry a bundle of other extras with the name SearchManager.APP_DATA.
what if the device doesn't have a Search button:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add("Search").setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
//launch the search dialog
onSearchRequested();
return true;
}
});
return true;
}
Adding extras to the search dialog:
@Override
public boolean onSearchRequested() {
Bundle bundle=new Bundle();
bundle.putString("extra", "exttra info");
// search initial query
startSearch("Country", false, bundle, false);
return true;
}
Handling the search query:
we said before that the search query is passed as a String extra when our activity is re-created. so we can handle the searcgh string in our onCreate() like this:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
list=(ListView)findViewById(R.id.list);
DBHelper helper=new DBHelper(this);
Intent intent=getIntent();
// if the activity is created from search
if(intent.getAction().equals(Intent.ACTION_SEARCH)){
// get search query
String query=intent.getStringExtra(SearchManager.QUERY);
ArrayList items=helper.getNamesSearch(query);
//get extras, just for demonstration
Bundle bundle=intent.getBundleExtra(SearchManager.APP_DATA);
String info=bundle.getString("extra");
Log.v("extra", info);
//bind the list
ArrayAdapter adapter=new ArrayAdapter(this, android.R.layout.simple_list_item_1,items);
list.setAdapter(adapter);
}
//activity created normally
else{
ArrayList items=helper.getNames();
ArrayAdapter adapter=new ArrayAdapter(this, android.R.layout.simple_list_item_1,items);
list.setAdapter(adapter);
}
helper.close();
}
we just extract the search string and any other extras and perform our search logic based on the search string.
and that's was all about implementing search
No comments: