25

My app intercepts the search button to deliver something more relevant to the app itself:

  @Override
  public boolean onSearchRequested() {
    if (isOkToSearchWithinTheApp())
      doRelevantOwnSearch();
    return true; 
  }

It worked (still works) great on all Android versions except on my new 4.1.2 phone: On this Android 4.x phone, something called "Google Now" is invoked itself.

Is this a well known (i.e. documented change)?

If so, is there any other way to "intercept" the search button?

Update: I did exactly as suggested by @daniel_c05 below but touching the search button keeps yielding the same behavior: Bringing the Google search activity (and suspending my own activity, which is clearly not the desired behavior):

enter image description here

BTW, the accepted answer in this similar question is not acceptable... so, is there any other way to "intercept" the search button?

Community
  • 1
  • 1
Souper
  • 1,247
  • 3
  • 14
  • 23
  • Similar to this: http://stackoverflow.com/questions/11931395/jelly-bean-search-key – A--C Dec 23 '12 at 20:04
  • 2
    @A--C Not a duplicate at all. :) Note the content and see that the 2 questions are talking about two different things. But thanks for the link! – Souper Dec 23 '12 at 20:06
  • Yet it's still a duplicate. – Geobits Feb 27 '13 at 01:07
  • @Geobits Fine. Let's say it *is* a duplicate. What good is a duplicate if its "accepted answer" is unacceptable? ;) – Souper Mar 01 '13 at 02:42
  • 1
    It's only unacceptable because *you* can't accept it. That doesn't make it wrong. My 6 year old would argue that bedtime is unacceptable ;) – Geobits Mar 01 '13 at 02:48
  • 9
    @Geobits You're right. It is hard for me to believe that there is no way to restore the behavior that we came to depend on so much in Android 1.x, 2.x and 3.x. I am perfectly willing to use an undocumented trick. I just want my search button back. Just like a 6-year old. :) – Souper Mar 01 '13 at 02:50

2 Answers2

10

Yup, Google hijacked the search button when it introduced Jelly Bean (Android 4.1) and if you try to intercept it earlier, in onKeyDown():

...
else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
  return this.onSearchRequested();
}

You'll realize it won't work either.

But maybe this workaround could help you?

A--C
  • 36,351
  • 10
  • 106
  • 92
ih8ie8
  • 944
  • 8
  • 23
  • 8
    Sorry but your suggested workaround is for the user. I need to **programmatic** solution. Still looking for a solution. – Souper Feb 27 '13 at 00:33
2

I have a Galaxy Nexus running 4.2.1 and I have no issues using oonSearchRequested

A few things to consider:

1 - Make sure you declare in your manifest that the searchable activity IS in fact searchable, and make sure you add the Search Intent Filter to catch onSearchRequested:

  <activity
        android:name="com.lazybits.rae.movil.Results"
        android:label="@string/title_activity_results"
        android:launchMode="singleTask"
        android:parentActivityName="com.lazybits.rae.movil.Home" >
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable" />
    </activity>

2 - Override onKeyDown() to make a proper search interface:

 @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {     

    if ((keyCode == KeyEvent.KEYCODE_SEARCH) && isOkToSearchWithinTheApp) {
        onSearchRequested();
        return true;
        }
    return super.onKeyDown(keyCode, event);
    }

At this point if you have a searchWidget it should be loaded automatically, and you are now just waiting on user input. You would want to override onNewIntent for handling the search via Action.Search or Action.View depending on your searchable.xml behaviour.

EDIT

OK, can you do me a favor, and simply try to override onKeyDown, but not put any code in it, like this:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {     

    if (keyCode == KeyEvent.KEYCODE_SEARCH) {
            //do nothing, simply return true to avoid regular behavious
            return true;
        }
    }

What I want to test, is to see if that will stop Google now from coming up, this should do absolutely nothing. If that works, then afterwards you can add your code, just make sure you return true (to avoid further propagation of the event), and that you don't call onSearchRequested.

daniel_c05
  • 11,438
  • 17
  • 60
  • 78
  • 1
    Sorry. I tried your solution and the search button on Android 4.1 still yields Google Search instead of letting my app handle this via onKeyDown (and the `android.intent.action.SEARCH` filter). – Souper Feb 28 '13 at 05:07
  • Clarification: I don't want a searchWidget or any other visual change in my running application when the user touches the search button. All I want is to **invoke a specific method** in my already active activity. Prior to Android 4.1, overriding `onSearchRequested()` provided me with exactly that. But at this point I don't mind having that method being called something else. I just need to invoke some callback/method upon the user touching the search button. I will take it from there. Ideas? – Souper Mar 01 '13 at 02:47
  • 1
    Override onKeyDown() rather than onSearchRequested(). If (keycode == KeyEvent.KEYCODE_SEARCH) then do your thing and return true so the event doesn't propagate. Else return super. onKeyDown(keycode, event); – daniel_c05 Mar 01 '13 at 04:09
  • 1
    @daniel_c05 I believe the OP already stated that he tried overriding onKeyDown() (also suggested in the other answer). It doesn't look like there is a solution to his problem (the way he described it). – ateiob Mar 01 '13 at 23:51