Android onSearchRequested()回调调用活动

时间:2011-01-26 17:39:07

标签: android search stack

我有一个MapActivity,当按下搜索按钮时,它会显示Android搜索框。 SearchManager管理对话框,并将用户的查询传递给可搜索的活动,该活动搜索SQLite数据库并使用自定义适配器显示结果。

这很好用 - 我从显示的数据库中得到了正确的结果。

但是,我想要做的是在用户点击搜索结果时在地图上的MapActivity中显示结果。目前,这意味着启动一个新的MapActivity,使用Bundle传递搜索结果。

我认为更清洁的方法是将搜索结果传回原始活动,而不是开始新活动。目前,我的活动堆栈是MapAct - > SearchManager - >搜索结果 - >新的MapAct。这意味着从新MapAct中按“后退”将返回查询结果,然后返回到原始MapAct。

似乎在搜索结果中,调用finish()不会导致在调用MapActivity中调用onActivityResult。

任何想法如何获得此回调并维护合理的活动堆栈?

2 个答案:

答案 0 :(得分:5)

我一直在寻找这个问题的答案,并最终找到了有效的方法。我不得不将原始的调用活动作为可搜索的活动,因此我在清单中的条目如下所示:

<activity android:name=".BaseActivity"
          android:launchMode="singleTop">
   <!-- BaseActivity is also the searchable activity -->
   <intent-filter>
      <action android:name="android.intent.action.SEARCH" />
   </intent-filter>
   <meta-data android:name="android.app.searchable"
              android:resource="@xml/searchable"/>
   <!-- enable the base activity to send searches to itself -->
   <meta-data android:name="android.app.default_searchable"
              android:value=".BaseActivity" />
</activity>

然后,不是在此活动中搜索,而是使用真实搜索活动手动startActivityForResult,这样您就可以setResultfinish返回原始调用活动。

我在blog post here中详细介绍了一些细节。

答案 1 :(得分:2)

我终于找到了一个不涉及singleTop的解决方案。

首先,在发起搜索的Activity中,覆盖startActivityForResult:

@Override
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        int flags = intent.getFlags();
        // We have to clear this bit (which search automatically sets) otherwise startActivityForResult will never work
        flags &= ~Intent.FLAG_ACTIVITY_NEW_TASK;
        intent.setFlags(flags);
        // We override the requestCode (which will be -1 initially)
        // with a constant of ours.
        requestCode = AppConstants.ACTION_SEARCH_REQUEST_CODE;
    }
    super.startActivityForResult(intent, requestCode, options);
}

由于某种原因,Android将始终(出于某种原因)使用Intent.FLAG_ACTIVITY_NEW_TASK标志启动ACTION_SEARCH目标,但如果设置了该标志,则onActivityResult永远不会(正确)调用您的原始内容任务。

接下来,在您的可搜索活动中,您只需在用户选择项目时正常呼叫setResult(Intent.RESULT_OK, resultBundle)

最后,您在原始活动中实施onActivityResult(int requestCode, int resultCode, Intent data),并在resultCodeIntent.RESULT_OKrequestCode为您的请求代码常量AppConstants.ACTION_SEARCH_REQUEST_CODE时做出适当回应在这种情况下)。