Search code examples
androidtext-to-speechgoogle-text-to-speech

Avoid opening the TTS engine selection popup


I've written a simple text-to-speech app. But in some mobile with more than one tts engine, Even though the choice of the tts engine within my code, the tts engine selection popup opens again!!

How can I avoid it from opening?

my code is here:

onCreate():

String GOOGLE_TTS_PACKAGE = "com.google.android.tts";

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

    // Fire off an intent to check if a TTS engine is installed
    Intent intent = new Intent();
    intent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
    startActivityForResult(intent, MY_TTS_DATA_CHECK_CODE);

    mButtonSpeak.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            speak();
        }
    });
}

onActivityResult():

 @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == MY_TTS_DATA_CHECK_CODE) {
        if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
            // success, create the TTS instance
            Log.e(TTS_TAG,"Already VOICE_DATA Installed, create the TTS instance");

            mTTS = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
                @Override
                public void onInit(int status) {
                    if (status == TextToSpeech.ERROR) {
                        Log.e(TTS_TAG, "Initialize failed");
                    } else {
                        int result = mTTS.setLanguage(Locale.US);

                        if (result == TextToSpeech.LANG_NOT_SUPPORTED
                                || result == TextToSpeech.LANG_MISSING_DATA) {
                            Log.e(TTS_TAG, "Language not supported");
                        } else {
                            mButtonSpeak.setEnabled(true);
                        }
                    }
                }
            }, GOOGLE_TTS_PACKAGE);
        } else {
            // missing data, install it
            Log.e(TTS_TAG,"missing data, install it");
            Intent installIntent = new Intent();
            installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
            try {
                Log.e(TTS_TAG, "Installing voice data: " + installIntent.toUri(0));
                startActivity(installIntent);
            } catch (ActivityNotFoundException ex) {
                Log.e(TTS_TAG, "Failed to install TTS data, no activity found for " + installIntent + ")");
            }
        }
    }
}

onDestroy():

@Override
protected void onDestroy() {
    super.onDestroy();

    if (mTTS != null) {
        mTTS.stop();
        mTTS.shutdown();
    }
}

As you can see, inside the TExtToSpeech constructor, the package name is specified.

please help me

UPDATE 1: In this app, in any case, Google TTS will work in the app, even if the user chooses any other engine!

UPDATE 2: I understand that this happens because I've used the startActivityForResult() and onActivityResult(). Does anyone have a solution to solve this problem?

UPDATE 3: When using the Google TTS in the app, and When a specific language is needed (e.g turkish), the files of this language will be downloaded automatically. But if the device is not connected to the Internet, it will remain in download mode. How and under what condition can I control this problem and give the user a message to turn on the Internet?


Solution

  • As far as I've tested in different modes, whenever no TTS engine is installed or disabled, the status==TextToSpeech.ERROR will occur.

    So you do not need to check this before onInit().

    String GOOGLE_TTS_PACKAGE = "com.google.android.tts"
    
    mTTS = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
    
                @Override
                public void onInit(int status) {
                    if (status == TextToSpeech.ERROR) {
                        Log.e(TTS_TAG, "TTS initialize failed");
                        // Open play store if user have'nt installed or disable google TTS
                        installGoogleTTS();
                    } else {
                        // Set engine for tts
                        if (isPackageInstalled(getPackageManager(), GOOGLE_TTS_PACKAGE)) {
                            mTTS.setEngineByPackageName(GOOGLE_TTS_PACKAGE);
                        }
    
                        int result = mTTS.setLanguage(Locale.US);
    
                        if (result == TextToSpeech.LANG_NOT_SUPPORTED
                                || result == TextToSpeech.LANG_MISSING_DATA) {
                            Log.e(TTS_TAG, "Language not supported");
                        } else {
                            mButtonSpeak.setEnabled(true);
                        }
                    }
                }
            });
    

    I also used this function to control the Google service being installed, before set engine for mTTS:

    public static boolean isPackageInstalled(PackageManager pm, String packageName) {
        try {
            pm.getPackageInfo(packageName, 0);
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
        return true;
    }
    

    and this for install Google TTS:

    private void installGoogleTTS() {
        try {
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + GOOGLE_TTS_PACKAGE)));
        } catch (android.content.ActivityNotFoundException anfe) {
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + GOOGLE_TTS_PACKAGE)));
        }
    }
    

    also You can display the dialog before install the Google TTS.