音声認識機能を使用する Android* アプリケーションの開発

同カテゴリーの次の記事

インテル® プロセッサー・ベースのプラットフォームにおけるサードパーティー Android* アプリケーションのデバッグ・リファレンス - パート 1

この記事は、インテル® デベロッパー・ゾーンに掲載されている「Developing Android* Applications with Voice Recognition Features」の日本語参考訳です。


Android* OSは音声認識をサポートしていないため、通常 Android* デバイスは音声を認識できませんが、できるようにする方法はあるのでしょうか?

最も簡単な方法は、別のアプリケーションに認識してもらうことです。Android* で別のアプリケーションに何かしてもらうことをインテント (Intent) の使用と言います。

RecognizerIntent.ACTION_RECOGNIZE_SPEECH アクションによって呼び出される音声認識のインテントを処理できる、少なくとも 1 つのアプリケーションがターゲットデバイスになければいけません。

例えば、Google* 音声検索 (https://play.google.com/store/apps/details?id=com.google.android.voicesearch) のようなアプリが必要です。Google* 音声検索は、最も優れた Android* 向け音声認識エンジンの 1 つであり、多数の言語をサポートしています。Google* サーバーで音声認識が行われるため、このアプリを使用するにはインターネット接続が必要です。このアプリのアクティビティー (Activity) は、ユーザーに音声入力可能なことを通知するだけの簡単なものです。ユーザーが話し終わるとすぐにダイアログが閉じ、アプリケーション (インテントの呼び出し元) は認識された音声の文字列配列を受け取ります。

音声認識のサンプル・アプリケーション

音声認識を使用する簡単なサンプル・アプリケーションを記述してみましょう。

このアプリケーションでは次の処理を行います。

  • 音声認識要求を受け取る
  • 音声認識アプリケーションの有無を確認する
  • 音声認識が利用可能な場合は、インテントを呼び出して結果を受け取る
  • 音声認識が利用不可の場合は、Google* 音声検索をインストールするダイアログを表示し、ユーザーの要望に応じて Google Play* へリダイレクトする

まず、音声認識ロジックを実装するクラスを作成します。このクラスは SpeechRecognitionHelper とし、音声認識の起動要求を受け取る static public 関数 run() を宣言します。

/**
 * 音声認識用のヘルパークラス
 */
public class SpeechRecognitionHelper {

/**
     * 認識プロセスを実行し、認識アクティビティーの有無を確認します。
     * アクティビティーがない場合は、Google Play* に誘導して Google* 音声検索を
     * インストールします。
     * アクティビティーがある場合は、インテントを送信して実行します。
     *
     * @param callingActivity - 認識プロセスを開始するアクティビティー
     */
    public static void run(Activity callingActivity) {
        // 認識アクティビティーの有無を確認します。
        if (isSpeechRecognitionActivityPresented(callingActivity) == true) {
            // ある場合は認識プロセスを実行します。
            startRecognition(callingActivity);
        } else {
            // ない場合は Google* 音声検索のインストール通知を表示します。
            Toast.makeText(callingActivity, "In order to activate speech recognition you must install \"Google Voice Search\"", Toast.LENGTH_LONG).show();
            // インストール処理を開始します。
            installGoogleVoiceSearch(callingActivity);
        }
    }
}

上記のコードから分かるように、run() 関数のほかに 3 つの関数を実装する必要があります。

  • isSpeechRecognitionActivityPresented – 音声認識アプリケーションがシステムにあるかどうかを確認します。
  • installGoogleVoiceSearch – Google* 音声検索のインストール処理を初期化します。
  • startRecognition – 適切なインテントの準備を行い、認識を実行します。

デバイスに音声認識アプリケーションがあるかどうかを確認するには、クラス PackageManagerqueryIntentActivities メソッドを使用します。このメソッドは、指定されたインテントを処理できるアクティビティーのリストを返します。PackageManager のインスタンスを受け取るには、getPackageManager を使用します。

以下にサンプルコードを示します。

isSpeechRecognitionActivityPresented

/**
     * 音声認識アクティビティーの有無を確認します。
     * @param callerActivity - 確認処理を呼び出したアクティビティー
     * @戻り値 - アクティビティーがある場合は true、ない場合は false
     */
    private static boolean isSpeechRecognitionActivityPresented(Activity callerActivity) {
        try {
            // パッケージ・マネージャーのインスタンスを取得します。
            PackageManager pm = callerActivity.getPackageManager();
            // 音声認識インテントを処理可能なアクティビティーのリスト
            List activities = pm.queryIntentActivities(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);

            if (activities.size() != 0) {
            // リストが空でない場合、音声認識が可能です。
                return true;
            }
        } catch (Exception e) {

        }

        return false; // 音声を認識できるアクティビティーがありません。
    }

次に、startRecognition 関数を実装します。この関数は、音声認識アクティビティーを起動する適切なインテントを作成します。詳細は、ドキュメント・ページ (英語) を参照してください。

ソースコード:

   /**
     * 音声認識要求のインテントを送信します。
     * @param callerActivity - 要求を送信したアクティビティー
     */
    private static void startRecognitionActivity(Activity callerActivity) {

        // RecognizerIntent.ACTION_RECOGNIZE_SPEECH アクションで
        // インテントを作成します。
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);

        // 追加のパラメーターを渡します。
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Select an application");    // ユーザーへのヒント
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
        // 検索クエリーを高速に処理できるように
        // 最適化された認識モデルを設定します。
        intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1);
        // 取得する結果の数
        // 最も関連性の高い最初の結果のみを選択します。

        // アクティビティーを開始し、結果を待機します。
        ownerActivity.startActivityForResult(intent, SystemData.VOICE_RECOGNITION_REQUEST_CODE);
    }

最後に、installGoogleVoiceSearch を実装します。この関数は、Google* 音声検索をインストールするかどうかを確認するダイアログを表示し、ユーザーの要望に応じて Google Play* に移動します。

/**
     * Google* 音声検索をインストールするかどうか確認します。
     * ユーザーが同意した場合は、Google Play* に移動します。
     * @param callerActivity - インストール処理を開始したアクティビティー
     */
    private static void installGoogleVoiceSearch(final Activity ownerActivity) {

        // 音声検索をインストールするかどうか、ユーザーに
        // 確認するためのダイアログを作成します。
        Dialog dialog = new AlertDialog.Builder(ownerActivity)
            .setMessage("For recognition it's necessary to install \"Google Voice Search\"")    // ダイアログメッセージ
            .setTitle("Install Voice Search from Google Play?")
            // ダイアログヘッダー
            .setPositiveButton("Install", new DialogInterface.OnClickListener() {    // 確認ボタン

                // インストール・ボタンのクリックハンドラー
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    try {
                        // Google Play* でアプリケーション・ページを
                        // 開くためのインテントを作成します。
                        // 音声検索パッケージ名:
                        // com.google.android.voicesearch
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.voicesearch"));
                        // アプリケーション履歴 (アクティビティーのコールスタック)
                        // に残らないようにフラグを設定します。
                        intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);    // インテントを送信します。
                        ownerActivity.startActivity(intent);
                     } catch (Exception ex) {
                         // 問題が発生した場合は何もしません。
                     }
                }})

            .setNegativeButton("Cancel", null)    // キャンセルボタン
            .create();

        dialog.show();    // ダイアログを表示します。
    }

これでほぼ終了です。音声認識アクティビティーを実行し、Google* 音声検索をインストールするかどうかをユーザーに確認して、ユーザーが同意した場合は Google Play* に移動します。後は音声認識結果を受け取るだけです。

startActivityForResult 関数を使って要求を送信し、起動したアクティビティーの結果を受け取ります。また、次のように、インテントの呼び出し元アクティビティーで OnActivityResult メソッドを再定義する必要があります。

// アクティビティー結果ハンドラー
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        // 音声認識の結果であることと、
        // 処理が問題なく完了したことを確認します。
        if (requestCode == SystemData.VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) {

            // 結果は文字列配列で受け取ります。
            // 音声認識エンジンは正しく認識できないことがあるため
            // いくつかの結果が返されますが、より関連性の高いものは
            // リストの最初にあります。
            ArrayList matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

            // matches 配列に格納された結果から最も関連性の高いものを表示します。
            if (matches.size() > 0) Toast.makeText(this, matches.get(0), Toast.LENGTH_LONG).show();
        }

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

まとめ

ここで作成したクラス SpeechRecognitionHelper は、1 つの関数 run() を呼び出すだけで音声認識要求を実行することができます。

プロジェクトにこのクラスを追加し、適切な場所で run 関数を呼び出すだけで音声認識機能を利用できます。そして、認識を呼び出すアクティビティーの onActivityResult メソッドを再定義して認識結果の処理を実装します。

関連情報は、Android Developers Web サイト (英語) を参照してください。音声認識の使用方法や利用可能な言語リストの取得方法を示したサンプルがあります。言語リストは、ユーザーのデフォルトのロケールとは異なる言語を認識する際に必要です。

SpeechRecognitionHelper クラスのコードをこちらからダウンロードして、アプリケーションに音声入力を迅速に統合できます。

著者紹介

Stanislav
インテル コーポレーションのソフトウェア & ソリューション・グループに所属しており、ソフトウェア開発において 10 年以上の経験があります。主に、パフォーマンス、消費電力、並列プログラミングの最適化に取り組んでいます。現在は、アプリケーション・エンジニアとしてインテル・デバイスのテクニカルサポートを担当しており、ソフトウェア開発者や SoC アーキテクトがインテルのプラットフォームで最良のパフォーマンスを引き出せるように支援しています。National Research University Higher School of Economics で数理経済学の修士号を取得しています。

Mikhail
このブログの共著者で、Lobachevsky University にてコンピューター・サイエンスを専攻しており、夏の間インテルでインターンとして働いていました。数学と Android* プログラミング技法に興味を持っています。

Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国における Intel Corporation の商標です。
* その他の社名、製品名などは、一般に各社の表示、商標または登録商標です。
© 2013 Intel Corporation.

コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。

関連記事