Androidアプリ開発

TextToSpeechで音声案内を実装する

この記事は約14分で読めます。
記事内に広告が含まれています。
スポンサーリンク

この記事は Androidスマホ用のアプリ開発の中で、
今後の開発で再使用性が高いと思われるコーディングをまとめたものです。
Java での開発経験、XML構文規則、Android のアプリ開発経験がある方を対象としています。
Android のアプリ開発でお役にたててれば、嬉しいです。
(これから Android のアプリ開発や Java での開発を始めたい方への案内は、
記事の最後で紹介します)

この記事のテーマ


TextToSpeechでテキストを音声に変換して再生する

<strong>重要ポイント</strong>
重要ポイント

音声案内は、スマホ本体のテキスト読み上げ機能を使用します。
機種やOSバージョンによっては、有効になっていない場合があります。
音声がでない場合は、
テキスト読み上げの設定 を実施してください。

仕事中に喉が渇いたら、冷えてなくても、おいしく飲めるフレーバーウォーターがおススメです♪

ポイント

TextToSpeech は、テキストから音声合成して、再生や音声ファイルを作成できるライブラリです。
画面上に通知メッセージをテキスト出力する感覚で、テキストを指定して音声で案内することが可能となります。
ここでは、
TextToSpeech を使用して、実用的なテキストによる音声案内の実装について、紹介いたします。

◎マニフェストファイルのクエリ要素に宣言を追加する
Android 11 以上をターゲットとする場合、マニフェストのクエリ要素に TTS_SERVICE を宣言します。

… 
<queries>
  …
  <intent>
      <action android:name="android.intent.action.TTS_SERVICE" />
  </intent>
…
</queries>

音声案内を実装する

動画や音楽を再生中に音声案内する場合、動画や音楽をミュートして、音声案内する必要があります。
ここでは、
Exoplayer で音楽を再生している場合のミュート制御を実装しています。
TextToSpeech をインスタンス化する際、音声言語が使用可能かの判定して、音声言語と使用可能な音声番号(VOICE_NO)を指定します。
音声再生の実行結果は、リスナーを使用して判定します。
再生開始、再生終了、エラー検出など、それぞれの処理を実装します。
音声が再生中の場合は、再生中の音声を停止したのち、新しい音声を再生します。

 …
 private TextToSpeech   textToSpeech;
 private ExoPlayer      exoPlayer;
 private boolean        resetVolume = false;
 private boolean        ttsError = false;
 private float          VOICE = 1.0f;
 private int            VOICE_NO = 0;


  …
    // 音声案内 //
    private void announce(String message, String id) {
        announce(message, id, true);
    }
    private void announce(String message, String id, boolean mute) {
    …
    // Exoplayerで音楽を再生中のミュート制御
    float player = exoPlayer.getVolume();
    if (mute) exoPlayer.setVolume(player * 0.05f);
    …
    textToSpeech = new TextToSpeech(context, status -> {
            if (TextToSpeech.SUCCESS == status) {
                Locale locale = new Locale(Locale.getDefault().getLanguage().equals("ja") ? "ja" : "en");
                // 音声言語が使用可能かの判定
                if (textToSpeech.isLanguageAvailable(locale) >= TextToSpeech.LANG_AVAILABLE) {
          // 音声言語の設定 
                    textToSpeech.setLanguage(locale);
                    List<Voice> voiceList = new ArrayList<>();
                    for (Voice voice : textToSpeech.getVoices()) {
                        if (voice.getName().startsWith(locale.getLanguage())) voiceList.add(voice);
                    }
                    VOICE_NO = VOICE_NO >= voiceList.size() || VOICE_NO < 0 ? 0 : VOICE_NO;
                    // 音声番号の設定
                    if (voiceList.size() > 0) textToSpeech.setVoice(voiceList.get(VOICE_NO));
                }
                textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
                    // 再生開始
                    @Override
                    public void onStart(String utteranceId) { }
                    // 再生終了
                    @Override
                    public void onDone(String utteranceId) {
                        resetVolume = mute;
                        if (utteranceId.equals("announce1")) {
                            // announce1の場合の処理
                            …
                        }
                    }
                    // エラー発生
                    @Override
                    public void onError(String utteranceId) {
                        ttsError = true;
                        resetVolume = mute;
                    }
                });
                // 音声再生中の場合は再生を停止する
                if (textToSpeech.isSpeaking()) textToSpeech.stop();
                Bundle params = new Bundle();
                params.putFloat(TextToSpeech.Engine.KEY_PARAM_VOLUME, VOICE);
                // 音声再生
                textToSpeech.speak(message, TextToSpeech.QUEUE_FLUSH, params, id);
            }
        });
    }

音声ファイルを作成する場合は、synthesizeToFile を使用します。

音声案内の呼び出し

音声案内の呼び出しでは、音声案内するテキストと、メッセージを識別するIDを指定します。
音声案内でミュートが不要な場合は、mute に false を指定しています。
音声案内前に
Exoplayer の再生ボリュームを取得し、音声案内後に再生ボリュームを元に戻します。
終了時に使用した
TextToSpeech のリソースを開放します。

 …
 // onCreate //
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
     …
     // EXOPLAYERのインスタンス化
     exoPlayer = new ExoPlayer.Builder(context)
                .setHandleAudioBecomingNoisy(true)
                .build();
     …
     // ミュートが不要な音声案内
     announce(context.getString(R.string.message1), "announce0", false);
     …
     // ミュートが必要な音声案内
     announce(context.getString(R.string.message2), "announce1")
     …
     // EXOPLAYERの再生ボリュームの取得
     float   initial = exoPlayer.getVolume();
     …
     // ボリューム復帰
     if (resetVolume) {
         exoPlayer.setVolume(initial);
         resetVolume = false;
     }
     if (ttsError) {
         ttsError = false;
        // 音声案内でエラーが発生いた場合の処理
        …
     }
  }
 …
 // onDestroy //
 @Override
 public void onDestroy() {
     if (exoPlayer != null) {
         exoPlayer.stop();
         exoPlayer.release();
     }
    …
   // TTSリソースの解放
     if (textToSpeech != null) textToSpeech.shutdown();
         super.onDestroy();
     }
  }

テキスト読み上げの設定

音声による案内は、スマホ本体のテキスト読み上げ機能を使用しています。
機種やOSバージョンによっては、
有効になっていない場合があります。
ここでは、テキスト読み上げ機能を有効にする方法を説明します。

①スマホ本体のメニューで『設定』をタップします。
②設定のメニューから、『システム』→『言語と入力』→『詳細設定』→『テキスト読み上げの設定』をタップします。

設定は機種やOSバージョンによって異なります。
基本的には「言語」や「キーボード」などの設定にあります。
無い場合は、システムの設定内に無いか確認してください。

③優先するエンジンのギア(アイコン)をタップします。
④『音声データをインストール』をタップし、日本語と英語をインストールします(アルファベットは英語用の音声が必要です)

今回は、ここまでです。

TextToSpeechで音声案内を実装している Androidアプリです。

誤字脱字、意味不明でわかりづらい、
もっと詳しく知りたいなどのご意見は、
このページの最後にある
コメントか、
こちらから、お願いいたします♪

ポチッとして頂けると、
次のコンテンツを作成する励みになります♪

ブログランキング・にほんブログ村へ

これからAndroidのアプリ開発やJavaでの開発を始めたい方へ

アプリケーション開発経験がない方や、アプリケーション開発経験がある方でも、Java や C# などのオブジェクト指向言語が初めての方は、Android のアプリ開発ができるようになるには、かなりの時間がかかります。オンラインスクールでの習得を、強くおススメします。

未経験者からシステムエンジニアを目指すのに最適かと、
まずは無料相談から♪