【アプリ開発⑥】音声認識アプリを簡単につくってみた

どうもShinです。

 

アプリ開発第6回目ということで、今回は音声認識アプリを簡単に作ってみようと思いました。

と、言ってもただボタンを押して、音声認識モードに入り、マイクから音声データを受け取ってそれを画面に出力させるだけです。(データベースとして保存はしてません。できるようになりたいですが。)

まだまだ初心者なので、アプリ作成の流れを掴むの主眼とした企画です。

完成コードから

ひとまず、完成コードから載せておきます。

(MainActivity.java)

package com.example.voicepra_app;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.view.View;
import android.widget.Button;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.widget.TextView;
import android.view.View.OnClickListener;
import java.util.Locale;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    //リクエストコードの設定。音声認識Activityに値を渡すために任意の文字を代入しておく。
    private static final int REQUEST_CODE = 1000;
  //langはlangageの略。言語選択のための変数として置いておいた。
    private int lang;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        lang = 0;


        Button voicebutton = findViewById(R.id.voicebutton);
    //ボイスボタンにクリック時の操作を実装。
        voicebutton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
          //speech()メソッドは音声入力開始のメソッド(あとで定義します)
                speech();
            }
        });
    }


    //speechメソッドを作成
    private void speech() {
    //インテントをインスタンス化。別アクティビティを使用するときに利用する。今回は「RecognizerIntent」クラスを使っている。
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);

        if (lang == 0) {
            intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.JAPAN.toString());
        } else if (lang == 1) {
            intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.ENGLISH.toString());
        } else if (lang == 2) {
            intent.putExtra(RecognizerIntent.EXTRA_PREFER_OFFLINE, true);
        }
        else{
            intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        }

    //結果を受け取る上限を100に設定。0だとうまく文字を取得できない。
        intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 100);
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "どうぞお話ください");

        try{
            //音声認識を開始。
            startActivityForResult(intent, REQUEST_CODE);
        }
            //例外が発生したときの処理(例外が発生しなければ行われない処理)
        catch (ActivityNotFoundException e){
            TextView textView1 = findViewById(R.id.textView1);
            e.printStackTrace();
            textView1.setText(R.string.app_name);
        }
    }


    //結果を受け取るために、onActivityResultを設置
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        super.onActivityResult(requestCode, resultCode, data);

    //REQUEST_CODEを受け取る。最初に渡した100が返されれば、ArrayList型のresultに結果を代入する。
        if (requestCode == REQUEST_CODE && resultCode == RESULT_OK){
            ArrayList result =
                    data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

            TextView textView1 = findViewById(R.id.textView1);
      //テキストIDのTextView1にresultの中身を表示させる。
            textView1.setText( result.get(0));
        }
    }

アプリ開発初心者なので0からコードを書いたわけではありません。他サイトを参考にしながら勉強しました。

ですが、きちんとコードの意味を理解しながら書くように努めました。コメントアウトしている箇所は私なりの補足説明です。参照ください。

参考サイト様

本企画で学んだとこと

RecognizerIntent.ACTION_RECOGNIZE_SPEECH

自作したspeechメソッドの冒頭で使った、Android Developerが用意したクラスをありがたく使わせて頂きました。

これで音声認識のActivityを利用することができます。Activity遷移を行うときにはIntentクラスを使う必要があります。Intentの引数にこのクラスを使うことで、音声認識を利用することができます。

このように、「○○っていう機能を実装したいな!」と思ったら、Android側が用意しているクラスをうまく使えばすぐに実装できるときが多いみたいですね。

参考:公式Android Developer

intent.putExtraについて

intentクラスを使うときは、アクティビティが複数あって、アクティビティ間でデータのやりとりや画面遷移をするときに頻繁に用いられる。

その時に使われる「intent.putExtra」は、別アクティビティへデータを渡すときに使われることがわかった。第一引数には渡すときの目印になる「キー名」と、第二引数には渡したいデータの「値」が入る。

今回の例がこちら↓

intent.putExtra(RecognizerIntent.EXTRA_PROMPT, “どうぞお話ください”);

第一引数のRecognizerintent.EXTRA_PROMPTは、ユーザーに音声入力を要求するときのメッセージを表示させるキーで、第二引数では、その実際のメッセージ内容(値)を渡していることがわかる。

 

ちなみに、今回の音声認識のアクティビティでは、別にファイルを作る必要がなかったので、受け取るときの処理コードを書く必要がなかった。

REQUEST_CODEについて

REQUEST_CODEは遷移先が決まっていれば、任意の数字でもOK。

private static final int REQUEST_CODE = 1000;

今回は1000という値を使ったが、別に1でも構わない。とにかく、アクティビティを管理するためにつける代表の数字ということがわかった。

どこのアクティビティから戻ってくるのか?を管理するのに使える。たくさんアクティビティがあるときにリクエストコードを書いておけば管理が楽になる。

startActivityForResult(intent, REQUEST_CODE)

リザルトありきでアクティビティをスタートさせるときに使うメソッド。

これによって、アクティビティ間の双方向でデータのやりとりを行うことができる。第一引数のintentには、intent情報が入っている。今回の場合はRecoginizerintent.ACTION_RECOGNIXE_SPEECHがintent内部に格納されいる。

第二引数にはREQUEST_CODEを渡しておく。

今回の場合の値は1000だった。つまり、音声認識のアクティビティに値の1000を渡すことで、双方向でその値を下にしてデータをやりとりすることができる。https://qiita.com/kskso9/items/01c8bbb39355af9ec25e

本企画の感想・気づいたこと

0からコードを書いてみよう!と検討してみたところ、やはりまだ自力で書くことが難しいと実感した。音声認識のためにはどのクラスを使えばいいのかも分からず、結局他サイト様のコードを参照にした。

Android Developer様のサイトみながら、なんとか実装できないかと思ったが現実はそう甘くないようだ。どうすれば自力でコードを書けるようになるのだろうか・・・。

 

プログラミング学習は英語学習と似ているとも感じた。

日本語から英文に英訳するとき、書ける知識や単語は頭の中に入ってはいるが、いざ目の前にして英文を書くとなると相当難しいと感じる。

プログラミング言語も同じで、1つ1つのメソッドやクラスの意味がわかっても、実際にコードを0から書こうとしても書けないことが多い。これはただ、経験が足りないからだと思っている、そうであってほしい。

 

他サイト様からコードをみながら写経するのもいいが、最低限「このコードはどういう意味をもっているのか?」をしっかりと吟味するのが重要だと感じた。思考停止しながら書いても、その時間は無駄で終わることになる。

 

最終的に自力でコードが書けるようになるには、「この機能が欲しいから、このメソッドやクラスを実装しよう、そのためにはあれが必要で・・・」という思考回路が重要になるはずだ。

そのためには、まだ経験が足りない。もっと効率的の良い学習方法を模索しながら独学に努めるつもりだ。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です