Android搜索小部件——onQueryTextSubmit和发送Intent到SearchableActivity之间的区别是什么?

9

我有一个包含SearchView小部件的活动。我正在使用onQueryTextSubmit监听器处理文本搜索结果,这很有效。(该活动本身被指定为可搜索的活动。)

最近,我决定通过在searchable.xml文件中添加“voiceSearchMode”属性来添加语音识别:

searchable.xml

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_name"
    android:hint="@string/search_hint"
    android:voiceSearchMode="showVoiceSearchButton|launchRecognizer">
</searchable>

当我添加语音识别时,提供语音输入后onQueryTextSubmit监听器不会被调用(然而,使用editText框提供文本输入后仍会被调用)。语音识别器将一个ACTION_SEARCH意图发送回相同的Activity(可以在onCreate方法中处理)。有没有一种方法可以使用语音识别器激活onQueryTextSubmit方法(或者类似的方法,不需要重新创建Activity)?我之所以问这个问题是因为如果识别器必须发送意图,我就必须创建并发送一个额外的包含APP_DATA的包,但这似乎并没有起作用。
所以我的问题是:
(1)如何在启用语音识别搜索时使用(或可以使用)onQueryTextSubmit监听器?(与普通的基于文本的搜索方式相同)
(2)如果(1)不可能,那么如何通过意图传递使用语音识别搜索查询的附加数据?我尝试通过onSearchRequested()这样添加:
@Override
public boolean onSearchRequested() {
    Bundle appData = new Bundle();
    appData.putInt("testKey", 44);
    this.startSearch(null, true, appData, false);
    return true;
}

但是当我在onCreate中尝试访问它时,appData为空:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.overview_list);

    Bundle extras = getIntent().getExtras();
    Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA);

    // Receive search intents (from voice recognizer)
    Intent intent = getIntent();
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
      String query = intent.getStringExtra(SearchManager.QUERY);
      //doMySearch(query);
    }
}

另外,当我添加onSearchRequested处理程序时,按下放大镜图标会导致搜索小部件重复扩展两次 - 我想这是因为我手动启动了搜索,除了设置可搜索的xml配置之外。关于相关问题,发送意图与在同一活动中使用监听器相比有什么优势?我知道如果你的SearchableActivity是另一个活动,那么你会想发送一个意图;但是,在包含搜索小部件的同一活动中,使用意图有什么意义呢?如果您有任何评论或建议,请告诉我。让我知道是否需要提供任何其他详细信息。

你可以提供一个演示吗? - Ando Masahashi
1个回答

13

(1) 经过大量调试,据我所知,在通过语音识别按钮输入搜索查询时,onQueryTextSubmit从未被调用。但是,有一个简单的解决方法-请参见下文。

(2) 我通过将活动启动模式设置为"singleTop"来解决我的问题-这意味着在语音搜索后,新的ACTION_SEARCH意图将在现有的活动实例中的onNewIntent()处理程序中处理,而不是重新创建活动。因此,您可以访问现有活动的所有私有成员,并且不需要通过修改搜索意图传递任何数据来进行束缚。

AndroidManifest.xml:向可搜索的活动添加launchmode=singleTop属性:

<activity
    android:name=".SearchableActivity"
    android:label="@string/app_name"
    android:uiOptions="splitActionBarWhenNarrow"
    android:launchMode="singleTop">

    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    <meta-data android:name="android.app.searchable"
        android:resource="@xml/searchable" />
</activity>
SearchableActivity 中,添加 onNewIntent() 方法:
@Override
public void onNewIntent(Intent intent) {
    super.onNewIntent(intent);      
    setIntent(intent);
    handleIntent(intent);
}

private void handleIntent(Intent intent) {
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        // Gets the search query from the voice recognizer intent
        String query = intent.getStringExtra(SearchManager.QUERY);

        // Set the search box text to the received query and submit the search
        mSearchView.setQuery(query, true);
    }
}

这基本上是接收语音识别器的查询并将其放入文本框中,然后提交文本框搜索,通常由onQueryTextSubmit处理。


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