这将是一个自我回答的问题,因为我想清楚地记录如何确定搜索意图是由文本输入还是语音识别触发的。我之所以需要这样,是因为我试图将我的应用中的搜索记录到Google Analytics中,我需要知道用户是否在键盘上输入了他们的搜索内容,或者他们是否使用了语音搜索功能。
我在StackOverflow上发现了一些解决这个问题的问题,但我发现它们很难找到并且记录不清。所以希望我的答案将提供正确的关键字和细节,以帮助其他人更快更清楚地找到这个主题。
答案 0 :(得分:0)
我的应用中的搜索活动正在singleTop
模式下运行,因此我通过@Override
onNewIntent()
来处理传入的搜索意图。在此方法中,您需要做的第一件事是检查传入的意图实际上是否是搜索意图。我们通过以下方式实现这一目标:
if (intent.getAction().equals(Intent.ACTION_SEARCH)){}
下一部分有点棘手,并且在旧API上引起了一些误报。 ACTION_SEARCH
意图附加了两个额外内容:QUERY
和USER_QUERY
。如果我们在SearchManager
docs中阅读了这两个值,我们会发现以下信息:
public static final String QUERY
:
Intent额外数据键:使用此键
content.Intent.getStringExtra()
从中获取查询字符串Intent.ACTION_SEARCH
。
public static final String USER_QUERY
:
Intent额外数据键:使用此键
content.Intent.getStringExtra()
获取输入的查询字符串 由用户。这可能与QUERY的值不同 意图是选择建议的结果。在那种情况下,QUERY 将包含SUGGEST_COLUMN_QUERY的值作为建议, 和USER_QUERY将包含用户输入的字符串。
基本上我们可以从这两个doc条目中收集的是QUERY
的值将始终包含搜索的实际值,而不管搜索是如何执行的。因此,如果用户键入搜索,使用语音识别说出来或选择搜索建议并不重要 - 该字段将包含他们搜索的原始字符串值。
另一方面,USER_QUERY
可能为空,也可能不为空,具体取决于搜索的执行方式。如果用户使用文本键入其搜索,则此字段将包含其搜索的值。如果用户使用语音识别执行搜索,此值将为空。
这为我们提供了一个很好的(尽管是hacky,在某种程度上)确定用户是使用文本键入搜索还是使用语音搜索功能的方式。但这里有一个棘手的部分:正如您在上面的文档中所看到的,建议使用getStringExtra()
从intent中检索此值。 这不可靠,因为USER_QUERY
的值实际上是SpannableString
,而不是String
。这可能会产生ClassCastException
,因为如果您使用getStringExtra()
,则会尝试将SpannableString
投射到String
,这将无效。系统会自动为您捕获异常,但是您可能会收到误报的空白,导致您的代码认为搜索是通过语音识别执行的,而实际上是键入的 - 因为ClassCastException而导致文本值丢失。
因此,解决方案是使用来自SpannableString
的{{1}},并检查是否为null,这样您就不会触发ClassCastException和false-positive null。但是您注意到Intent
没有获取SpannableStrings的方法,但它确实有USER_QUERY
方法。由于getCharSequenceExtra()
实现了SpannableString
,我们可以简单地使用此方法来检索我们的USER_QUERY SpannableString,并在出路时将其强制转换。所以我们这样做:
CharSequence
我们现在可以检查此值的空值,以安全地确定用户是键入文本还是以其他方式执行搜索,例如语音识别。
总而言之,我们最终会得到这样的结论:
SpannableString user_query_spannable = (SpannableString) intent.getCharSequenceExtra(SearchManager.USER_QUERY);
正如我之前提到的,对我来说,通过Google和StackOverflow上的搜索很难找到这些信息,特别是当官方Android文档提供有关如何使用这些值的误导性信息时。希望这个答案将为寻找类似信息的其他人提供更容易访问的来源。
答案 1 :(得分:0)
套装[{android.speech.extra.RESULTS = [你好],查询=你好,android.speech.extra.CONFIDENCE_SCORES = [0.9299549]}] 这将成为语音包