私のアプリの検索アクティビティはモードで実行されているため、 ofsingleTop
を介して着信検索インテントを処理しています。このメソッド内で最初に行う必要があるのは、受信インテントが実際に検索インテントであるかどうかを確認することです。これは次の方法で実現します。@Override
onNewIntent()
if (intent.getAction().equals(Intent.ACTION_SEARCH)){}
次の部分は少しトリッキーで、古い API でいくつかの誤検出を引き起こしました。ACTION_SEARCH
インテントにはQUERY
との 2 つのエクストラが付属していUSER_QUERY
ます。SearchManager
docsでこれら 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_QUERY
SpannableString
String
ClassCastException
getStringExtra()
SpannableString
String
、実際には入力されたテキスト値が ClassCastException のために単に失われたときに、音声認識によって検索が実行されたとコードに信じ込ませます。
したがって、解決策は、代わりにSpannableString
fromUSER_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 の公式ドキュメントでこれらの値の操作方法に関する誤解を招くような情報が提供されている場合はなおさらです。うまくいけば、この回答は、同様の情報を探している他の人にとって、より簡単にアクセスできるソースを提供します。