In my application i made my content provider searchable, defining my main activity as the default search activity on my manifest.
<activity
android:name="com.pt.application.MainActivity"
android:label="#string/title_activity_map"
android:launchMode="singleTop"
android:theme="#style/AppTheme" >
<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>
Then i implemented the onSuggestionClick option to update a map, based on the suggestion clicked by the user. The searchview is on the action bar.
The problem is that when the user clicks on a suggestion, somehow the activity is recreated (i think OnPause and OnResume are called?). Is there any way to prevent this from happening? I don't want that my activity is "recreated" every time the user clicks on a suggestion.
If more code is needed, please ask. Thanks.
EDIT: Code added
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/app_name"
android:hint="#string/search_hint"
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"
android:voiceLanguageModel="web_search"
android:searchSuggestAuthority="com.pt.provider"
android:searchSuggestIntentData="content://com.pt.provider/busstop">
</searchable>
On my main activity:
// Bind the Activity’s SearchableInfo to the Search View
searchView = (SearchView)menu.findItem(R.id.menu_search).getActionView();
this.setupSearchView();
private void setupSearchView()
{
// Use the Search Manager to find the SearchableInfo related
// to this Activity.
SearchManager searchManager =
(SearchManager)getSystemService(Context.SEARCH_SERVICE);
SearchableInfo searchableInfo =
searchManager.getSearchableInfo(getComponentName());
searchView.setSearchableInfo(searchableInfo);
searchView.setSubmitButtonEnabled(false);
searchView.setOnSuggestionListener(new OnSuggestionListener() {
#Override
public boolean onSuggestionSelect(int position) {
return false;
}
#Override
public boolean onSuggestionClick(int position) {
// Do things
return false;
}
});
}
Solved my question. Changed on the manifest:
From:
android:launchMode="singleTop"
To:
android:launchMode="singleTask"
Related
I'm actually trying to perform a search from a fragment. I would just like to display the text (with a Toast) the user is trying to search with the SearchView widget which in inflated to the fragment. According to the Android documentation, when a user performs a search with the SearchView widget, the application should start a SearchableActivity. The problem is that I can't make it start a SearchableActivity.
Here is my Android Manifest (EDITED with Berhan zikarge's answer):
<activity
android:name=".ClientActivity"
android:screenOrientation="nosensor"
android:label="#string/title_activity_client"
android:windowSoftInputMode="stateAlwaysHidden|adjustPan">
<meta-data android:name="android.app.default_searchable"
android:value=".SearchableActivity" />
</activity>
<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>
Here is the fragment called in ClientActivity :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_organisation_search, container, false);
SearchView searchView = (SearchView) view.findViewById(R.id.search_view_id);
searchView.setIconified(false);
searchView.setIconifiedByDefault(false);
searchView.requestFocus();
return view;
}
The layout it inflates :
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
>
<android.support.v7.widget.SearchView
android:id="#+id/search_view_id"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:label="#string/app_name"
android:hint="#string/search_hint"
android:background="#drawable/block"
>
</android.support.v7.widget.SearchView>
</ScrollView>
The SearchableActivity.java :
public class SearchableActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
doMySearch(query);
}
}
//Here no log is displayed in logcat, and no Toast is shown on the app
public void doMySearch(String query) {
Toast.makeText(getBaseContext(), query+"wsh", Toast.LENGTH_SHORT).show();
Log.e("The query : ",query);
}
}
I've been strugling on this problem for more then 2 hours, if anyone have a solution I would be thankful.
EDIT
I made it work adding this code to my fragment :
#Override
public boolean onQueryTextSubmit(String query) {
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
I think you need to put the meta-data tags on the activity sending the search data and not the one receiving the data. ClientActivity should have the meta-data tag:
<!-- 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>
...
https://developer.android.com/guide/topics/search/search-dialog.html
the problem is that the meta data for the client activity is outside of the activity tag. copy and paste the following code in the manifest
<activity
android:name=".ClientActivity"
android:screenOrientation="nosensor"
android:label="#string/title_activity_client"
android:windowSoftInputMode="stateAlwaysHidden|adjustPan">
<meta-data android:name="android.app.default_searchable"
android:value=".SearchableActivity" />
</activity>
<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>
I am following the google android reference https://developer.android.com/training/search/setup.html to implement my app's SearchView, but when entry completes and I click the right-bottom in the keyboard,it doesn't go to the SearchResultsActivity without error info.
My SearchView is in NotesActivity, and when user type the keyword complete,it will go to SearchResultsActivity with a recyclerView in it.
Here is my manifest.xml :
<activity
android:name=".notes.NotesActivity"
android:label="#string/app_name"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar">
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable"/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".search.SearchResultsActivity"
android:label="#string/title_activity_search_results"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.SEARCH"/>
</intent-filter>
</activity>
and this is the NotesActivity.java
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
return true;
}
Here is the SearchResultsActivity's main code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_results);
handleIntent(getIntent());
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
mKeyword = intent.getStringExtra(SearchManager.QUERY);
//use the query to search your data somehow
if (!TextUtils.isEmpty(mKeyword)) {
mPresenter.loadNotes(mKeyword);
} else {
Snackbar.make(mRecyclerView, R.string.search_empty_keyword, Snackbar.LENGTH_SHORT)
.show();
}
}
}
menu/main.xml:
<item
android:id="#+id/action_search"
android:icon="#drawable/ic_search_white_24dp"
android:orderInCategory="100"
android:title="#string/action_search"
app:actionViewClass="android.widget.SearchView"
app:showAsAction="always"/>
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/app_name"/>
Please guide.
You are missing from the SearchResultsActivity the
<category android:name="android.intent.category.DEFAULT" />
and the
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable"/>
in the NotesActivity the linkage is done via
<meta-data
android:name="android.app.default_searchable"
android:value=".SearchResultsActivity" />
The searchable is related to the activity where the search dialog is displayed and the default_searchable to define which one to use for delivering the searches.
and the proper documentation for it is here https://developer.android.com/guide/topics/search/search-dialog.html
During changes from Holo to Material using Google support library I found an issue that it seems like onSearchRequested callback of Activity is not called. Both Activities - the one that starts search (ProjectDetail) and the one that is search target (ResultList) - are extending android.support.v7.app.ActionBarActivity.
Search works but it never reaches onSearchRequested callback therefore I cannot set additional parameters to search bundle.
There are many similar questions but none of the solutions worked for me so far, therefore I am asking here. I am fighting this for a couple of hours and maybe I am missing something terribly obvious as desperation is obscuring my vision :) Pretty please, help!
Snippet form Manifest:
<application>
<meta-data
android:name="android.app.default_searchable"
android:value=".ResultList" />
<activity android:name="my.package.ProjectDetail">
<meta-data
android:name="android.app.default_searchable"
android:value=".ResultList"/>
</activity>
<activity android:name="my.package.ResultList" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.gms.actions.SEARCH_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="android.app.searchable" android:resource="#xml/searchable" />
</activity>
</application>
This is in onCreateOptionsMenu in Activity that starts the search:
getMenuInflater().inflate(R.menu.search, menu);
MenuItem searchItem = menu.findItem(R.id.menu_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchableInfo info = searchManager.getSearchableInfo(getComponentName());
searchView.setSearchableInfo(info);
searchView.setIconifiedByDefault(true);
searchView.setQueryRefinementEnabled(true);
searchView.setQueryHint(getString(R.string.search_hint));
This is search.xml inflated in previous snippet, containing MenuItem and ActionView:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/menu_search"
android:title="#string/m_search"
android:icon="#android:drawable/ic_menu_search"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView" />
</menu>
And this is onSearchRequested callback in ProjectDetail Activity:
#Override
public boolean onSearchRequested() {
L.dd("SEARCH", "REQUESTED IN PROJECT");
Bundle searchData = new Bundle();
searchData.putLong(Const.EXTRA_PROJECT_ID, projectId);
searchData.putLong(Const.EXTRA_ACCOUNT_ID, accountId);
startSearch(null, false, searchData, false);
return true;
}
Finally, this is searchable.xml as referenced from Manifest:
<?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"
android:searchSuggestAuthority="my.package.provider.SearchSuggestionsProvider"
android:searchSuggestSelection=" ?"
android:includeInGlobalSearch="true"
/>
Thanks in advance.
I had the same problem. Found one simple workaround here.
Generally speaking you override method startActivity in search activity and put params to intent when action is equal to Intent.ACTION_SEARCH:
#Override
public void startActivity(Intent intent) {
// check if search intent
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
intent.putExtra("KEY", "VALUE");
}
super.startActivity(intent);
}
And then in searchable activity get passed params like this:
private void handleIntent(Intent intent){
if (Intent.ACTION_SEARCH.equals(intent.getAction())){
mSearchedQuery = intent.getStringExtra(SearchManager.QUERY);
mExtraData = intent.getStringExtra("KEY");
}
Ok I'm incredibly frustrated I've been trying to get a SearchView to work for hours now with no luck. I checked out how to handle this and I found a sample project and the sample project works great. I then implement the same exact things in my project and bam I'm screwed. The intent won't fire. I don't understand why. I followed this
I have all my activities in an activity folder but removed the Search and Main one to see if that was the case... it's not. In my Search Results activity I'm handling the intent. It looks like this currently.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_result);
// get the action bar
ActionBar actionBar = getActionBar();
// Enabling Back navigation on Action Bar icon
actionBar.setDisplayHomeAsUpEnabled(true);
txtQuery = (TextView) findViewById(R.id.txtQuery);
handleIntent(getIntent());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.search_result, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
handleIntent(intent);
}
/**
* Handling intent data
*/
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
txtQuery.setText("Search Query: " + query);
}
}
My Searchable XML looks like this.
<?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_name" />
For some reason the search hint is not appearing, Yet the string resource shows up and it's declared.
my options menu looks like this
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/search"
android:title="Search"
android:icon="#android:drawable/ic_search_category_default"
android:showAsAction="collapseActionView|ifRoom"
android:actionViewClass="android.widget.SearchView" />
<item android:id="#+id/Menu"
android:title="MENU"
android:showAsAction="collapseActionView|ifRoom"
/>
And my Manifest looks like this.
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/MyTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name"
>
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activities.MenuActivity"
android:label="#string/title_activity_menu"
android:theme="#style/IDME.Theme.Transparent" >
</activity>
<activity
android:name=".activities.CategoriesActivity"
android:label="#string/title_activity_categories" >
</activity>
<activity
android:name=".SearchResultActivity"
android:label="#string/title_activity_search_result"
>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
</activity>
</application>
</menu>
And my Search View inflator looks like this.
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.options_menu, menu);
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =
(SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
return true;
}
I cannot for the life of me figure out what's going on, I followed both guides to a tee, I cannot see what's wrong. I've messed around with metadata and I just really can't see the problem anymore. I'm stuck
I, too, followed the exact same (official Android) guide Setting Up the Search Interface and was in the same boat as the OP #rubsnick.
Turns out, all that that needs to be tweaked is--
Change
<activity
android:name=".MainActivity"
android:label="#string/app_name"
>
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
To
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<meta-data
android:name="android.app.default_searchable"
android:value=".SearchResultActivity" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Notice the <meta-data code! (specifically, android:name)
Also, no need to specify the searchable xml resource here... instead, do that in the SearchResultActivity activity, as shown below...
Lastly, Modify <activity for SearchResultActivity, like so:
<activity
android:name=".SearchResultActivity"
android:label="#string/title_activity_search_result" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable" android:resource="#xml/searchable" />
</activity>
The following SO thread does full justice as to why default_searchable and not searchable:
What's the difference between android.app.default_searchable and android.app.searchable meta-data?
your meta data is incorrect you must use:
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable"
android:value="your package name of searchable activity.SearchResultActivity" />
I have a strange issue. Only thing when the text in the SearchView is submitted,i just want to do move to another Activity. But what actually happens here,when i submit it, near around 1 to 5 sec it starts the main Activity again. I've tried to put that Intent somewhere else and it works well.
Do you have any idea, how to solve this?
Thanks in advance
part of MainActivity (I use ActionBar tabs btw ...Sherlock)
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
getSupportMenuInflater().inflate(R.menu.main, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
if (null != searchView )
{
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
}
SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener()
{
public boolean onQueryTextChange(String newText)
{
return true;
}
public boolean onQueryTextSubmit(String query)
{
Log.v("tag", "submited");
Intent intent = new Intent(getApplicationContext(), SearchActivity.class);
intent.putExtra("null", "null");
startActivity(intent);
return true;
}
};
searchView.setOnQueryTextListener(queryTextListener);
int currentItem = mPager.getCurrentItem();
if(currentItem == 0){
menu.findItem(R.id.action_refresh).setVisible(false);
menu.findItem(R.id.action_search).setVisible(true);
menu.findItem(R.id.action_overflow).setVisible(false);
}
else if(currentItem == 1) {
menu.findItem(R.id.action_refresh).setVisible(true);
menu.findItem(R.id.action_search).setVisible(false);
menu.findItem(R.id.action_overflow).setVisible(false);
}
else if(currentItem == 2) {
menu.findItem(R.id.action_refresh).setVisible(false);
menu.findItem(R.id.action_search).setVisible(false);
menu.findItem(R.id.action_overflow).setVisible(true);
}
return true; }
AndroidManifest
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.animalist.MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait" >
<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.default_searchable"
android:value=".SearchActivity" />
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
<activity
android:name="com.example.animalist.MoreActivity"
android:label="#string/title_activity_more"
android:parentActivityName="com.example.animalist.MainActivity"
android:screenOrientation="portrait" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.animalist.MainActivity" />
</activity>
<activity
android:name="com.example.animalist.SearchActivity"
android:label="#string/title_activity_search"
android:parentActivityName="com.example.animalist.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.animalist.MainActivity" />
</activity>
</application>
</manifest>
Maybe your problem can be that you're querying repeatedly, have you tried to debug and confirm that this is not happening? in case it's happening, you will need to handle which is the right time for starting your activity, you can use a handler post delaying or another solution could be to check if have just come across the onQuerySubmit method and if so, don't start the activity.
In the activity where the SearchView is displayed you need to change
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable"/>
to
<meta-data
android:name="android.app.default_searchable"
android:value="ActivitySearchResults" />
Try this, I think this will work:
searchView.setQuery("", false);
searchView.requestFocus();
return true;