Search code examples
androidandroid-studioandroid-emulatortext-to-speech

Text to Speech app not working in emulator in android studio but works in android device


Is there some settings I have to change in the android emulator? The app runs in the android device but doesnt run in the simulator. When I press the convert button it just doesn't output any speech at all. I even checked if other apps give output through the speaker. Yes, youtube works perfectly fine.

package com.example.labpgm7;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import java.util.Locale;

public class MainActivity extends AppCompatActivity {
    EditText texttospeak;
    Button speak;
    TextToSpeech t;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        texttospeak=findViewById(R.id.texttospeech);
        t=new TextToSpeech(this, new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status)
            {

            }
        });
    }

    public void speak(View v)
    {
        String text=texttospeak.getText().toString();
        t.setPitch(1.0f);
        t.setSpeechRate(1.0f);
        t.speak(text,TextToSpeech.QUEUE_FLUSH,null);
    }
}

Solution

  • The reason why the TTS is not working on the emulator is because the TextToSpeech instance creation should be performed asynchronously, not in the main UI thread.

    Indeed, you have to make sure that the TTS initialisation is successful by waiting on the onInit() callback verifying that the status is TextToSpeech.SUCCESS. Language should be defined as well, for instance (used AsyncTask for demonstration only):

    private class TTSInit extends AsyncTask<Void, Void, Void> {
    
            @Override
            protected Void doInBackground(Void... voids) {
                t=new TextToSpeech(getContext(), status -> {
                    if (status == TextToSpeech.SUCCESS) {
                        t.setLanguage(Locale.ENGLISH);
                        /* now you can invoke speak() */
                    }
                });
                return null;
            }
    }
    

    Finally, if you're targeting Android 11, the following code should be added into the manifest:

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