【问题标题】:Android onSearchRequested() callback to the calling activityAndroid onSearchRequested() 回调到调用活动
【发布时间】:2011-06-16 00:36:31
【问题描述】:

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

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

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

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

似乎在Search Result中,调用finish()不会导致在调用MapActivity中调用onActivityResult。

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

【问题讨论】:

    标签: android search stack


    【解决方案1】:

    我一直在寻找这个确切问题的答案,终于找到了可行的方法。我必须使原始调用活动成为可搜索活动,因此清单中的条目如下所示:

    <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 中进行了更详细的介绍。

    【讨论】:

      【解决方案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 Intent,但如果设置了该标志,onActivityResult 将永远不会(正确地)在您的原始任务中被调用。

      接下来,在您的可搜索 Activity 中,您只需在用户选择项目时照常调用 setResult(Intent.RESULT_OK, resultBundle)

      最后,您在您的原始 Activity 中实现 onActivityResult(int requestCode, int resultCode, Intent data) 并在 resultCodeIntent.RESULT_OKrequestCode 是您的请求代码常量(在本例中为 AppConstants.ACTION_SEARCH_REQUEST_CODE)时做出适当的响应。

      【讨论】:

      • 刚刚遇到这个,这正是我想要的解决方案。我唯一的问题是它会发出警告:BaseFragmentActivityApi16.startActivityForResult can only be called from within the same library group (groupId=com.android.support) 我已经添加了@SuppressLint("RestrictedApi") 这使它可以工作,但我不确定这是否是一个好的解决方案。
      猜你喜欢
      • 2012-05-10
      • 2012-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-26
      • 2018-11-13
      • 2016-02-25
      • 2015-01-15
      相关资源
      最近更新 更多