2

I'm actually trying to use the built-in search interface of Android, but I have some issues when I try to pass data with the search query.

Here is a brief explanation : I have an object in a first Activity (FirstActivity) called "Category" which implements Serializable (I already pass it successfuly between Activities) and I want to perform a search related to that category, and display the results in a second Activity (SecondActivity).

So, in FirstActivity I override the onSearchRequest method :

@Override
public boolean onSearchRequested() {
    Bundle appData = new Bundle();
    appData.putSerializable("category", _currentCategory);
    Log.d(Utils.LOG_TAG, "Bundle : "+appData.keySet());
    startSearch(null, false, appData, false);
    return true;
}

And in SecondActivity, I try to get this Bundle :

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

private void handleIntent(Intent intent){
    Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
    if(appData == null) Log.d(Utils.LOG_TAG, "appData == null");
    Log.d(Utils.LOG_TAG, "Extras : "+intent.getExtras().keySet());
}

Problem is that appData seems to be equals to null everytime. Here is the logcat output :

Bundle : [category]
appData == null
Extras : [query, user_query]

I tried to add some other objects into the Bundle (Booleans, etc...) but it doesn't change anything at all and I keep having a null appData.

Lyrkan
  • 1,063
  • 10
  • 18
  • Please add your `startSearch()` method. The problem may be in this method where you are constructing the Intent that you're using to launch your second activity. – Mark Allison Jun 16 '11 at 13:25
  • startSearch() is an existing method from Activity : http://developer.android.com/reference/android/app/Activity.html#startSearch%28java.lang.String,%20boolean,%20android.os.Bundle,%20boolean%29. From what I read, it should handle that stuff. – Lyrkan Jun 16 '11 at 13:29
  • 1
    I found the best way to do it is to override StartActivity. See: http://enjoysmile.com/blog/28/passing-extra-variables-to-search-activity-invoked-by-a-search-widget/ – danada Feb 22 '13 at 20:45

4 Answers4

3

I had problems figuring this out as well, and the examples I found didn't really help. A lot of them suggested overriding onSearchRequested(), but that actually doesn't work for SearchWidget. I ended up using the following (from danada) as a solution, since it seemed much simpler for me than setting up the OnQueryTextListener. I just overrode startActivity (in the first, search Activity) like so:

@Override
public void startActivity(Intent intent) {      
    //check if search intent
    if(Intent.ACTION_SEARCH.equals(intent.getAction())) {
        intent.putExtra("KEY", "VALUE");
    }

    super.startActivity(intent);
}

Then in the second, searchable Activity, I pulled out the info like so (called from onCreate() or from overriding onNewIntent() (if using singleTop)):

private void handleIntent(Intent intent){
    if(Intent.ACTION_SEARCH.equals(intent.getAction())){
    mSearchedQuery = intent.getStringExtra(SearchManager.QUERY);
    mExtraData = intent.getStringExtra("KEY");
}

Simple, and worked like a charm! Check the link to the article above if you would like a little more explanation about it.

Jason
  • 1,238
  • 1
  • 15
  • 18
1

If you're using SearchView, it will not send your appData. Instead, consider using OnQueryTextListener. For example:

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

    /*
     * Get the SearchView and set the searchable configuration.
     */
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.your-search-menuitem-id)
            .getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    /*
     * Set query text listener here.
     */
    searchView.setOnQueryTextListener(mSearchViewOnQueryTextListener);

    return true;
}// onCreateOptionsMenu()

...
private final SearchView.OnQueryTextListener mSearchViewOnQueryTextListener = new SearchView.OnQueryTextListener() {

    @Override
    public boolean onQueryTextSubmit(String query) {
        /*
         * You don't need to deal with "appData", because you already
         * have the search query here.
         */

        // Tell the SearchView that we handled the query.
        return true;
    }// onQueryTextSubmit()

    @Override
    public boolean onQueryTextChange(String newText) {
        // TODO Auto-generated method stub
        return false;
    }// onQueryTextChange()
};// mSearchViewOnQueryTextListener

Note: You still need to keep the old way (using appData inside onSearchRequested()). In your onCreate(), if the extra for SearchManager.APP_DATA is null, that means you already handled the search query in the listener.

Conclusion:

  • If the SearchView is inactive, and you invoke it via onSearchRequested(), this will happen: onSearchRequested() >> onCreate() (ACTION_SEARCH contains SearchManager.APP_DATA).
  • If the SearchView is active, the user types and submits search, this will happen: SearchView.OnQueryTextListener.onQueryTextSubmit() >> onCreate() (ACTION_SEARCH without SearchManager.APP_DATA).
0

While putting data and retrieving it you are using two different keys. while putting you are using "category" and while retrieving you are using SearchManager.APP_DATA instead of using "category"

Try with

Bundle appData = intent.getBundleExtra("category");

Thanks Deepak

Sunil Kumar Sahoo
  • 53,011
  • 55
  • 178
  • 243
  • Thanks for your answer but unfortunately, it doesn't change anything. As I wrote earlier, intent.getExtras().keySet() returns [query, user_query] so, no trace of my Bundle. – Lyrkan Jun 16 '11 at 13:37
0

In your example, you are asking for the keyset on the original intent object, and not the Bundle containing your appData. Here is an example that should work:

private void handleIntent(Intent intent){
    final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);

    for (String key : appData.keySet()) {
        Log.d(TAG, "key="+appData.getString(key));
    }
}
NPike
  • 13,136
  • 12
  • 63
  • 80