title: Android: TextToSpeech doesn't work on Android 4.1
body: <p>Does anybody have idea why the <code>TextToSpeech</code> method I have here doesn't work anymore on Android 4.1?</p>
  
  <p>On the <code>sayIt()</code> method it always returns <code>Log.i(TAG, "Failure: TextToSpeech instance tts was not properly initialized");</code></p>
  
  <pre><code>public class SpeakSuperActivity extends Activity implements OnInitListener {
  
      private final static String TAG = "TextToSpeech";
  
      protected static final Locale defaultLocale = Locale.GERMAN;
      private static int TTS_DATA_CHECK = 100;
      protected TextToSpeech tts = null;
      protected boolean ttsIsInit = false;
  
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
  
          // Use an Intent and startActivityForResult to check whether TTS data installed on the
          // device. Result returned and acted on in method onActivityResult(int, int, Intent) below.
  
          Intent checkIntent = new Intent();
          checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
          startActivityForResult(checkIntent, TTS_DATA_CHECK);
      }
  
      // protected void initTextToSpeech() {
      // Log.d(TAG, "TTS initTextToSpeech() called");
      // Intent intent = new Intent(Engine.ACTION_CHECK_TTS_DATA);
      // startActivityForResult(intent, TTS_DATA_CHECK);
      // }
  
      protected void onActivityResultOld(int requestCode, int resultCode, Intent data) {
          if (requestCode == TTS_DATA_CHECK) {
              Log.d(TAG, "onActivityResult: TTS_DATA_CHECK fork reached");
              if (resultCode == Engine.CHECK_VOICE_DATA_PASS) {
                  Log.d(TAG, "Data installed: Engine.CHECK_VOICE_DATA_PASS fork reached");
                  tts = new TextToSpeech(this, this);
                  // tts = new TextToSpeech(this, new OnInitListener() {
                  // public void onInit(int status) {
                  // if (status == TextToSpeech.SUCCESS) {
                  // Log.w(TAG, "TTS onInit() success :)");
                  // ttsIsInit = true;
                  // if (tts.isLanguageAvailable(Locale.UK) &gt;= 0) {
                  // Log.d(TAG, "Local UK available");
                  // tts.setLanguage(Locale.UK);
                  // }
                  // if (tts.isLanguageAvailable(Locale.GERMAN) &gt;= 0) {
                  // Log.d(TAG, "Local German available");
                  // tts.setLanguage(Locale.GERMAN);
                  // }
                  // tts.setPitch(0.8f);
                  // tts.setSpeechRate(1.1f);
                  // speak("Hallo Sprücheklopfer");
                  // } else if (status == TextToSpeech.ERROR) {
                  // Log.w(TAG, "TTS onInit() failed :(");
                  // }
                  // }
                  // });
  
              } else {
                  Log.i(TAG, "TTS not installed yet, calling intent to install...");
                  Intent installVoice = new Intent(Engine.ACTION_INSTALL_TTS_DATA);
                  startActivity(installVoice);
              }
          }
  
      }
  
      // Create the TTS instance if TextToSpeech language data are installed on device. If not
      // installed, attempt to install it on the device.
  
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          if (requestCode == TTS_DATA_CHECK) {
              if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
  
                  // Success, so create the TTS instance. But can't use it to speak until
                  // the onInit(status) callback defined below runs, indicating initialization.
  
                  Log.i(TAG, "Success, let's talk");
                  // XXX: NOTE: it is REALLY important to use new TextToSpeech(getApplicationContext(), this) instead of new TextToSpeech(this, this)!
                  tts = new TextToSpeech(getApplicationContext(), this);
  
                  // // Use static Locales method to list available locales on device
                  // Locale locales [] = Locale.getAvailableLocales();
                  // Log.i(TAG,"Locales Available on Device:");
                  // for(int i=0; i&lt;locales.length; i++){
                  // String temp = "Locale "+i+": "+locales[i]+" Language="
                  // +locales[i].getDisplayLanguage();
                  // if(locales[i].getDisplayCountry() != "") {
                  // temp += " Country="+locales[i].getDisplayCountry();
                  // }
                  // Log.i(TAG, temp);
                  // }
  
              } else {
                  // missing data, so install it on the device
                  Log.i(TAG, "Missing Data; Install it");
                  Intent installIntent = new Intent();
                  installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
                  startActivity(installIntent);
              }
          }
      }
  
      public void onInit(int status) {
  
          if (status == TextToSpeech.SUCCESS) {
              ttsIsInit = true;
  
              // Set to a language locale after checking availability
              Log.i(TAG, "defaultLocaleAvailable=" + tts.isLanguageAvailable(defaultLocale));
              tts.setLanguage(defaultLocale);
              // Examples of voice controls. Set to defaults of 1.0.
              tts.setPitch(1.0F);
              tts.setSpeechRate(1.0F);
              // Issue a greeting and instructions in the default language
              // speakGreeting(defaultLocale.getDisplayLanguage());
              // sayIt("Hallo Sprücheklopfer", true);
          } else {
              ttsIsInit = false;
              Log.i(TAG, "Failure: TextToSpeech instance tts was not properly initialized");
          }
      }
  
      // protected void speak(String text) {
      // Log.d(TAG, "TTS sould say: " + text);
      // if (tts != null &amp;&amp; ttsIsInit) {
      // tts.speak(text, TextToSpeech.QUEUE_ADD, null);
      // } else {
      // Log.w(TAG, "TTS not initialised or null");
      // }
      // }
  
      // Method to speak a string. The boolean flushQ determines whether the text is
      // appended to the queue (if false), or if the queue is flushed first (if true).
  
      public void sayIt(String text, boolean flushQ) {
          if (tts != null &amp;&amp; ttsIsInit) {
              if (flushQ) {
                  tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);
              } else {
                  tts.speak(text, TextToSpeech.QUEUE_ADD, null);
              }
          } else {
              Log.i(TAG, "Failure: TextToSpeech instance tts was not properly initialized");
          }
      }
  
      // Release TTS resources when finished
  
      @Override
      protected void onDestroy() {
          if (tts != null) {
              tts.stop();
              tts.shutdown();
              ttsIsInit = false;
          }
          super.onDestroy();
      }
  
      public void onInitOld(int status) {
          Log.i(TAG, "TTS onInit() status :" + status);
          if (status == TextToSpeech.SUCCESS) {
              Log.w(TAG, "TTS onInit() success :)");
              ttsIsInit = true;
              if (tts.isLanguageAvailable(Locale.UK) &gt;= 0) {
                  Log.d(TAG, "Local UK available");
                  tts.setLanguage(Locale.UK);
              }
              if (tts.isLanguageAvailable(Locale.GERMAN) &gt;= 0) {
                  Log.d(TAG, "Local German available");
                  tts.setLanguage(Locale.GERMAN);
              }
              tts.setPitch(0.8f);
              tts.setSpeechRate(1.1f);
              sayIt("Hallo Sprücheklopfer", true);
          } else if (status == TextToSpeech.ERROR) {
              Log.w(TAG, "TTS onInit() failed :(");
          } else {
              Log.w(TAG, "TTS onInit() unknown status :" + status);
          }
      }
  
  }
  </code></pre>