SearchInfo always coming out null
Asked Answered
M

7

21

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>
Meson answered 18/4, 2012 at 20:38 Comment(0)
B
43

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.

Brnaby answered 20/4, 2012 at 15:15 Comment(7)
Wow! That is a very evil bug. I reported it here: code.google.com/p/android/issues/detail?id=37517Dichotomy
Actually, it says in docs that which parameters must be string resource and which can be strings developer.android.com/guide/topics/search/…Disequilibrium
Just lost 4 hours because of this, it probably would have been more if I hadn't seen this answer. Many thanks.Ambo
We should make you a knight for that answer.Reentry
Saved me hours and headache.Suzansuzann
Thank you! I gain half a day ~Reveille
Omg lost several hours of my life because of this, thanks man!Valence
W
19

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"
Wreath answered 28/8, 2014 at 12:15 Comment(0)
R
19

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;
}
Reindeer answered 4/5, 2015 at 14:47 Comment(2)
Thanks man.....the only solution to have worked for me is the new componentName one.....i don't know why but all others didnt workScour
Oh wow! The only solution that worked! Deserves more upvotes!Coarsen
S
11

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.

Steiermark answered 8/3, 2013 at 18:9 Comment(0)
A
3

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.

Admonish answered 13/9, 2012 at 16:35 Comment(0)
A
3

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.

Against answered 18/12, 2015 at 20:2 Comment(0)
R
1

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.

Rooks answered 1/5, 2016 at 14:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.