RecognizerIntent クラスを使用すると、音声認識を行うことができます。
認識のタイプは3種類ありますが、Android2.3 あたりを考慮すると2種類しか使えません。

今回は、それら2種類の認識を切り替えて行う音声認識アプリを作りたいと思います。



詳しくは RecognizerIntent の仕様をご覧ください。
なお、音声認識はネットに繋がり、Google へアクセスできる状態じゃないと利用できませんのでご注意ください。



  • 音声認識方法の種類
RecognizerIntent クラスによる音声認識には、API16 の時点では次の3種類の認識方法があるようです。しかし、2番目の ACTION_VOICE_SEARCH_HANDS_FREE は API16 から追加されたものなので、古い Android 端末を考慮すると使えません。今回は、Action_RECOGNIZE_SPEECH と ACTION_WEB_SEARCH の2種類を使った音声認識サンプルを作りたいと思います。
  • ACTION_RECOGNIZE_SPEECH:
  • ACTION_VOICE_SEARCH_HANDS_FREE:
  • ACTION_WEB_SEARCH:
ACTION_RECOGNIZE_SPEECH は、利用者が話した音声を解析し、尤もらしいと思われる認識率の単語をまとめて返してくれます。ACTION_WEB_SEARCHは、音声の認識結果のうち一つの単語を選択して Web 検索を行います。
単純に Google の音声認識結果が欲しい場合は、 ACTION_RECOGNIZE_SPEECH を利用することになると思われます。




  • 音声認識オプション

また、音声認識のオプションを設定することができます。
設定できることとしては、次のようなものがあります。
  • EXTRA_LANGUAGE_MODEL:音声認識の言語モデル設定
  • EXTRA_PROMPT:音声入力時の説明文書設定
  • EXTRA_MAX_RESULTS:結果の数に上限を設ける

まず、EXTRA_LANGUAGE_MODEL に関しての言語モデルの設定です。これは必ず指定する必要があるようです。この設定を変えると微妙に変わる気もしますが、喋り方の方が強く影響するので果たしてどの程度変わるかはよくわかりません。自分でしゃべってみたところ、なんとなく変わっている気はする、というレベルです。

また、他には以下のようなものがあります。
  • ACTION_RECOGNIZE_SPEECH:自由な会話での語を参考にして認識する
  • ACTION_WEB_SEARCH:Web でよく使われる語を参考にして認識する
他にも重要なオプションがあったりするかもしれませんが、じっくり読む元気がないのでとりあえずここまで。



  • 音声認識のテストプログラム
さて、今回は次のようなサンプルプログラムを作りました。上記2種類の認識方法について、切り替えて音声認識できるようになっています。認識結果はテキストボックスに表示され、一番尤度の高かった結果はトーストでポップアップするようになっています。

こんな感じの動作画面。


音声入力画面。



SPEECHで「ハローワールド」と喋った場合の認識結果。



WEB_SEARCH で「ハローワールド」と喋った場合の検索結果。


結果を選択すると・・・


ブラウザに飛びます。





では重要なポイントの紹介。


・ボタンを押したら、音声入力画面が立ち上がるように設定。
        voiceRecognitionButton.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                if(actionStr == null || langModelStr == null){
                    Toast.makeText(VoiceRecognitionAndRegistAppActivity.this,
                            "isNull",
                            Toast.LENGTH_LONG).show();
                }

                try{
                    // 音声認識インテントの作成
                    Intent voiceRecognizeIntent = new Intent(actionStr);

                    // 単語認識方法の言語モデル設定
                    voiceRecognizeIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, langModelStr);

                    // 音声入力時の説明文章を設定
                    voiceRecognizeIntent.putExtra(
                            RecognizerIntent.EXTRA_PROMPT,
                            VoiceRecognitionAndRegistAppActivity.this.getString(R.string.voice_recognize_prompt));

                    // インテントを発行
                    startActivityForResult(voiceRecognizeIntent, VOICE_RECOGNIZE_CODE);
                }catch(ActivityNotFoundException e){
                    // このインテントに応答できるアクティビティがインストールされていない場合はエラー表示
                    Toast.makeText(VoiceRecognitionAndRegistAppActivity.this,
                            "ActivityNotFoundException",
                            Toast.LENGTH_LONG).show();
                    EditText editText = (EditText)VoiceRecognitionAndRegistAppActivity.this.findViewById(R.id.reconized_edit_text);
                    editText.setText(e.toString());
                }
            }
        });


・結果の取得部分。
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        // 音声インテント終了時の応答処理
        if (requestCode == VOICE_RECOGNIZE_CODE && resultCode == RESULT_OK) {

            // 結果文字列リスト
            ArrayList<String> results = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

            // トーストを使って一番スコアの高い結果を表示
            Toast.makeText(this, results.get(0), Toast.LENGTH_LONG).show();

            // EditText に認識結果を書き込む.
            EditText editText = (EditText)VoiceRecognitionAndRegistAppActivity.this.findViewById(R.id.reconized_edit_text);
            editText.setText("");
            for(String r : results){
                editText.append(r + "\n");
            }
        }

        super.onActivityResult(requestCode, resultCode, data);
    }
}


ソースはこちら