株式会社ライブキャストロゴ 株式会社ライブキャスト

2011年11月3日 追記
ご注意!
Google Translate API v1が2011年12月1日にサービスが終了いたします。添付のサンプルソースでは、Google Translate API v1を利用していますので、翻訳が正常に機能しない場合がございます。ご承知おきください。

Android Market公開を目指してAndroidアプリを開発する!(翻訳履歴参照編)の続きです。

いよいよ、TranslatAIRにはない機能の実装に入りたいと思います。

Android端末に向かってしゃべった言葉をテキストに落とす機能(翻訳対象とする)

を実装します。

まず、画面下部に、「voice」ボタンを用意しました。このボタンを押すと、音声認識機能が実行されるようにしたいと思います。

activity

画面デザインのXMLはこんな感じです。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <EditText
    	android:id="@+id/srctext"
	    android:layout_width="fill_parent"
	    android:layout_height="fill_parent"
	    android:layout_weight="1"
	    android:layout_margin="5dp"
	    android:inputType="textMultiLine"
	    android:gravity="top"
	    />
	<LinearLayout
		android:orientation="horizontal"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		>
		<Spinner
			android:id="@+id/srclanguage"
			android:layout_width="fill_parent"
			android:layout_height="fill_parent"
		    android:layout_weight="1"
			android:layout_marginLeft="5dp"
			/>
		<ToggleButton
			android:id="@+id/vector"
		    android:layout_width="wrap_content"
			android:layout_height="fill_parent"
			android:textOff=">>"
		/>
		<Spinner
			android:id="@+id/dstlanguage"
			android:layout_width="fill_parent"
			android:layout_height="fill_parent"
		    android:layout_weight="1"
			android:layout_marginRight="5dp"
			/>
	</LinearLayout>
    <EditText
    	android:id="@+id/dsttext"
	    android:layout_width="fill_parent"
	    android:layout_height="fill_parent"
    	android:layout_weight="1"
	    android:layout_margin="5dp"
	    android:inputType="textMultiLine"
	    android:gravity="top"
	    />
	<LinearLayout
		android:orientation="horizontal"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:gravity="right"
		>
		<Button
			android:id="@+id/voice"
			android:layout_width="fill_parent"
			android:layout_height="fill_parent"
	    	android:layout_weight="1"
			android:layout_marginLeft="5dp"
		    android:text="voice"
		    />
		<Button
			android:id="@+id/tweet"
			android:layout_width="fill_parent"
			android:layout_height="fill_parent"
	    	android:layout_weight="1"
		    android:text="tweet"
		    />
		<Button
			android:id="@+id/translate"
			android:layout_width="fill_parent"
			android:layout_height="fill_parent"
	    	android:layout_weight="1"
	    	android:layout_marginRight="5dp"
		    android:text="translate"
		    />
	</LinearLayout>
</LinearLayout>

それでは、「voice」ボタンを押された時の処理に、入っていきたいと思います。

音声認識機能(Voice Recognition)には、RecognizerIntentというクラスを利用します。

Android Developersサイトのサンプルソース
VoiceRecognition.java | Android Developers



音声認識(RecognizerIntent)を使用するには – 逆引きAndroid入門
を参考にさせていただきました。

事前に、RecognizerIntentが使えるかどうかを判断して、初期化処理をしておきます。

    	try {
    		PackageManager manager = getPackageManager();
    		List<ResolveInfo> activities = manager.queryIntentActivities(
    			new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);

        	if (activities.size() != 0) {
        		recognizable = true;
    		} else {
    			recognizable = false;
    		}
    	}
    	catch (Exception ex) {
    		recognizable = false;
    	}

RecognizerIntentが使えれば、「voice」ボタンのクリックイベントリスナーを設定します。「voice」ボタンを押したときには、まず、Android端末に向かって何語でしゃべるかを選択させるDialogを表示するようにします。

        if (recognizable) {
	        btnSpeak.setOnClickListener(new OnClickListener() {

				public void onClick(View v) {
    				final AlertDialog.Builder builder = new AlertDialog.Builder(TranslatorSample7.this);
    		    	final CharSequence[] labels = getResources().getStringArray(R.array.language_label);

    				builder.setTitle("選択してください。");
    				builder.setItems(labels, new DialogInterface.OnClickListener() {

						public void onClick(DialogInterface dialog, int which) {
							showVoiceRecognitionDialog(languages.getItem(which));
						}
    		    	});

    				builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

						public void onClick(DialogInterface dialog, int which) {
							return;
						}

    				});

    				builder.setCancelable(true);
    				builder.create().show();
				}

	        });
        }

何語をしゃべるかが選択されたら、RecognizerIntentを起動させて、音声を認識するまで待ちます。

    private void showVoiceRecognitionDialog(LanguageModel locale) {
    	extraLanguage = getLocale(locale);

        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "TranslatorSample7");
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, extraLanguage);
        startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);
    }

音声が認識されたときのコールバックで、結果を画面に反映させるようにします。

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == VOICE_RECOGNITION_REQUEST_CODE) {
        	// 音声認識初期化の結果
    		if (resultCode == RESULT_OK) {
    			ArrayList<String> matches = data.getStringArrayListExtra(
    				RecognizerIntent.EXTRA_RESULTS);

    			StringBuilder sb = new StringBuilder();

    			for (int i = 0; i < matches.size(); i++) {
    				sb.append(matches.get(i));
    			}

    			ToggleButton vector = (ToggleButton)findViewById(R.id.vector);

    			if (vector.isChecked()) {
    				((EditText)findViewById(R.id.dsttext)).setText(sb.toString());
    			}
    			else {
    				((EditText)findViewById(R.id.srctext)).setText(sb.toString());
    			}
    		}
        }

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

そのときのリクエストコード(requestCode)は、メンバー変数で定義しています。値は、とりあえず9999にしましたが、0以上でアプリケーション内でユニークであればいくつでもよいと思います。

    private static final int VOICE_RECOGNITION_REQUEST_CODE = 9999;

実行結果はこちら。

●「voice」ボタンを押した後

language

●Android端末に向かってしゃべるところ

recoginize

●音声認識された後、翻訳までしてみたところ

hungry

サンプルソースのアプリでも、十分遊べると思います。是非、試してみてください!

サンプルソース