在Android 4.x+中,onSearchRequested()不再起作用?

25

我的应用截取了搜索按钮,以便传递更与应用本身相关的内容:

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

除了我的新的4.1.2手机,它在所有Android版本上工作得很好(仍然有效):在这个Android 4.x手机上,有一个叫做“Google Now”的东西被调用。

这是一个众所周知的变化吗(例如记录在案)?

如果是,那么还有没有其他方法可以“拦截”搜索按钮?

更新:我按照@ daniel_c05的建议完全操作,但触摸搜索按钮仍然产生相同的行为:带出Google搜索活动(并挂起我的活动,这显然不是期望的行为):

enter image description here

顺便说一下,在这个类似的问题中的被接受的答案是不可接受的...那么还有其他方法可以“拦截”搜索按钮吗?


类似于这个:https://dev59.com/OGfWa4cB1Zd3GeqPezUO - A--C
2
@A--C 一点也不是重复的问题。 :) 请注意内容并查看这两个问题正在讨论两件不同的事情。但是感谢提供链接! - Souper
但它仍然是一个副本。 - Geobits
@Geobits 好的。假设它确实是一个重复的问题。如果这个重复问题的“被接受的答案”是不可接受的,那么这个重复问题有什么好处呢?;) - Souper
1
这只是因为不能接受它才变得不可接受。这并不意味着它是错的。我的六岁孩子会争辩说上床睡觉是不可接受的;) - Geobits
9
@Geobits 你说得对。我很难相信在Android 1.x、2.x和3.x中我们如此依赖的功能没有恢复的方法。我愿意使用未记录的技巧,只是想要我的搜索按钮回来。就像一个六岁的孩子一样。 :) - Souper
2个回答

10

没错,谷歌在引入Jelly Bean(Android 4.1)时劫持了搜索按钮,如果您尝试在更早的时候拦截它,在onKeyDown()方法中:

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

你会意识到它也行不通。

但也许这个解决方法能够帮到你?


8
抱歉,但你提出的解决方法只适用于用户。我需要一种编程的解决方案。仍在寻找解决方法。 - Souper

2

我有一部运行4.2.1的Galaxy Nexus手机,使用oonSearchRequested没有问题。

需要考虑以下几点:

1 - 确保在你的清单文件中声明可搜索活动确实是可搜索的,并确保添加了搜索意图过滤器以捕获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 - 重写onKeyDown()以创建一个合适的搜索界面:

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

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

在这一点上,如果您有一个searchWidget,它应该自动加载,现在只需要等待用户输入。您会希望通过覆盖onNewIntent来处理搜索,根据您的searchable.xml行为使用Action.Search或Action.View。
编辑
好的,您能否帮我一个忙,尝试重写onKeyDown,但不要放任何代码在其中,像这样:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {     

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

我想要测试的是,看看这样做是否能阻止Google的出现,这应该完全没有作用。如果这个方法有效,那么之后你可以添加自己的代码,只需确保返回true(以避免事件的进一步传播),并且不调用onSearchRequested即可。

1
抱歉。我尝试了您的解决方案,但在Android 4.1上,搜索按钮仍然会返回Google搜索,而不是通过onKeyDown(和android.intent.action.SEARCH过滤器)让我的应用程序处理此操作。 - Souper
澄清:当用户点击搜索按钮时,我不想在我的运行应用程序中添加searchWidget或任何其他视觉变化。我只想在我的已激活活动中调用特定方法。在Android 4.1之前,覆盖onSearchRequested()正是我所需要的。但是现在我不介意将该方法命名为其他名称。我只需在用户触摸搜索按钮时调用一些回调/方法即可。想法? - Souper
1
重写onKeyDown()而不是onSearchRequested()。如果(keycode == KeyEvent.KEYCODE_SEARCH),那么执行你的操作并返回true,这样事件就不会传播了。否则,返回super.onKeyDown(keycode, event)。 - daniel_c05
1
@daniel_c05 我相信原帖已经提到他尝试了覆盖onKeyDown()方法(其他答案中也有建议)。从他描述的情况来看,似乎没有解决他的问题的方法。 - ateiob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接