I have a little problem: I have a searchView which works with the suggestionAdapter. The problem is that the searchView start to display results from 2 characters. I have however set the threshold to 1 in the searchable.xml + in the code but it doesn't works.The magic here is if I set the threshold to 5 it works...
Searchable.xml:
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/city_list_search"
android:hint="#string/city_list_search"
android:searchSuggestThreshold="1">
</searchable>
Manifest.xml:
<activity
android:name=".activities.HomeActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<action android:name="android.intent.action.SEARCH" />
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable"/>
</intent-filter>
</activity>
My fragment where I also set the threshold to 1:
AutoCompleteTextView search_text = (AutoCompleteTextView) mSearchView.findViewById(mSearchView.getContext().getResources().getIdentifier("android:id/search_src_text", null, null));
search_text.setThreshold(1);
mSearchView.setIconifiedByDefault(false);
mSearchView.setSearchableInfo(mSearchManager.getSearchableInfo(getActivity().getComponentName()));
Where I set the custom adapter: (called in : public boolean onQueryTextChange(String newText))
public void updateSearchResults() {
mSearchView.setSuggestionsAdapter(new CityListSearchResultAdapter(root.getContext(), mCursor));
}
According to documentation, you have to declare the searchSuggestAutority in your searchable :
android:searchSuggestAuthority="com.example.MyCustomSuggestionProvider"
http://developer.android.com/guide/topics/search/adding-custom-suggestions.html
if you really want to use suggestionsAdapter to provide data, don't call setSuggestionsAdapter in updateSearchResults but in onCreate, just update your cursor.
You can also have a look to https://gist.github.com/slightfoot/5514856
You can use Appcompact activity with v7 Searchview. Use as follows to change the threshold,
AutoCompleteTextView autoCompleteTextView = (AutoCompleteTextView) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
autoCompleteTextView.setThreshold(0);
Related
In an Android's search activity, is it possible to handle the event when the user touches the cross button to clear the search box?
The button I'm talking about is the cross in the screenshot:
This is the definition on the manifest:
<activity
android:name=".MySearchActivity"
android:theme="#android:style/Theme.Dialog">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable"/>
</activity>
This is the xml referenced on the meta-data:
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/app_name"
android:hint="#string/search_hint" />
use SearchView.OnQueryTextListener interface, in particular see onQueryTextChange(String newText) method
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'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.
I'm trying to implement the search dialog and I am unable to display the search from an Activity.
I have my main activity defined in my manifest file, this activity shows the user a list of options they have to choose from. One of the options is a Search option.
<activity
android:name=".MenuListActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
My Search activity is defined in my manifest file like so.
<activity android:name=".SearchActivity"
android:launchMode="singleTop"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable"/>
</activity>
Now my problem is when I call the onSearchRequested() from my MenuListActivity nothing happens.
public void onItemClick(AdapterView<?> parent, View itemClicked, int position, long id) {
String strText = items[position];
if (strText.equalsIgnoreCase(getResources().getString(R.string.menu_item_browse))) {
startActivity(new Intent(MenuListActivity.this, WSMobileActivity.class));
} else if (strText.equalsIgnoreCase(getResources().getString(R.string.menu_item_search))) {
// If i call it like this it doesn't work, nothing happens
onSearchRequested();
} else if (strText.equalsIgnoreCase(getResources().getString(R.string.menu_item_locator))) {
startActivity(new Intent(MenuListActivity.this, StoreLocatorActivity.class));
}
}
Please help, how do I invoke the search request from my MenuActivity?
did you check your res/xml/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>
Search dialog doesn't show up when you have hard coded strings for hint and label. They have to be #string resources.
Also, there is no need to call or override the onSearchRequested() method in your calling activity unless you want to invoke search from one of your UI widgets like a Button or a ListItem.
Apart from declaring the SearchActivity in the manifest file you need to include the meta-data info.
If you want to invoke the search dialog throughout the application then include
<meta-data android:name="android.app.default_searchable"
android:value=".SearchActivity" />
inside the application tag.
If you want to invoke the search dialog only in a particular activity then include
<meta-data android:name="android.app.default_searchable"
android:value=".SearchActivity" />
inside the activity tag.
for more details please refer
http://developer.android.com/guide/topics/search/search-dialog.html.
You are missing tag in your activity tag in manifest. replace your activity declaration by following.
<activity
android:name=".MenuListActivity"
android:label="#string/app_name">
<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>
I've done all that but still cannot see the search dialog on API 17. It works however after adding
android:actionViewClass="android.widget.SearchView"
in the fragment menu
<item
android:id="#+id/menu_item_search"
android:actionViewClass="android.widget.SearchView"
android:icon="#android:drawable/ic_menu_search"
android:showAsAction="ifRoom"
android:title="#string/search"/>