jas7457
jas7457

Reputation: 1991

I'm having trouble getting the Android Search Interface to work in the Action Bar

I tried following the guide here, but I'm having some problems. I correctly got the search icon to appear in the action bar, but I'm having trouble attaching the searchable configuration to the SearchView.

My res/menu/options_menu.xml file:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/search"
          android:title="@string/search_title"
          android:icon="@drawable/search"
          android:showAsAction="collapseActionView|ifRoom"
          android:actionViewClass="android.widget.SearchView" />
</menu>

My res/xml/searchable.xml file (Note: I had to create an "xml" folder in the res folder because one did not exist. I don't think this should make a difference though?

<?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" />

My res/values/strings.xml file:

<?xml version="1.0" encoding="utf-8"?>
<resources>

<string name="app_name">Starting To Feel It</string>
<string name="single_post">Single Post View</string>
<string name="search">Search Activity</string>

<string name="action_settings">Settings</string>
<string name = "pagination_last">Last</string>
<string name = "pagination_next">Next</string>

<string name = "player_play">Play</string>
<string name = "player_previous">Previous</string>
<string name = "player_next">Next</string>
<string name = "player_playlist">Playlist</string>
<string name = "player_progress_bar">Progress Bar</string>

<string name="drawer_open">Open navigation drawer</string>
<string name="drawer_close">Close navigation drawer</string>


<string name="search_title">Search STFI</string>
<string name="search_hint">Search STFI</string>


<string name="menu_item_picture">Menu Item Picture</string>

</resources>

My AndroidManifest.xml file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.stfi"
android:versionCode="1"
android:versionName="1.0" >

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

<uses-sdk
    android:minSdkVersion="14"
    android:targetSdkVersion="17" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:theme="@android:style/Theme.Holo.Light" >


    <activity
        android:name=".StartingToFeelIt"
        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=".activities.SinglePost"
        android:label="@string/single_post">

    </activity>

    <activity 
        android:name=".activities.SearchActivity" 
        android:label="@string/search">

        <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>

All of my activities extend a class I called MenuActivity, and here is the onCreateOptionsMenu function define in MenuActivity.java:

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

    // Associate searchable configuration with the SearchView
    SearchManager searchManager =
            (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView =
            (SearchView) menu.findItem(R.id.search).getActionView();

    System.out.println("The component name is " + this.getComponentName().toString());

    SearchableInfo info = searchManager.getSearchableInfo(getComponentName());

    if(info  == null)
    {
        System.out.println("It is null!");
    }

    searchView.setSearchableInfo(info);

    return true;
}

I'm always getting that info is null in this function. I'm not sure what I'm doing wrong to get info is null, and I'm not sure how to fix it. I'm not sure if you need it or not, but below is my SearchActivity class. Right now it doesn't do anything but try to display the search (however, it is never called because the search configuration is not set up correctly). The file is saved in com.stfi.activities.SearchActivity.java.

Another note: When I print out the component name in the function above, I get The component name is ComponentInfo(com.stfi/com.stfi.StartingToFeelIt) and not just com.stfi.StartingToFeelIt. This leads me to believe something is wrong with my AndroidManifest file, but I have no idea if this is the cause as to why I can't attach the search configuration.

public class SearchActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    handleIntent(getIntent());
}

@Override
protected void onNewIntent(Intent intent) {
    handleIntent(intent);
}

private void handleIntent(Intent intent) {

    if (Intent.ACTION_SEARCH.equals(intent.getAction()))
    {
        String query = intent.getStringExtra(SearchManager.QUERY);
        System.out.println("You are searchin " + query);
    }
}
}

Upvotes: 15

Views: 1991

Answers (4)

Social_Engineerer
Social_Engineerer

Reputation: 108

     <activity
        android:name="com.yourapp.YourSearchActivity"
        android:label="@string/title_activity_search"
        android:launchMode="singleTop" >
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>

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

In my Menu XML for the activity:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.example.mirrorcamera.MainActivity" >

    <item
        android:id="@+id/search"
        android:showAsAction="always"
        android:title="@string/string_title"/>

</menu>

Java Code:

public class SearchActivity extends ListActivity {

    private static final int             ICON = R.drawable.ic_ab_back_holo_light;
    private SearchDataBaseAdapter        searchDataBaseAdapter;
    private ArrayList<SearchResultModel> searchResultList;
    private ResultListAdapter            resultListAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);

        super.onCreate(savedInstanceState);

        searchResultList = new ArrayList<SearchResultModel>();

        // gets the db reference from adapter
        searchDataBaseAdapter = new SearchDataBaseAdapter(this);
        searchDataBaseAdapter.open();

        handleIntent(getIntent());

    }



    /**
     * Handles the intent from the search.
     * 
     * @param intent
     */
    private void handleIntent(Intent intent) {
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            // handles a search query
            String query = intent.getStringExtra(SearchManager.QUERY);
            search(query);

        }
    }



    @Override
    public void onNewIntent(Intent intent) {
        // super.onNewIntent(intent);
        setIntent(intent);
        handleIntent(intent);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {

        case R.id.search:
            onSearchRequested();
            break;
        }

        return true;
    }

    /**
     * Search function.
     * 
     * @param searchTerm
     */
    public void search(String searchTerm) {

        try {
            Cursor cursor = searchDataBaseAdapter.getWordMatches(searchTerm, null);
            //create and add your list to your adapter.
            resultListAdapter = new ResultListAdapter(this, itemsFound(cursor, cursor.getString(cursor.getColumnIndex("YOUR_COLUMN"))));
        } catch (NullPointerException ex) {
            Toast.makeText(this, "Search Term not found", Toast.LENGTH_LONG).show();
            ex.getStackTrace();

        }

        setListAdapter(resultListAdapter);

    }

    /**
     * Returns the items found and writes the items found to an arraylist.
     * @return
     */
    private ArrayList<SearchResultModel> itemsFound(Cursor cursor, String itemName, String     itemDescription, int type) {
        // ArrayList<String> list = new ArrayList<String>();

        if (cursor.moveToFirst()) {
            do {
                searchResultList.add(new SearchResultModel(itemName, itemDescription, type, ICON));
            } while (cursor.moveToNext());
        }
        cursor.close();

        return searchResultList;
    }


}

Hope this helps

Upvotes: 1

mrres1
mrres1

Reputation: 1155

"My res/xml/searchable.xml file (Note: I had to create an "xml" folder in the res folder because one did not exist. I don't think this should make a difference though?"

You can add folders as you need, as long as you are following the guidlines of the xmls' namespaces

In regard to the search, I don't believe the minSdkVersion and targetSdkVersion are right.

According to Android's, Remaining Backward Compatible article you should be using

<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="15" />

<application>
...

Upvotes: 1

LOG_TAG
LOG_TAG

Reputation: 20569

probably problem with the manifest i guess,

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

is missing in your manifest's activity tag for 'StartingToFeelIt'

 <activity
    android:name=".StartingToFeelIt"
    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>

also you can use ABS CollapsibleSearchMenu Lib.

Upvotes: 1

nathanleachman
nathanleachman

Reputation: 285

I have beeen poking around and have found two things you need to do.

1. Update your Manifest.xml and use <meta to add your Search Interface.

2. In order for it to have searchable configuration you need to add meta data

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

</activity>

Upvotes: 2

Related Questions