Reputation: 14022
I want to use TTS
in an Android
application. I followed introduction-to-text-to-speech-in. And this is the code of the Activity
which creates TTS
instance:
public class MainActivity extends Activity implements TextToSpeech.OnInitListener {
private int MY_DATA_CHECK_CODE = 0;
private TextToSpeech myTTS;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent checkTTSIntent = new Intent();
checkTTSIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkTTSIntent, MY_DATA_CHECK_CODE);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == MY_DATA_CHECK_CODE) {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
myTTS = new TextToSpeech(this, this);
}
else {
Intent installTTSIntent = new Intent();
installTTSIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installTTSIntent);
}
}
}
@Override
public void onInit(int status) {
}
}
As you can see it is straightforward and simple and also works up to Android 8.1-API 27
; but in Android 9.0
I get ActivityNotFoundException
:
onCreate
method: No Activity found to handle Intent { act=android.speech.tts.engine.CHECK_TTS_DATA }
onActivityResult
method: No Activity found to handle Intent { act=android.speech.tts.engine.INSTALL_TTS_DATA }
Although with attention to documentation about ACTION_CHECK_TTS_DATA and ACTION_INSTALL_TTS_DATA, no one of them is deprecated. How I can solve above errors?
Upvotes: 1
Views: 1068
Reputation: 7437
Sounds like it's probably a beta version of Android 9.0 emulator that is janky?
I don't think it's necessary these days to use the CHECK_TTS_DATA intent... as
1) most all devices (commercial phones, at least) have at least one TTS installed,
2) the myTTS object won't initialize unless that is true ( or, at least it will return an onError callback if you attempt a speak() ), and
3) devices can have multiple engines installed and thus will force the user to choose which engine to send the intent (from the example you used) to.
Instead, I would decide what exact engine/s you want to support, check for it/them specifically, and prompt to install it/them.
For example, if you decided to use/support the Google engine:
private boolean isGoogleTTSInstalled() {
Intent ttsIntent = new Intent();
ttsIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
PackageManager pm = this.getPackageManager();
List<ResolveInfo> listOfInstalledTTSInfo = pm.queryIntentActivities(ttsIntent, PackageManager.GET_META_DATA);
for (ResolveInfo r : listOfInstalledTTSInfo) {
String engineName = r.activityInfo.applicationInfo.packageName;
if (engineName.equals("com.google.android.tts")) {
return true;
}
}
return false;
}
private void installGoogleTTS() {
Intent goToMarket = new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse("market://details?id=com.google.android.tts"));
startActivity(goToMarket);
}
And, if you intend to support a specific language, check for it using myTTS.isLanguageAvailable(Locale loc), and if not:
private void openTTSSettingsToInstallUnsupportedLanguage() {
Intent intent = new Intent();
intent.setAction("com.android.settings.TTS_SETTINGS");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
Upvotes: 1