1

検索意図がテキスト入力または音声認識によってトリガーされたかどうかを判断する方法を明確に文書化したいので、これは自己回答型の質問になります。これが必要になった理由は、アプリでの検索を Google アナリティクスに記録しようとしていて、ユーザーが検索をキーボードでテキストとして入力しているのか、それとも音声検索機能を使用しているのかを知る必要があったためです。

この質問に対処する StackOverflow に関するいくつかの質問を見つけましたが、見つけるのが難しく、文書化も不十分であることがわかりました。うまくいけば、私の答えが適切なキーワードと詳細を提供し、他の人が将来このトピックをより迅速かつ明確に見つけるのに役立つことを願っています.

4

2 に答える 2

0

私のアプリの検索アクティビティはモードで実行されているため、 ofsingleTopを介して着信検索インテントを処理しています。このメソッド内で最初に行う必要があるのは、受信インテントが実際に検索インテントであるかどうかを確認することです。これは次の方法で実現します。@OverrideonNewIntent()

if (intent.getAction().equals(Intent.ACTION_SEARCH)){}

次の部分は少しトリッキーで、古い API でいくつかの誤検出を引き起こしました。ACTION_SEARCHインテントにはQUERYとの 2 つのエクストラが付属していUSER_QUERYます。SearchManagerdocsでこれら 2 つの値について読むと、次の情報が見つかります。

public static final String QUERY:

インテント エクストラ データ キー: このキーを で使用し content.Intent.getStringExtra()て、 からクエリ文字列を取得します Intent.ACTION_SEARCH

public static final String USER_QUERY:

インテント エクストラ データ キー: このキーを使用 content.Intent.getStringExtra()して、ユーザーが入力したクエリ文字列を取得します。インテントが提案を選択した結果である場合、これは QUERY の値とは異なる場合があります。その場合、QUERY には提案の SUGGEST_COLUMN_QUERY の値が含まれ、 USER_QUERY にはユーザーが入力した文字列が含まれます

基本的に、これら 2 つの doc エントリから収集できることはQUERY、検索の実行方法に関係なく、 の値には常に検索の実際の値が含まれることです。したがって、ユーザーが検索を入力したか、音声認識で音声入力したか、検索候補を選択したかは問題ではありません。このフィールドには、検索対象の生の文字列値が含まれます。

一方、USER_QUERY検索の実行方法によっては、null になる場合とならない場合があります。ユーザーがテキストを使用して検索を入力すると、このフィールドには検索の値が含まれます。ユーザーが音声認識で検索を実行した場合、この値は null になります

これにより、ユーザーがテキストで検索を入力したか、音声検索機能を使用したかを判断するための優れた (ある程度ハックではありますが) 方法が得られます。しかし、ここにトリッキーな部分があります。上記のドキュメントでわかるようにgetStringExtra()、インテントからこの値を取得するために を使用することをお勧めします。の値は実際にはではなく であるため、これは信頼できません。を使用すると、 aを aにキャストしようとしているため、これはおそらく a につながりますが、これは機能しません。例外は自動的にキャッチされますが、結果として誤検知の null が返される場合があります。USER_QUERYSpannableStringStringClassCastExceptiongetStringExtra()SpannableStringString、実際には入力されたテキスト値が ClassCastException のために単に失われたときに、音声認識によって検索が実行されたとコードに信じ込ませます。

したがって、解決策は、代わりにSpannableStringfromUSER_QUERYを処理し、その代わりに null をチェックして、ClassCastException と偽陽性の null をトリガーしないようにすることです。Intentただし、SpannableStrings を取得するメソッドはありませんが、メソッドはあることに気付くでしょうgetCharSequenceExtra()SpannableStringが を実装しているためCharSequence、このメソッドを使用して USER_QUERY SpannableString を取得し、途中でキャストすることができます。したがって、次のようにします。

SpannableString user_query_spannable = (SpannableString) intent.getCharSequenceExtra(SearchManager.USER_QUERY);

この値の null をチェックして、ユーザーがテキストを入力したか、音声認識などの他の方法で検索を実行したかを安全に判断できるようになりました。

すべてをまとめると、次のようになります。

@Override
protected void onNewIntent(Intent intent) {

    if (intent.getAction().equals(Intent.ACTION_SEARCH)) {

        SpannableString user_query_spannable = (SpannableString) intent.getCharSequenceExtra(SearchManager.USER_QUERY);

        //if this was a voice search
        if (user_query_spannable == null) {
            //Log, send Analytics hit, etc.
            //Then perform search as normal...
            performSearch(intent.getStringExtra(SearchManager.QUERY));

        } else {
            //Log, send Analytics hit, etc.
            //Then perform search as normal
            performSearch(intent.getStringExtra(SearchManager.QUERY));
        }
    } 
}

前述したように、私にとって、この情報は Google や StackOverflow での検索では簡単には見つかりませんでした。特に、Android の公式ドキュメントでこれらの値の操作方法に関する誤解を招くような情報が提供されている場合はなおさらです。うまくいけば、この回答は、同様の情報を探している他の人にとって、より簡単にアクセスできるソースを提供します。

于 2016-04-25T16:40:44.207 に答える