I'm having trouble setting up the search view in the action bar.
I followed the developer site, but it doesn't work. I get the feeling that I am missing something.
When I run my code, it always outputs "failed to get searchable info" (MainActivity.setupSearchView()).
MainActivity.java
// package...
// imports...
public class MainActivity extends Activity {
private static String tag = "Main Activity";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater mi = getMenuInflater();
mi.inflate(R.menu.search_view, menu);
setupSearchView(menu);
return true;
}
private void setupSearchView(Menu menu) {
SearchManager sm = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchableInfo si = sm.getSearchableInfo(getComponentName());
if (si == null) {
Log.wtf(tag, "failed to get searchable info");
return;
}
SearchView sv = (SearchView) menu.findItem(R.id.menu_search).getActionView();
sv.setSearchableInfo(si);
// Do not iconify the widget; expand it by default
sv.setIconifiedByDefault(false);
}
}
SearchResultsActivity.java
// package...
// imports...
public class SearchResultsActivity extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Intent queryIntent = getIntent();
doSearchQuery(queryIntent);
}
#Override
public void onNewIntent(final Intent newIntent) {
super.onNewIntent(newIntent);
final Intent queryIntent = getIntent();
doSearchQuery(queryIntent);
}
}
searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="#string/search_hint"
android:label="#string/search_label" >
</searchable>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="kpaek.examples"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".search.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SearchResultsActivity">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
</application>
</manifest>
The key thing I found is that searchable.xml must not contain literal strings, only resources. I wasted about half a day on that one, since it causes getSearchableInfo to fail silently.
In my case using custom tags in res/menu/mymenu.xml worked for me:
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"
Do not use:
android:showAsAction="ifRoom|collapseActionView"
android:actionViewClass="android.support.v7.widget.SearchView"
I have found that the intent-filter and the meta-data elements must be included in the manifest activity element from which the search is initiated (MainActivity having a SearchView) for the method getSearchableInfo(getComponentName()) to return the correct configuration and not null.
<activity
android:name=".MainActivity"
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>
I wonder if instead (and the solution I am going with for now) one should leave the intent and meta-data on the results activity declaration and change the argument to getSearchableInfo() as follows:
<activity android:name=".SearchResultsActivity">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
And the changes to MainActivity (note the assignment statement for searchableInfo):
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_search, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView mySearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
SearchableInfo searchableInfo = searchManager.getSearchableInfo(new ComponentName(getApplicationContext(), SearchResultsActivity.class));
mySearchView.setSearchableInfo(searchableInfo);
return true;
}
This killed me for a day - I thought it was ActionBarSherlock-related, but no it works fine with that.
The problem was that I was trying to short-circuit the sample. At least one of your activities - the one you're doing the searching from is sufficient - must have this intent-filter in it in the manifest:
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
If not, then searchManager.getSearchableInfo(getComponentName()) always returns null, and your configuration is ignored.
From the developersite:
A searchable configuration defines how the SearchView behaves and is
defined in a res/xml/searchable.xml file. At a minimum, a searchable
configuration must contain an android:label attribute that has the
same value as the android:label attribute of the or
element in your Android manifest.
As an example, they show:
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/app_name"
android:hint="#string/search_hint" />
app_name is, like in your manifest, the label of the activity. However, in your searchable, the label refers to search_label. Works perhaps if app_name and search_label are equal, but that seems fragile to me.
I encountered this issue but the advice above did not resolve it. Instead it turned out to be setting category default in the SearchResultActivity. For example the following breaks:
<activity android:name=".SearchResultActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
Removing android.intent.category.DEFAULT resolves this problem.:
<activity android:name=".SearchResultActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
Also the previous answers to this question have an error. MainActivity should be defined with android.app.default_searchable. android.app.searchable is only for your SearchResultsActivity.
<activity
android:name=".MainActivity"
android:label="#string/app_name">
<!-- other stuff-->
<meta-data android:name="android.app.default_searchable"
android:value=".SearchResultsActivity" />
</activity>
In conclusion the SearchManager is a fragile component prone to silent failures when the AndroidManifest.xml isn't perfect.
I wasted 8 full hours on this one because I checked all the above solutions but one thing was missing for me.
In my Android Manifest:
<meta-data
android:name="android.app.searchable"
android:value="#xml/searchable" />
Should has been:
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
For me it was failing silently. The best thing to do at first is just copy and paste the examples. Just be sure that all your attributes are exactly the same.
Related
Search activity not being launched when pressing enter.The search view is shown nicely on the action bar. But when i type the search query and press enter
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.punit.rateit"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
>
<activity
android:name="com.punit.rateit.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:theme="#style/Theme.AppCompat.Light"
android:name=".SearchPageActivity">
<meta-data android:name="android.app.default_searchable" android:value=".SearchResultsActivity" />
<intent-filter>
<action android:name="android.intent.action.SearchPage" />
</intent-filter>
</activity>
<activity android:name="com.punit.rateit.SearchResultsActivity" android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable"/>
</intent-filter>
</activity>
</application>
</manifest>
Here is the Menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:com.punit.rateit="http://schemas.android.com/apk/res-auto" >
<!-- Search, should appear as action button -->
<item android:id="#+id/search"
android:icon="#drawable/ic_search"
android:title="#string/action_search"
com.punit.rateit:actionViewClass="android.widget.SearchView"
com.punit.rateit:showAsAction="ifRoom"
/>
</menu>
The activity which shows action bar.
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu,menu);
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =
(SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
searchView.setSubmitButtonEnabled (true);
return super.onCreateOptionsMenu(menu);
}
The SearchResult activity which should be the activity called when search submit button is pressed
public class SearchResultsActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("search", "search triggered");
setContentView(R.layout.searchpage);
handleIntent(getIntent());
}
#Override
protected void onNewIntent(Intent intent) {
Log.d("search", "search triggered");
setIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent)
{
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
Log.d("search", query);
}
}
#Override
public boolean onSearchRequested() {
Log.d("search", "search triggered");
return false; // don't go ahead and show the search box
}
After a long Research i have Analyse something
searchView.setSearchableInfo( searchManager.getSearchableInfo(new
ComponentName(this,SearchResultsActivity.class)));
Here the activity.class is the name of the searchable activity where you want to pass the search query.
I had the same problem, and my search for an answer took me here, so here is what worked for me...
Make sure your searchables.xml file is in the correct location (i.e,
in your res/xml/ folder) and that the same file does not contain any
errors - otherwise you will find that
(SearchManager)getSystemService(Context.SEARCH_SERVICE).getSearchableInfo(componentName)
will return null, breaking your search functionality.
(Also, ensure you set componentName in the appropriate manner,
because the example shown in the Android guide is for only when you
are making searches and displaying searches in the same Activity.)
...am sharing in the hope it may save someone else a wasted 4 hours! :/
Solved the problem. The tag
was needed to be for application .Removing it from activity and putting it under application did the trick.
Here is the latest application tag in manifest.xml
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
>
<meta-data android:name="android.app.default_searchable" android:value=".SearchResultsActivity"/>
<activity
android:name="com.punit.rateit.MainActivity"
android:label="#string/app_name" >
<meta-data android:name="android.app.default_searchable"
android:value="com.punit.rateit.SearchResultsActivity" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Creating a ComponentName object with the name of the Search Result activity class worked for me. Like this:
searchView.setSearchableInfo(searchManager.getSearchableInfo(new ComponentName(this, SearchStoreActivity.class)));
I was not using the strings within searchable.xml.
You MUST set it up that way or you will get null. I had just put in text instead of using #string.
<?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" >
</searchable>
I struggled with the problem for a day or two, it's not very clearly mentioned in the documentation.
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
In the above the getComponentName function returns the name of the
current component, which is good if your current component is
handling/showing the search results, but if you have a different
activity then you need to put the component name of that activity for
search view to redirect searches to that activity.
searchView.setSearchableInfo(searchManager.getSearchableInfo(new ComponentName(this, SearchResultActivity.class)));
Also make sure to have no errors in searchable.xml file in res/xml folder.
I'm currently working on adding search ability to my app but I'm facing some problems. First of all I'd just like to clear out that I don't want to create a search activity, I just want to use the Action Bar SearchView and press on suggestions to perform the search.
I've created a SearchView which expands correctly although it doesn't seem like it can attach to my Searchable Configuration xml object. I added this line of code:
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"
Yet my SearchView doesn't seem to be affected by it. The same goes for this line of code:
android:hint="Search my stuff"
Again, no effect.
Here's my activity in my AndroidManifest.xml:
<activity
android:name="com.simon.holocountownapp.ItemListActivity"
android:label="Holo Countdown" >
<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>
Here's my setup of the SearchView in my onCreateOptionsMenu():
searchView = (SearchView) menu.findItem(R.id.abSearch)
.getActionView();
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
searchView.setQueryRefinementEnabled(true);
So to summarise things:
The tags used to my searchable.xml doesn't seem to attach to my SearchView, what am I doing wrong?
Thanks for taking the time to read this, I hope you can help me :)
You need to add the android.intent.action.SEARCH intent filter as well. See the code here for reference.
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
I think you also need a <meta-data> element as a child of the <application> element
<application>
<meta-data
android:name="android.app.default_searchable"
android:value="com.simon.holocountownapp.ItemListActivity" >
</meta-data>
</application>
I don't recall if this is documented. I think I found it in one of the sample applications.
I had the same problem, seems that I was missing the default searchable meta-data tag in the manifest.
Add this where you declare the Activity that sends the search to the searchable Activity:
<meta-data android:name="android.app.default_searchable"
android:value=".SearchableActivity" />
Your manifest should look like this:
<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>
...
docs
I'm trying to get suggestions for SearchView. I've implemented a custom content provider for it. I've also referred to this link to implement suggestions for the SearchView. The problem I'm facing is, I get null value on searchManager.getSearchableInfo(getComponentName())
Here are the snippets:
AndroidManifest.xml
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<provider android:name=".SearchProvider"
android:enabled="true"
android:authorities="com.example.currentlocationmapdemo"
android:grantUriPermissions="true"
android:exported="true">
<grant-uri-permission android:pathPattern="*" />
</provider>
<uses-library android:name="com.google.android.maps" />
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable"/>
</activity>
searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="label"
android:hint="hint"
android:searchSuggestAuthority="com.example.currentlocationmapdemo"
android:searchSuggestSelection=" ? ">
MainActivity
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.searchview_in_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
mSearchView = (SearchView) searchItem.getActionView();
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchableInfo info = searchManager.getSearchableInfo(getComponentName()); // null returned
mSearchView.setSearchableInfo(info);
return true;
}
At least one of your activities - the one you're doing the searching from is sufficient - must have this intent-filter in it in the manifest:
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
If not, then searchManager.getSearchableInfo(getComponentName()) always returns null, and your configuration is ignored.
This killed me for a day - I thought it was ActionBarSherlock-related, but no it works fine with that. The problem was that I was trying to short-circuit the sample, as you have too :-)
I think your approach is wrong. You should have 2 activities - 1: Main activity which has as SearchView (on ActionBar or layout) and 2: SearchActivity which will be started when search is performed.
Maybe you can also do it like that but Im not sure. Where would you like to recive ACTION_SEARCH intent in your approach? Normally you do that in OnCreate in your searchActivity like that:
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
System.out.println("searching for: " + query);
}
I did it on two activites and it worked for me. One additional thing I had to do and I didn't find in Android Search Tutorial was adding:
<meta-data
android:name="android.app.default_searchable"
android:value=".SearchableActivity" />
In manifest for my MainActivity
Your searchable.xml contains string literals (hint and label), they should be references. That's what make it fail according to this: SearchInfo always coming out null
Just wanted to add for anyone still struggling with this that a <data> tag will interfere with your intent-filter and cause you to get a null searchableInfo. I had this:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.SEARCH" />
<data android:scheme="https"
android:host="www.example.com"/>
</intent-filter>
which I needed to change to:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="https"
android:host="www.example.com"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
If you are using two activities, one for displaying search dialog(OtherActivity) and another for results(SearchableActivity), then save yourself time by looking at this https://stackoverflow.com/a/58261225/4594347
I am pretty new to java and android development; and I have been working on an app in which I want an action bar with a SearchView. I have looked at the google examples but I can not get it to work. I must be doing something wrong and I'm about to give up on app-development :D I have searched but I have not found anything helpful. Maybe you guys can help me :)
The problem: I get the search view to open as it should, but after that nothing happens at all, I've noticed that my searchManager.getSearchableInfo(getComponentName()) returns null. Also my hint that I've given is not displayed in my search box which leads me to believing that maybe the app can't find my searchable.xml? Enough talk :)
MainActivity.java
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
// Get the SearchView and set the searchable configuration
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =
(SearchView) menu.findItem(R.id.menu_search).getActionView();
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
return true;
}
}
searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="#string/search_hint"
android:label="#string/app_label">
</searchable>
Androidmanifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.searchapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="15" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity android:name=".SearchableActivity" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable"/>
</application>
</manifest>
SearchableActivity.java
package com.example.searchapp;
import android.app.ListActivity;
import android.app.SearchManager;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
public class SearchableActivity extends ListActivity {
#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);
}
}
private void doMySearch(String query) {
Log.d("Event",query);
}
}
And here is a link to the referred project, I would be eternally grateful if someone was to help me with this!
Source code
Your problem is in your AndroidManifest. I had it almost exactly as you do, because that is what I get following the documentation. But it is unclear or mistaken.
Watching at the API Demos source I found that the "android.app.searchable" metadata must go in your "results" activity, and in the main activity (or the activity where you place the SearchView) you point to the other one with "android.app.default_searchable".
You can see it in the following file, which is the Manifest from my test project:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<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=".SearchActivity" />
</activity>
<activity
android:name=".SearchActivity"
android:label="#string/app_name" >
<!-- This intent-filter identifies this activity as "searchable" -->
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<!-- This metadata entry provides further configuration details for searches -->
<!-- that are handled by this activity. -->
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
</application>
It is also important that the hint and label in the searchable.xml are references, and not hardcoded strings.
I hope it solves your problem. It took me all day to figure it out :(
Android guides explicitly says:
// Assumes current activity is the searchable activity
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
Which is in your case NOT TRUE. Because you don't want to search in MainActivity but in SearchableActivity. That means you should use this ComponentName instead of getComponentName() method:
ComponentName cn = new ComponentName(this, SearchableActivity.class);
searchView.setSearchableInfo(searchManager.getSearchableInfo(cn));
Also it seems that both the android:hint and android:label attributes MUST be references to strings in strings.xml. Being lazy and hardcoding the string values doesn't seem to work at all :)
i.e. Don't do:
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="Search for something..."
android:label="My App">
</searchable>
But definitely do (as the OP correctly did):
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="#string/search_hint"
android:label="#string/app_label">
</searchable>
If you are using Android Studio,
<meta-data
android:name="android.app.default_searchable"
android:value=".SearchActivity" />
part may not work.
write full package name like
<meta-data
android:name="android.app.default_searchable"
android:value="com.example.test.SearchActivity" />
be careful with "xml/searchable.xml".
If you made HARD CODE with android:hint and android:label.It will not work. Haha
Should be :
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="#string/app_name"
android:label="#string/search_lb"
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"/>
There's actually no need use the "missing part" as described in the answers above. This method(using a SearchView) works exactly as the official docs say till Using the Search widget. Here a slight modification needs to made as follows:
Properties in a SearchableInfo are used to display labels, hints, suggestions, create intents for launching search results screens and controlling other affordances such as a voice button(docs).
Thus, the SearchableInfo object we pass to the SearchView.setSearchableInfo(SearchableInfo s) must contain proper references to the target activity which should be displayed to show the search results. This is done by manually passing the ComponentName of our target activity. One constructor for creating a ComponentName is
public ComponentName (String pkg, String cls)
pkg and cls are package names and class names of the target activity to be launched for displaying search results. Note that:
pkg must point to the root package name of your project and,
cls must be a fully qualified name of the class(i.e. the entire thing)
e.g.:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
// Get the SearchView and set the searchable configuration
String pkg = "com.example.musicapp"
String cls = "com.example.musicapp.search.SearchActivity"
ComponentName mycomponent = new ComponentName(pkg,cls);
SearchManager searchManager =(SearchManager)getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(mycomponent));
searchView.setIconifiedByDefault(false); //if using on actionbar
return true;
}
Depending on your requirements take a look at the other ComponentName constructors.
Make sure your searchables.xml file is in the correct location (i.e, in your res/xml/ folder) and that the same file does not contain any errors - otherwise you will find that (SearchManager)getSystemService(Context.SEARCH_SERVICE).getSearchableInfo(componentName) will return null, breaking your search functionality.
(Also, ensure you set componentName in the appropriate manner, because the example shown in the Android guide is for only when you are making searches and displaying searches in the same Activity.)
i was facing same issue adding search intent filter like this to searchable activity:
<activity
android:launchMode="singleTop"
android:name=".ui.activities.MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<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>
Double check if the corresponding entry(ie search_hint and app_label) is present in values/strings.xml
eg
<string name="app_label">FunApp</string>
<string name="search_hint">Caps Off</string>
I am trying to implement two different searchable activities, one for honeycomb(with search widget) and others for non-honeycomb(with search dialog).
My Manifest looks like:
<activity android:name=".activities.Search"
android:theme="#style/NoTitleTheme"
android:configChanges="orientation|keyboardHidden"
android:launchMode="singleTop">
android:enabled="#bool/disableForNonHoneycomb"
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable"
android:value=".activities.Search"/>
</activity>
<activity android:name=".activities.SearchHoneycomb"
android:theme="#style/CustomTheme"
android:configChanges="orientation|keyboardHidden"
android:enabled="#bool/enableForNonHoneycomb"
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"
android:value=".activities.SearchHoneycomb"/>
</activity>
And, I use following code to get the searchable configuration and set up the search view in my activity.
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
_searchView = (SearchView) mCustomView.findViewById(R.id.action_bar_searchwidget);
_searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
Problem is that when I use the search widget, it does not start the SearchHoneycomb activity. How can I make this work?
Thanks.
So, after a lot of investigation... there is no way to have 2 searchable activities as android manifest only accepts 1 meta-data for default-searchable.
I got a work around by using a search dialog with default-searchable meta-data and the implemented the querytextlistener for search widget.