Android
 Computer >> コンピューター >  >> プログラミング >> Android

Androidでシングルトンパターンを使ってTextToSpeech(音声読み上げ)を実装する方法

本記事では、シングルトンデザインパターンを活用して、AndroidアプリのどこからでもTextToSpeech(TTS:テキスト読み上げ)機能を呼び出せるようにする実装方法を解説します。

シングルトンパターンとは?

まず前提知識として、シングルトンデザインパターンについて確認しておきましょう。シングルトンとは、あるクラスのインスタンス生成を「アプリケーション全体で1つだけ」に制限するデザインパターンのことです。主な用途としては、同時実行の制御や、データストアへのアクセスポイントを一元化することなどが挙げられます。TTSのように複数の画面やクラスから共通して利用したい機能は、シングルトンとして管理すると非常に便利です。

実装の流れ

ステップ1:プロジェクトの作成

Android Studioを開き、「File」→「New Project」を選択して新しいプロジェクトを作成します。必要な項目をすべて入力してプロジェクトの雛形を生成してください。

ステップ2:レイアウトファイルの作成

res/layout/activity_main.xml に以下のコードを追加します。

<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout xmlns:android = "https://schemas.android.com/apk/res/android"
    xmlns:tools = "https://schemas.android.com/tools"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    tools:context = ".MainActivity"
    android:orientation = "vertical">
    <EditText
        android:id = "@+id/editText"
        android:hint = "Write here what to speak "
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content" />
    <Button
        android:id = "@+id/show"
        android:text = "TTS from singleTone"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content" />
</LinearLayout>

このレイアウトでは、EditText(入力欄)とButtonを1つずつ配置しています。ユーザーがボタンをタップすると、EditTextに入力されたテキストを取得し、シングルトンクラス経由で音声を読み上げる仕組みです。

ステップ3:MainActivityの実装

src/MainActivity.java に以下のコードを追加します。

package com.example.andy.myapplication;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
    Button show;
    singleTonExample singletonexample;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        show = findViewById(R.id.show);
        singletonexample = singleTonExample.getInstance();
        singletonexample.init(getApplicationContext());
        final EditText editText = findViewById(R.id.editText);
        show.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!editText.getText().toString().isEmpty()) {
                    singletonexample.textToSpeach(editText.getText().toString());
                }
            }
        });
    }
}

ここでは singleTonExample をシングルトンクラスとして利用しています。getInstance() メソッドで唯一のインスタンスを取得し、init() にApplicationContextを渡して初期化しています。ボタンがクリックされると、入力内容が空でないかをチェックした上で、textToSpeach() メソッドに文字列を渡します。

ステップ4:シングルトンクラスの作成

次に、singleTonExample.java という新しいクラスファイルを作成し、以下のコードを記述します。

package com.example.andy.myapplication;

import android.content.Context;
import android.media.MediaPlayer;
import android.speech.tts.TextToSpeech;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
public class singleTonExample {
    static TextToSpeech t1;
    private static singleTonExample ourInstance = new singleTonExample();
    private Context appContext;
    private singleTonExample() { }
    public static Context get() {
        return getInstance().getContext();
    }
    public static synchronized singleTonExample getInstance() {
        return ourInstance;
    }
    public void init(Context context) {
        if (appContext == null) {
            this.appContext = context;
        }
    }
    private Context getContext() {
        return appContext;
    }
    public void textToSpeach(String Speak) {
        t1 = new TextToSpeech(get(), new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                if(status != TextToSpeech.ERROR) {
                    t1.setLanguage(Locale.UK);
                }
            }
        });
        t1.speak(Speak, TextToSpeech.QUEUE_FLUSH, null);
    }
}

このクラスのポイントは以下の通りです。

  • コンストラクタをprivateにすることで、外部からのインスタンス生成を禁止しています。
  • 静的フィールド ourInstance に唯一のインスタンスを保持し、synchronized を付けた getInstance() メソッドでスレッドセーフにアクセスできるようにしています。
  • init() メソッドでは、ApplicationContextが未設定の場合のみ代入するため、何度呼び出しても安全です。
  • textToSpeach() メソッド内で TextToSpeech のインスタンスを生成し、OnInitListener で言語を Locale.UK(英語)に設定した後、speak() メソッドで読み上げを実行します。QUEUE_FLUSH を指定しているため、既存の読み上げキューは破棄されて新しいテキストが即座に再生されます。

アプリの実行と動作確認

それでは実際にアプリを起動してみましょう。Android端末をPCに接続していることを確認し、Android Studioのツールバーにある「Run」アイコンをクリックします。デバイス選択画面で自分のスマートフォンを選択すると、端末に以下のような初期画面が表示されます。

Androidでシングルトンパターンを使ってTextToSpeech(音声読み上げ)を実装する方法

ボタンをタップすると、EditTextに入力したテキストがシングルトンクラスを経由して音声として読み上げられます。この構成にすれば、Activityをまたいだ場合でも同じシングルトンインスタンスを通じてTTS機能を再利用でき、コードの一元管理にも役立ちます。

  1. AndroidのrunOnUiThreadの使い方を解説!ワーカースレッドからUIを安全に更新する方法

    runOnUiThread()とは?具体的な実装例に入る前に、まずAndroidにおけるrunOnUiThread()の役割について理解しておきましょう。Androidアプリでは、UIの描画やユーザー操作への応答はすべて「メインスレッド(UIスレッド)」が担当しています。しかし、メインスレッドで重い処理を実行したり、長時間のタスクを処理したりすると、UIの応答が遅延し、最悪の場合はANR(Application Not Responding)——つまり「アプリが応答していません」というエラーが発生してしまいます。そこで活躍するのがrunOnUiThread()です。このメソッドを使うことで、ワ

  2. Androidローダーの使い方とは?連絡先一覧を表示する実装例をステップ解説

    Androidローダー(Loader)とはローダーは、Android 3.0(APIレベル11)で導入された、バックグラウンドで非同期にデータを読み込むための仕組みです。UIスレッドをブロックすることなくコンテンツプロバイダやデータベースからデータを取得でき、画面回転などの設定変更時にも読み込み済みのデータを再利用できるのが大きな特徴です。本記事では、ローダー(CursorLoader)を使って端末の連絡先一覧をListViewに表示する方法を、サンプルコード付きでステップごとに解説します。ステップ1:新しいプロジェクトを作成するAndroid Studioを起動し、メニューから「File」⇒