10

My use case is the following: in activity A, I have an action bar with a collapsible SearchView. When the user gives her query and presses the 'search' button, I would like to show activity B with the results. I'm failing to do so, here is my code:

searchable.xml:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
            android:hint="@string/action_search_hint"
            android:label="@string/app_name"/>

Activity A:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu, menu);

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

    return true;
}

AndroidManifest for Activity A and B:

    <activity
        android:name=".ActivityA">

        <intent-filter>

            <action android:name="android.intent.action.MAIN"/>

            <category android:name="android.intent.category.LAUNCHER"/>

        </intent-filter>

    </activity>

    <activity android:name=".ActivityB">

        <intent-filter>

            <action android:name="android.intent.action.SEARCH"/>

        </intent-filter>

        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable"/>

    </activity>

Howerver, no matter what I try, getSearchableInfo in A always returns null.

I have the feeling I'm not understanding something. The only way I can make getSearchableInfo() return not null is when I put the SEARCH intent filter and the searchable meta-data into activity A in the manifest. But then, when I press the 'search' button, another instance of activity A is started again on top of the current one, which definitely is not what I want. I guess I could add singleTop to A and handle the SEARCH action in onNewIntent and start B, but I generally don't want A to be singleTop, I want the default. Or do I?

I tried adding this to A in the manifest (as suggested in some other threads):

    <meta-data
        android:name="android.app.default_searchable"
        android:value=".ActivityB" >
    </meta-data>

What am I doing wrong?

EDIT: I replaced the 'getComponentName()' line in A with the following:

searchView.setSearchableInfo(searchManager.getSearchableInfo(new ComponentName(this, ActivityB.class)));

and it seems to work the way I want! Am I doing something wrong here, or is this the correct way? I'm a bit uncertain because it is not mentioned anywhere!

wujek
  • 7,600
  • 9
  • 42
  • 72
  • 1
    The doc says `getSearchableInfo(componentName)` take one argument, which is 'the activity to get searchable information for'. In your case you need ActivityB, so constructing a `ComponentName` that points to ActivityB is the correct way. – hidro Feb 02 '15 at 09:21
  • @hidro - I will accept your answer if you write one. – wujek Feb 16 '15 at 22:23
  • Thanks a million for asking this question. Rescued after four hours of wasted time. – X09 Aug 11 '16 at 20:35

2 Answers2

17

According to Android documentations, SearchManager.getSearchableInfo(componentName) takes one argument, which is:

componentName: The activity to get searchable information for

In your case you need ActivityB, so constructing a ComponentName that points to ActivityB is the correct way

new ComponentName(this, ActivityB.class)
hidro
  • 11,509
  • 5
  • 49
  • 53
  • 1
    Works like magic. I can't give more than one upvote else I could have given a million. – X09 Aug 11 '16 at 20:36
0
<intent-filter>
            <action android:name="android.intent.action.SEARCH"/>
        </intent-filter>

add this intent filter to activity A.

2.SearchView Menu

SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        searchView = (SearchView) menu.findItem(R.id.search).getActionView();
        searchView.setSearchableInfo(searchManager
                .getSearchableInfo(getComponentName()));

xml:

  <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/search"
        android:actionViewClass="android.widget.SearchView"
        android:icon="@drawable/ic_action_search"
        android:showAsAction="collapseActionView|always"
        android:title="@string/search_hint"/>

</menu>

3.Call this method from oncreate.

private void handleIntent(Intent intent) {
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            String query = intent.getStringExtra(SearchManager.QUERY);

            Debug.e("Suggestion handle click", "call " + query);

            startNextActivity(query);

        }
    }

4. if you are using Autosuggestion Listview implement searchView.setOnQueryTextListener ,setOnSuggestionListener and setSuggestionsAdapter.

SreeAndroidDev
  • 141
  • 1
  • 1
  • 11
  • I don't want A to get the search intent, that's the whole point in my question, sorry if I wasn't clear. – wujek Feb 02 '15 at 08:58