In Android 11, when targetSdk is set to 30 and voice search is enabled, the microphone icon doesn't show on the SearchView. However, it works correctly if targetSdk is set to 29. It works on Android 10 devices also with targetSdk 30.
Is there anything extra which needs to be done for 30?
menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_search"
android:title="Search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="always" />
</menu>
Manifest.xml
<activity android:name=".MainActivity">
<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" />
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
</activity>
searchable.xml
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/app_name"
android:hint="Search"
android:imeOptions="actionSearch"
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"/>
MainActivity
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.search, menu)
val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
val searchView: SearchView = menu.findItem(R.id.action_search).actionView as SearchView
val searchableInfo = searchManager.getSearchableInfo(componentName)
Log.d(TAG, "onCreateOptionsMenu: ${searchableInfo.voiceSearchEnabled}, ${searchableInfo.voiceSearchLaunchRecognizer}")
searchView.setSearchableInfo(searchableInfo)
searchView.setIconifiedByDefault(false)
return super.onCreateOptionsMenu(menu)
}
Android 11 doesn't allow checking all the installed applications, so we need to add a queries block to allow the app to see the voice search app.
Add this in AndroidManifest.xml below the manifest tag for microphone icon to show up:
<queries>
<intent>
<action android:name="android.speech.action.RECOGNIZE_SPEECH" />
</intent>
</queries>
Package visiblility in Android 11
Note: If you get build error(not lint warning) saying queries element not allowed, make sure to update build tools version:
Image taken from https://android-developers.googleblog.com/2020/07/preparing-your-build-for-package-visibility-in-android-11.html
Related
I'm following this Android tutorial to implement the Search View. After fixing some issues, I got it to work. However, the search view needs to be clicked twice to open the editText. Any idea of what's going on?
Filter class:
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.toolbar_menu_filter, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =
(SearchView) menu.findItem(R.id.menu_item_search).getActionView();
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
searchView.setQueryHint(getResources().getString(R.string.search_hint));
return super.onCreateOptionsMenu(menu);
}
menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".FilterUI">
<item android:id="#+id/menu_item_search"
android:title="Search"
android:icon="#drawable/ic_search_white"
app:actionViewClass="android.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView"/>
<item android:id="#+id/menu_item_options"
android:icon="#drawable/ic_clear_all_white"
app:showAsAction="ifRoom"
android:title="#string/filter_default"/>
Manifest file
<activity android:name=".Activities.FilterUI"
android:screenOrientation="portrait"
android:configChanges="orientation"
android:windowSoftInputMode="adjustNothing">
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
<activity android:name=".Activities.SearchActivity">
<intent-filter>
<action android:name="android.intent.action.SEARCH"/>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Might be too late to answer but, let's get this done. Like I said, it's better to use:
app:actionViewClass="android.support.v7.widget.SearchView"
For more compatibility and etc. But the point is, in new AndroidX, we can't use android.support since we migrate to AndroidX and there will be only:
app:actionViewClass="android.widget.SearchView"
Available. But, let's see what documentation says for the newest APIs (AndroidX) and etc:
Note: This class is included in the support library for compatibility with API level 7 and higher. If you're developing your
app for API level 11 and higher only, you should instead use the
framework android.widget.SearchView class.
So in AndroidX, I have found:
app:actionViewClass="androidx.appcompat.widget.SearchView"
To use but you still can use: android.widget.SearchView.
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'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.