9

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

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

可搜索的.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 Intent 发送回同一个 Activity(可以在 onCreate 方法中处理)。有没有办法使用语音识别器激活 onQueryTextSubmit 方法(或不需要重新创建活动的类似方法?)我问的原因是因为如果识别器必须发送意图,我必须创建和发送一个带有 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 是另一个活动,那么您会想向它发送一个意图;但是在 SearchableActivity 是包含搜索小部件的同一个活动的情况下,使用意图的意义何在?

任何意见和建议将不胜感激。如果我需要提供任何其他详细信息,请告诉我。

4

1 回答 1

13

(1) 据我所知,当我通过语音识别器按钮输入搜索查询时,onQueryTextSubmit 永远不会被调用。但是,有一个简单的解决方法 - 见下文。

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

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 处理的文本框搜索。

于 2013-03-15T22:42:36.660 回答